refactor(web): composer key handling lives in useComposerCommandKey#23060
The editor key handler and prompt-history navigation are about 140 lines in the composer body. The handler covers send shortcuts, the slash/mention menu keys, ArrowUp/ArrowDown history, the Shift+Tab plan toggle, and list continuation on Enter/Tab.
This PR moves:
navigatePromptHistory,replacePromptFromHistory, the history messages ref andonComposerCommandKeyintouseComposerCommandKey. The composer passes in the helpers it already had and keeps its existingonComposerCommandKeyStablewrapper.promptHistoryPositionRefstays in the composer, because the prompt-change handler also resets it.extendReplacementRangeForTrailingSpace, a pure helper used by mention, skill and text insertion, intocomposer-logic.tsnext toreplaceTextRange, with a test.
The existing layout-effect ref for prompt history messages moved with the code. This PR adds no useStableCallback and no new layout-effect refs.
| File | before | after |
|---|---|---|
| ChatComposer.tsx | 4,111 | 3,992 |
| useComposerCommandKey.ts | 264 |
Renders are unchanged. Typing 20 chars is 165 renders, the same as #23058.
Tested:
vp test run src/composer-logic.test.ts, 54 passed, including the new case.- apps/web typecheck and lint on the touched files.
- React Compiler: 0 bailouts on ChatComposer.tsx, useComposerCommandKey.ts and composer-logic.ts.
- Hands-on in a dev build:
- Enter sends from a draft.
- Enter sends in a seeded thread with history (Take Over PR 6315, Claude, Supervised). The thread first compacted its context, which it was already set to do, then the queued message ran and Claude replied "OK".
- In that thread, ArrowUp recalls the last prompt and ArrowDown clears it again.
- In the slash menu, ArrowDown moves the highlight and Escape closes the menu.
- Not checked: Shift+Tab. This dev environment shows no plan-mode control, so there was nothing to toggle.
🤖 Generated with Claude Code
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- Successful
Skipped - Not affected
- Skipped
- Skipped
- Skipped
- SuccessfulRemove preview downloadGitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- Successful
- Successful
- SuccessfulLabel PR 23060GitHub
- Successful
- Successful
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
- SuccessfulCheckGitHub
- SuccessfulNative fingerprint diffGitHub
- SkippedRelease SmokeGitHub
- SkippedRustGitHub
- Skipped
- SuccessfulBuild and TypecheckGitHub
- SuccessfulTestGitHub
- SuccessfulTest WebGitHub
- SkippedEAS PreviewGitHub
- SuccessfulLabel PR 23060GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
- SuccessfulNative fingerprint diffGitHub
- SuccessfulLintGitHub
- SuccessfulTest Server 5GitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulTest Server 8GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulChangesGitHub
Added 1 commit
- refactor(web): composer key handling lives in useComposerCommandKeyc59c78e
Approvability
Verdict: Approved at c59c78e
Macroscope's review found this PR approvable — This is a localized composer refactor that moves existing key-handling logic into a hook and relocates an unchanged pure helper, with no new user-facing capability or product-default change. The added test covers the helper, and the existing editor wiring and runtime branches remain equivalent.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Configuration used: Path: .coderabbit.config.ts
- Review profile: CHILL
- Plan: Team
- Run ID:
a2ae1422-02d9-45ed-98a5-76ce9f3acf44
📥 Commits
Reviewing files that changed from the base of the PR and between 959fea314650da81769dde58c4b89b77ffeada8f and c59c78e7b187b19a88634920f0d19d70270b90ff.
📒 Files selected for processing: 4
apps/web/src/components/chat/ChatComposer.tsxapps/web/src/components/chat/useComposerCommandKey.tsapps/web/src/composer-logic.test.tsapps/web/src/composer-logic.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.
📝 Walkthrough
ChatComposer now delegates keyboard command handling to
useComposerCommandKey. Trailing-space replacement range logic now resides in shared composer logic and has test coverage.Changes: Composer keyboard handling
Layer / File(s) Summary Shared replacement range logic
apps/web/src/composer-logic.ts,apps/web/src/composer-logic.test.ts,apps/web/src/components/chat/ChatComposer.tsxextendReplacementRangeForTrailingSpacenow resides in composer logic. Tests cover when it extends the range. ChatComposer imports the shared utility.Keyboard command hook
apps/web/src/components/chat/useComposerCommandKey.tsThe new hook handles prompt-history navigation, menu keyboard actions, submission dispatch, plan-mode toggling, list continuation, and indentation. ChatComposer integration
apps/web/src/components/chat/ChatComposer.tsxChatComposer imports the hook and passes it composer state, refs, menu handlers, prompt replacement logic, and submission callbacks. Priority: ⬇️ Low
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Refactor
Suggested reviewers:
maria-rcks
Merge Risk: ⚪ Minimal · up to c59c7
This refactor moves composer key handling into a hook without changing its behavior in the inspected code. No actionable merge risk remains.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly and concisely identifies the main change: moving composer key handling into useComposerCommandKey. Description check Passed The description explains the refactor, affected behaviors, file changes, validation results, manual checks, and the unverified Shift+Tab path. It omits the explicit Scope and approval section, but the… Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request. Full details: Description check
Explanation
The description explains the refactor, affected behaviors, file changes, validation results, manual checks, and the unverified Shift+Tab path. It omits the explicit Scope and approval section, but the core required information is present.
✨ Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.