diff --git a/ui/src/e2e/new-session-page.workspace-validation.e2e.test.ts b/ui/src/e2e/new-session-page.workspace-validation.e2e.test.ts index 2ade199bd1b3..895c50a76c73 100644 --- a/ui/src/e2e/new-session-page.workspace-validation.e2e.test.ts +++ b/ui/src/e2e/new-session-page.workspace-validation.e2e.test.ts @@ -142,7 +142,7 @@ suite.define(() => { } }); - it("blocks a custom worktree when Git rediscovery is unavailable", async () => { + it("allows clearing a custom worktree when Git rediscovery is unavailable", async () => { const context = await suite.browser.newContext({ locale: "en-US", serviceWorkers: "block" }); const page = await context.newPage(); const gateway = await installMockGateway(page, { @@ -155,6 +155,7 @@ suite.define(() => { defaultBranch: "main", repositoryStatus: "git", }, + "sessions.create": { key: "agent:main:custom-worktree-cleared" }, }, }); @@ -192,11 +193,23 @@ suite.define(() => { await expect.poll(() => start.isDisabled()).toBe(true); await trigger.click(); const worktree = place.getByRole("button", { name: "Worktree" }); - expect(await worktree.isDisabled()).toBe(true); + expect(await worktree.isEnabled()).toBe(true); expect(await worktree.getAttribute("title")).toBe( "Couldn't verify Git for this folder. Choose it again to retry.", ); - expect(await gateway.getRequests("sessions.create")).toHaveLength(0); + await worktree.click(); + await expect.poll(() => trigger.getAttribute("data-worktree")).toBe("false"); + await expect.poll(() => start.isEnabled()).toBe(true); + await page.keyboard.press("Escape"); + + await start.click(); + const create = await gateway.waitForRequest("sessions.create"); + expect(create.params).toMatchObject({ + agentId: "main", + cwd: TARGET_REPO, + message: "do not run directly", + }); + expect(create.params).not.toHaveProperty("worktree"); } finally { await context.close(); } diff --git a/ui/src/pages/new-session/place-picker.ts b/ui/src/pages/new-session/place-picker.ts index aa057edf17d7..b89cba3bba79 100644 --- a/ui/src/pages/new-session/place-picker.ts +++ b/ui/src/pages/new-session/place-picker.ts @@ -399,7 +399,11 @@ export function renderPlaceSelect(params: { value: "worktree", label: t("newSession.worktree"), checked: params.worktree, - disabled: Boolean(params.cloudProfileId) || !params.worktreeAvailable, + // Failed discovery blocks enabling Worktree, but an existing selection + // must stay actionable so the user can clear the submit-blocking state. + disabled: + Boolean(params.cloudProfileId) || + (!params.worktreeAvailable && !params.worktree), title: params.cloudProfileId ? t("newSession.cloudRequiresWorktree") : params.worktreeAvailable