diff --git a/packages/app/e2e/regression/subagent-child-navigation.spec.ts b/packages/app/e2e/regression/subagent-child-navigation.spec.ts index c3fa0148de4..937dfab6015 100644 --- a/packages/app/e2e/regression/subagent-child-navigation.spec.ts +++ b/packages/app/e2e/regression/subagent-child-navigation.spec.ts @@ -26,6 +26,16 @@ test("navigates to a subagent child session missing from the session list", asyn await expect(titlebarRight.getByRole("button", { name: "Toggle review" })).toHaveCount(1) }) +test("returns to the parent session with Escape", async ({ page }) => { + await setup(page) + await openChildFromParent(page) + await expectSessionTitle(page, taskDescription) + + await page.keyboard.press("Escape") + + await Promise.all([expect(page).toHaveURL(sessionHref(parentID)), expectSessionTitle(page, parentTitle)]) +}) + test("shows parent lineage while the child timeline loads", async ({ page }) => { await setup(page) const requested = Promise.withResolvers() diff --git a/packages/app/src/session/composer/region.tsx b/packages/app/src/session/composer/region.tsx index 3bfe4095003..794bba7454f 100644 --- a/packages/app/src/session/composer/region.tsx +++ b/packages/app/src/session/composer/region.tsx @@ -101,6 +101,10 @@ export function createActiveSessionRegion(input: { const focus = () => { if (!input.session.data.isChild()) promptRef?.focus() } + const openParent = () => { + const id = input.session.data.parentID() + if (id) navigate(sessionHref(requireServerKey(input.session.identity.params.serverKey), id)) + } const editable = (target: EventTarget | null | undefined) => { if (!(target instanceof HTMLElement)) return false return /^(INPUT|TEXTAREA|SELECT|BUTTON)$/.test(target.tagName) || target.isContentEditable @@ -113,6 +117,7 @@ export function createActiveSessionRegion(input: { return current instanceof HTMLElement ? current : undefined } const handleKeyDown = (event: KeyboardEvent) => { + if (event.defaultPrevented) return const path = event.composedPath() const target = path.find((item): item is HTMLElement => item instanceof HTMLElement) const active = activeElement() @@ -124,6 +129,11 @@ export function createActiveSessionRegion(input: { ) { return } + if (event.key === "Escape" && input.session.data.isChild()) { + event.preventDefault() + openParent() + return + } if (active === promptRef) { if (event.key === "Escape") promptRef?.blur() return @@ -172,10 +182,7 @@ export function createActiveSessionRegion(input: { }, region: { centered: input.screen.centered, - openParent: () => { - const id = input.session.data.parentID() - if (id) navigate(sessionHref(requireServerKey(input.session.identity.params.serverKey), id)) - }, + openParent, prompt, setDockRef: input.timeline.view.setDockRef, setPromptRef: (element: HTMLDivElement) => {