Skip to content

[Bug] New-session page opened from the command palette doesn't focus the prompt box #4230

Description

@randypitcherii

Description

Opening the new-session page (/) from the command palette leaves the prompt textarea unfocused, so the user has to reach for the mouse before typing. It breaks this all-keyboard journey:

  1. ⌘K from an active session page
  2. type new
  3. "New chat" is the top result — hit Return
  4. the new-session prompt box should be focused, ready for the prompt

Today step 4 fails: focus lands on <body> and the first keystrokes go nowhere.

Root cause. The landing composer does focus itself — <textarea autoFocus> in NewChatLandingScreen (web/src/shell/NewChatDialog.tsx) — but the command palette takes it straight back. The palette is a Radix modal Dialog, and Radix's FocusScope keeps a document-level focusin trap installed until the dialog actually unmounts. The palette's close animation (data-closed:animate-out, ~150ms) delays that unmount well past the navigation, so:

  1. selection → close() + navigate("/") — the route swaps immediately
  2. the landing screen mounts and autoFocus focuses its textarea
  3. the still-installed trap sees a focusin outside its container and yanks focus back into the (now off-page) palette
  4. the palette finishes animating and unmounts; focus lands on <body>

This only reproduces in a real browser. jsdom runs no animations, so the trap releases in the same commit and a jsdom test never sees it. Verified with a Playwright test against a live server: the ⌘K → "new chat" journey fails, while the sidebar's "New session" link (no overlay in the way) already passes.

Same race, currently masked. Switching sessions from the palette focuses the in-session composer the same way — the conversationId bind effect in Composer (web/src/pages/ChatPage.tsx). That one happens to survive today only because session hydration delays the composer's mount past the palette's teardown. It's the same unguarded race, not a working design.

Related gap. The landing screen relies on autoFocus, which fires on mount only, so the per-project "New session" pencils (/?project=<name>) — which swap the query param while the screen stays mounted — leave the composer unfocused too.

Steps to reproduce

  1. Open the web UI and enter any session (/c/<id>).
  2. Press ⌘K (Ctrl+K on Linux/Windows).
  3. Type new and press Return.
  4. The new-session page loads. Type — nothing appears; document.activeElement is <body>.

And on /, clicking a project's "New session" pencil leaves the composer unfocused.

Expected

Entering the new-session page by any path leaves the caret in the prompt textarea, so the flow works end to end without touching the mouse. Switching sessions from the palette should land in that session's composer for the same reason, and by design rather than by timing.

Version

main @ 7316bb8

OS

macOS 15 / Chromium. Not platform-specific — the cause is the dialog close animation, so it affects every browser.

Metadata

Metadata

Assignees

Labels

BugSomething isn't workingP2-mediumPriority: bug with workaround, important feature requestcomp:web-uiComponent: web frontend (ap-web)triagedIssue has been triaged by the botvalidated:reproducedRepro agent validated the issue can be reproduced

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions