Skip to content

Fix new-thread shortcuts when terminal has focus#984

Merged
juliusmarminge merged 2 commits intomainfrom
t3code/fix-terminal-mod-n-keybinding
Mar 12, 2026
Merged

Fix new-thread shortcuts when terminal has focus#984
juliusmarminge merged 2 commits intomainfrom
t3code/fix-terminal-mod-n-keybinding

Conversation

@juliusmarminge
Copy link
Member

@juliusmarminge juliusmarminge commented Mar 12, 2026

Summary

  • move global new-thread keyboard shortcut handling to the chat route so it works consistently outside sidebar scope
  • add shared useHandleNewThread hook to centralize draft-thread reuse/creation and navigation behavior
  • add isTerminalFocused utility and use shortcut command resolution with terminal context (terminalFocus, terminalOpen)
  • remove duplicate shortcut logic from Sidebar and inline terminal-focus detection from ChatView
  • update browser fixture RPC handling to support terminalOpen requests in ChatView.browser tests

Testing

  • Not run (no test changes in this commit)
  • Not run: bun fmt
  • Not run: bun lint
  • Not run: bun typecheck

Note

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.newLocal behavior by moving global keydown handling out of Sidebar and into the /_chat route (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 useHandleNewThread hook, and deduplicates terminal-focus detection via new isTerminalFocused() utility (also used by ChatView).

Updates terminal handling to cap splits per terminal group (MAX_TERMINALS_PER_GROUP) rather than a global max, reflecting this in ChatView, ThreadTerminalDrawer, and terminalStateStore, with new/updated tests and MSW WS fixtures (including terminalOpen) 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.new and chat.newLocal shortcuts when terminal has focus

  • Moves global chat.new/chat.newLocal shortcut handling from Sidebar into a new ChatRouteGlobalShortcuts component in _chat.tsx, which is context-aware of terminal focus and open state via a new isTerminalFocused utility.
  • Adds useHandleNewThread hook to centralize draft thread creation/reuse logic previously duplicated in Sidebar.
  • Changes terminal split limits from a global cap to a per-group cap (MAX_TERMINALS_PER_GROUP = 4); creating new terminals in a new group is now always allowed.
  • Behavioral Change: Sidebar no longer registers keydown listeners for new-thread shortcuts; shortcuts now fire correctly even when an xterm terminal element has focus.

Macroscope summarized dc4eac8.

- 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
@github-actions github-actions bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Mar 12, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ff846d1e-57b4-4f15-898b-4454c3919761

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch t3code/fix-terminal-mod-n-keybinding
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Stale activeDraftThread due to missing store data subscription
    • Replaced the stable getDraftThread function reference selector with a direct subscription to store.draftThreadsByThreadId[routeThreadId], ensuring the component re-renders when draft thread data changes.

Create PR

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
@juliusmarminge juliusmarminge merged commit c52ad29 into main Mar 12, 2026
8 of 9 checks passed
@juliusmarminge juliusmarminge deleted the t3code/fix-terminal-mod-n-keybinding branch March 12, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant