refactor(web): the prompt stash lives in useComposerStash#23046
Stashing, restoring and deleting prompts took about 550 lines of the composer body. Its state was declared hundreds of lines away from the code that used it.
useComposerStash now owns all of it:
- the stash menu open state
- the badge pulse, plus the timer and in-flight refs behind it
- the stash store selectors
stashCurrentPrompt,restoreStashEntryanddeleteStashEntrytoggleStashMenu- closing the menu when the prompt changes
- the
composer.stashshortcut listener
The hook reads the draft-store setters it needs itself and takes the composer values it reads as one input object. It returns what the badge and menu render.
The hook is called where the stash code used to start, so the order of the composer's other effects is unchanged. The stash shortcut listener now registers ahead of a few layout effects in between, none of which listen for keydown. The existing useStableCallback wrappers moved with the code. This PR adds none.
| File | before | after |
|---|---|---|
| ChatComposer.tsx | 5,434 | 4,860 |
| useComposerStash.ts | 745 |
Renders are unchanged. With Claude selected, typing 20 chars is 224 renders before and after.
Tested:
- apps/web typecheck and lint on the touched files.
- React Compiler: 0 bailouts on both files.
- Hands-on in a dev build. Ctrl+S stashes the prompt, clears the composer and shows the badge. The badge opens the menu. Restore puts the prompt back. Delete removes the entry and the badge.
🤖 Generated with Claude Code
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- Successful
Skipped - Not affected
- Skipped
- Skipped
- Skipped
- SuccessfulRemove preview downloadGitHub
- SuccessfulLabel PR 23046GitHub
- Skipped
- Successful
- Successful
- SuccessfulLabel PR sizeGitHub
- Successful
- Successful
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
- SuccessfulCheckGitHub
- Skipped
- SkippedRustGitHub
- SkippedRelease SmokeGitHub
- SuccessfulBuild and TypecheckGitHub
- SuccessfulTest WebGitHub
- SuccessfulTestGitHub
- SuccessfulLabel PR 23046GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 5GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 8GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulLintGitHub
- SuccessfulChangesGitHub
- SkippedEAS PreviewGitHub
- SuccessfulNative fingerprint diffGitHub
- SuccessfulCollect PR targetsGitHub
- SuccessfulPrepare PR size configGitHub
Added 1 commit
- refactor(web): the prompt stash lives in useComposerStash25fa572
Approvability
Verdict: Approved at 25fa572
Macroscope's review found this PR approvable — This PR extracts the existing prompt-stash state, persistence, attachment handling, and shortcut logic from ChatComposer into a dedicated local hook. The diff is large because of the relocation, but it does not introduce a new capability, product-default change, schema change, or sensitive runtime path.
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:
f4774186-f9f2-44c4-8a2e-20597f936d7a
📥 Commits
Reviewing files that changed from the base of the PR and between 1807a1e9c9d9c7e2dd80b05c6c43041dc5172a8e and 25fa572eba1b8a200711bee4bb5b3acc7e39e5c0.
📒 Files selected for processing: 2
apps/web/src/components/chat/ChatComposer.tsxapps/web/src/components/chat/useComposerStash.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
📝 Walkthrough
ChatComposer now delegates prompt-stash state and workflows to the new useComposerStash hook. The hook manages stash creation, restoration, deletion, menu state, badge pulses, and shortcut handling.
Changes: Composer prompt stash
Layer / File(s) Summary Hook state and restoration
apps/web/src/components/chat/useComposerStash.tsThe hook manages stash state and restores prompts, context records, files, and images. Restoration validates attachments and applies deduplication and capacity limits. Stash operations and shortcuts
apps/web/src/components/chat/useComposerStash.tsThe hook validates and persists stash entries, handles deletion and image compression, updates menu and badge state, and processes the stash shortcut. Composer integration
apps/web/src/components/chat/ChatComposer.tsxChatComposer calls the hook and uses its returned state and actions. The inline stash implementation and local shortcut listener are removed. Priority: ⬇️ Low
Estimated code review effort: 4 (Complex) | ~45 minutes
Change: Refactor
Suggested reviewers:
t3dotgg
Merge Risk: ⚪ Minimal · up to 25fa5
This refactor moves prompt-stash handling into its own hook without a stated behavior change. Review found no concrete defect, so no merge-blocking risk remains.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly and concisely describes the main change: moving prompt-stash logic into useComposerStash. Description check Passed The description clearly explains the refactor and provides focused verification results. It does not include a dedicated Problem or Scope and approval section, but it identifies the problem and remain… 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 clearly explains the refactor and provides focused verification results. It does not include a dedicated Problem or Scope and approval section, but it identifies the problem and remains sufficiently complete and on topic.
✨ 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.