diff --git a/packages/app/src/screens/new-workspace-screen.test.tsx b/packages/app/src/screens/new-workspace-screen.test.tsx index 93d9e99f30..f118d9f933 100644 --- a/packages/app/src/screens/new-workspace-screen.test.tsx +++ b/packages/app/src/screens/new-workspace-screen.test.tsx @@ -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(); diff --git a/packages/app/src/screens/new-workspace-screen.tsx b/packages/app/src/screens/new-workspace-screen.tsx index 3421c27ad2..a9fd44ed5a 100644 --- a/packages/app/src/screens/new-workspace-screen.tsx +++ b/packages/app/src/screens/new-workspace-screen.tsx @@ -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,