refactor(web): ChatView's send paths live in useComposerSend#23062
ChatView carried every send path inline: a ~1,200-line onSend plus resume, plan follow-up, and implement-in-a-new-thread, with the commands and draft-store setters only they use.
They move verbatim into chat/useComposerSend.ts. The hook selects its own orchestration commands and draft-store setters, and owns the state only sends touch (resuming keys, send generation, the unavailable-environment toast slot, and the approval refs a send reads after its uploads). ChatView passes what it already derives. No send logic changed.
| Before | After | |
|---|---|---|
ChatView.tsx lines | 7,258 | 5,700 |
Hands-on in the dev server at the top of this stack, which carries this code unchanged (Claude, a sandbox git project): new thread from a draft, plain follow-ups in that thread, a send with an attached image (the reply named its color), a message queued behind a running turn and then promoted to steer, /plan as a standalone slash command, a plan request and a plan follow-up that revised it, "Implement in a new thread", a multiple-model start (two worktree threads started, the draft composer came back), and resuming an interrupted run. Each worked.
Renders, median of 3, counted with the commit-only fiber counter on a dev server seeded from real data (stack top vs the stack's base; "ChatView" is ChatView's own render count):
| Interaction | Before: commits / renders / ChatView | After: commits / renders / ChatView |
|---|---|---|
| Type 20 chars in the composer | 22 / 351 / 1 | 22 / 351 / 1 |
| Streaming reply (12 lines) | 129 / 3412 / 18 | 134 / 3406 / 18 |
| Switch threads | 26 / 1520 / 5 | 26 / 1480 / 5 |
| Open and close the right panel | 14 / 603 / 4 | 14 / 569 / 4 |
No render boundary moved in a way that changes these: the hooks run inside ChatView, and the new leaf components are small. The point of the stack is readability and per-file compiler caching, not a render win.
Tests: tsc-rs --noEmit for apps/web, oxlint on the changed files, vp test run src/components/ChatView.logic.test.ts, and the React Compiler coverage test for every changed file (0 bailouts). ChatView stays in the coverage test's slow set.
Part of the ChatView split (7,258 → 3,975 lines across the stack).
Opus 5.5, Claude Code.
🤖 Generated with Claude Code
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- Skipped
- Skipped
- Skipped
- SuccessfulRemove preview downloadGitHub
- SuccessfulCheckGitHub
- Skipped
- Skipped
- Skipped
- SkippedRustGitHub
- SkippedRelease SmokeGitHub
- SuccessfulBuild and TypecheckGitHub
- SuccessfulTestGitHub
- SuccessfulTest WebGitHub
- Skipped
- Skipped
- Skipped
- SuccessfulLabel PR sizeGitHub
- SuccessfulLabel PR 23062GitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SuccessfulTest Server 8GitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 5GitHub
- Skipped
- SuccessfulLintGitHub
- SuccessfulChangesGitHub
- SuccessfulNative fingerprint diffGitHub
- Skipped
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
Approvability
Verdict: Approved at 9883c52
Macroscope's review found this PR approvable — This PR extracts ChatView’s existing send, resume, feedback, plan, attachment, and multi-model flows into a custom hook without introducing new behavior, defaults, schemas, or infrastructure changes. The large diff is primarily relocation and explicit parameter plumbing, leaving the existing production paths intact.
No code changes detected at d17ebea. Prior analysis still applies.
You can add or adjust custom eligibility rules. Learn more.
Added 1 commit
- refactor(web): ChatView's send paths live in useComposerSendd17ebea
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:
44710f5b-8357-4873-92d9-5bccb04c751c
📥 Commits
Reviewing files that changed from the base of the PR and between e78f58046876271109bf6985e8f46769d8e7505d and d17ebeae9f3fcceaefe276bbfda6ac610dd7b312.
📒 Files selected for processing: 2
apps/web/src/components/ChatView.tsxapps/web/src/components/chat/useComposerSend.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
📝 Walkthrough
ChatView delegates composer sending, resuming, and plan actions to the new
useComposerSendhook. The hook contains the related validation, dispatch, attachment, draft, approval, and recovery workflows.Changes: Composer Send Flow
Layer / File(s) Summary Hook contract and ChatView wiring
apps/web/src/components/chat/useComposerSend.ts,apps/web/src/components/ChatView.tsxAdded the hook contract and initialization. ChatView passes the required state and callbacks to the hook and removes the extracted send-flow implementations and supporting state. Resume and submission routing
apps/web/src/components/chat/useComposerSend.tsAdded resumption handling and routing for usage limits, environment and provider availability, queued edits, feedback, plan follow-ups, slash commands, and terminal contexts. Turn preparation and approval checks
apps/web/src/components/chat/useComposerSend.tsAdded turn planning, worktree and attachment validation, upload handling, and checks for pending approvals before dispatch. Dispatch and recovery
apps/web/src/components/chat/useComposerSend.tsAdded multiple-model and standard thread dispatch, optimistic messages, attachment and background-draft handling, cleanup, and failure recovery. Plan follow-up and implementation
apps/web/src/components/chat/useComposerSend.tsAdded proposed-plan follow-up submission and implementation in a new thread, including startup, navigation, cleanup, and error handling. Priority: ⬇️ Low
Estimated code review effort: 4 (Complex) | ~45 minutes
Change: Refactor
Suggested reviewers:
t3dotgg
Merge Risk: ⚪ Minimal · up to d17eb
This refactor moves the composer send, resume, and plan follow-up logic into a dedicated hook without intended behavior changes. No concrete regression was identified, and the PR is ready to merge after the usual checks.
Pre-merge checks: Passed 3 · Failed 1
Failed Failed checks: 1 warning
Check name Status Explanation Resolution Description check Warning The description explains the problem, change, verification steps, manual checks, and performance observations. It does not include the required Scope and approval information, such as a linked issue, … Add a Scope and approval section with the triaged issue or explicit maintainer approval and link. If no prior issue or approval is required, explain why this focused refactor qualifies for the exemption. Passed Passed checks: 3 passed
Check name Status Explanation Title check Passed The title clearly and concisely describes the main change: moving ChatView send paths into useComposerSend. 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 problem, change, verification steps, manual checks, and performance observations. It does not include the required Scope and approval information, such as a linked issue, maintainer approval, or a rationale for exemption.
Resolution
Add a Scope and approval section with the triaged issue or explicit maintainer approval and link. If no prior issue or approval is required, explain why this focused refactor qualifies for the exemption.
✨ 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.