Fix new-thread shortcuts when terminal has focus#984
Conversation
- move chat-wide key handling into `_chat` route-level shortcut handler - extract reusable `useHandleNewThread` hook and `isTerminalFocused` helper - update browser WS fixture to support `terminalOpen` RPC shape
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Stale
activeDraftThreaddue to missing store data subscription- Replaced the stable
getDraftThreadfunction reference selector with a direct subscription tostore.draftThreadsByThreadId[routeThreadId], ensuring the component re-renders when draft thread data changes.
- Replaced the stable
Or push these changes by commenting:
@cursor push 55dbe3f48c
Preview (55dbe3f48c)
diff --git a/apps/web/src/hooks/useHandleNewThread.ts b/apps/web/src/hooks/useHandleNewThread.ts
--- a/apps/web/src/hooks/useHandleNewThread.ts
+++ b/apps/web/src/hooks/useHandleNewThread.ts
@@ -11,7 +11,6 @@
const getDraftThreadByProjectId = useComposerDraftStore(
(store) => store.getDraftThreadByProjectId,
);
- const getDraftThread = useComposerDraftStore((store) => store.getDraftThread);
const setProjectDraftThreadId = useComposerDraftStore((store) => store.setProjectDraftThreadId);
const setDraftThreadContext = useComposerDraftStore((store) => store.setDraftThreadContext);
const clearProjectDraftThreadId = useComposerDraftStore(
@@ -26,7 +25,9 @@
const activeThread = routeThreadId
? threads.find((thread) => thread.id === routeThreadId)
: undefined;
- const activeDraftThread = routeThreadId ? getDraftThread(routeThreadId) : null;
+ const activeDraftThread = useComposerDraftStore((store) =>
+ routeThreadId ? (store.draftThreadsByThreadId[routeThreadId] ?? null) : null,
+ );
const handleNewThread = useCallback(
(- ensure `chat.new` creates a fresh draft after a promoted draft thread - enforce terminal cap per split group (4) while allowing additional terminal groups - refine sidebar row selected/active styling via shared class-name logic and tests


Summary
useHandleNewThreadhook to centralize draft-thread reuse/creation and navigation behaviorisTerminalFocusedutility and use shortcut command resolution with terminal context (terminalFocus,terminalOpen)Sidebarand inline terminal-focus detection fromChatViewterminalOpenrequests inChatView.browsertestsTesting
bun fmtbun lintbun typecheckNote
Medium Risk
Changes global keyboard shortcut handling and draft-thread creation/navigation, plus adjusts terminal split limits (per-group) in state and UI; regressions could affect thread routing or terminal management across the app.
Overview
Fixes inconsistent
chat.new/chat.newLocalbehavior by moving global keydown handling out ofSidebarand into the/_chatroute (ChatRouteGlobalShortcuts), resolving commands with context (terminalFocus,terminalOpen) so shortcuts don’t trigger while the terminal is focused.Extracts draft-thread reuse/creation + navigation into a shared
useHandleNewThreadhook, and deduplicates terminal-focus detection via newisTerminalFocused()utility (also used byChatView).Updates terminal handling to cap splits per terminal group (
MAX_TERMINALS_PER_GROUP) rather than a global max, reflecting this inChatView,ThreadTerminalDrawer, andterminalStateStore, with new/updated tests and MSW WS fixtures (includingterminalOpen) to cover shortcut-driven thread creation and promoted-draft behavior.Written by Cursor Bugbot for commit dc4eac8. This will update automatically on new commits. Configure here.
Note
Fix
chat.newandchat.newLocalshortcuts when terminal has focuschat.new/chat.newLocalshortcut handling fromSidebarinto a newChatRouteGlobalShortcutscomponent in _chat.tsx, which is context-aware of terminal focus and open state via a newisTerminalFocusedutility.useHandleNewThreadhook to centralize draft thread creation/reuse logic previously duplicated inSidebar.MAX_TERMINALS_PER_GROUP = 4); creating new terminals in a new group is now always allowed.Sidebarno longer registerskeydownlisteners for new-thread shortcuts; shortcuts now fire correctly even when an xterm terminal element has focus.Macroscope summarized dc4eac8.