Compare commits

...
Author SHA1 Message Date
Mohamed Boudra 16d321899c fix(app): select current branch for new workspaces
Closes #541
2026-04-24 13:50:22 +07:00
2 changed files with 38 additions and 8 deletions
@@ -97,7 +97,11 @@ const {
const hoistedMockClient = {
isConnected: true,
getCheckoutStatus: vi.fn(async () => ({ currentBranch: "main" })),
getCheckoutStatus: vi.fn(
async (): Promise<{ currentBranch: string | null }> => ({
currentBranch: "main",
}),
),
getBranchSuggestions: vi.fn(async () => ({ branches: ["main", "dev", "feat/x"] })),
searchGitHub: vi.fn(async () => ({
items: [hoistedPrItem, hoistedPrItemB],
@@ -672,7 +676,7 @@ describe("NewWorkspaceScreen picker payload", () => {
});
});
it("sends no new fields when nothing is selected (default)", async () => {
it("uses the loaded current branch as the selected branch", async () => {
renderScreen();
await flush();
@@ -684,12 +688,24 @@ describe("NewWorkspaceScreen picker payload", () => {
expect(call).toMatchObject({
cwd: "/repo",
worktreeSlug: "gentle-slug",
action: "branch-off",
refName: "main",
});
expect(call).not.toHaveProperty("refName");
expect(call).not.toHaveProperty("action");
expect(call).not.toHaveProperty("githubPrNumber");
});
it("requires a branch selection when the current branch is unavailable", async () => {
mockClient.getCheckoutStatus.mockResolvedValueOnce({ currentBranch: null });
renderScreen();
await flush();
click(await findByTestId("test-composer-submit"));
await flush();
expect(mockClient.createPaseoWorktree).not.toHaveBeenCalled();
expect(document.body.textContent).toContain("Choose a branch to start from");
});
it("opens the new workspace draft tab as soon as the worktree is ready", async () => {
initialDraftState.text = "please review this change";
renderScreen();
@@ -194,6 +194,15 @@ function pickerItemTriggerLabel(item: PickerItem): string {
return item.kind === "branch" ? item.name : formatPrLabel(item.item);
}
function resolveSelectedPickerItem(input: {
pickerSelection: PickerSelection | null;
currentBranch: string | null | undefined;
}): PickerItem | null {
if (input.pickerSelection) return input.pickerSelection.item;
const currentBranch = input.currentBranch?.trim();
return currentBranch ? { kind: "branch", name: currentBranch } : null;
}
function syncPickerPrAttachment(input: {
attachments: ComposerAttachment[];
previousPickerPrNumber: number | null;
@@ -436,7 +445,6 @@ export function NewWorkspaceScreen({
const displayName = displayNameProp?.trim() ?? "";
const workspace = createdWorkspace;
const selectedItem = pickerSelection?.item ?? null;
const isPending = pendingAction !== null;
const client = useHostRuntimeClient(serverId);
const isConnected = useHostRuntimeIsConnected(serverId);
@@ -476,7 +484,10 @@ export function NewWorkspaceScreen({
refetchOnWindowFocus: false,
});
const currentBranch = checkoutStatusQuery.data?.currentBranch ?? null;
const selectedItem = resolveSelectedPickerItem({
pickerSelection,
currentBranch: checkoutStatusQuery.data?.currentBranch,
});
const branchSuggestionsQuery = useQuery({
queryKey: ["branch-suggestions", serverId, sourceDirectory, debouncedPickerSearchQuery],
@@ -527,8 +538,8 @@ export function NewWorkspaceScreen({
const triggerLabel = useMemo(() => {
if (selectedItem) return pickerItemTriggerLabel(selectedItem);
return currentBranch ?? "main";
}, [currentBranch, selectedItem]);
return "Select branch";
}, [selectedItem]);
const selectedOptionId = useMemo(() => {
if (!selectedItem) return "";
@@ -588,6 +599,9 @@ export function NewWorkspaceScreen({
const buildCreateWorktreeInput = useCallback(
(input: { cwd: string; attachments: AgentAttachment[] }) => {
const checkoutRequest = pickerItemToCheckoutRequest(selectedItem);
if (!checkoutRequest) {
throw new Error("Choose a branch to start from");
}
return {
cwd: input.cwd,