# refactor\(web\): resuming an interrupted run lives in its own hook · PR \#23087 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/23087)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: refactor/split3-send-resume

Target branch: main

Head commit: 9c7a742e1f18ec3fb7be07b6099e20ea01c7a8d3

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/23087)

[Commits](https://git.cafe/pingdotgg/t3code/pull/23087/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/23087/diffs?format=markdown)

## Description

---

`useComposerSend` was moved verbatim out of ChatView in #23062. It is still one ~1,900-line hook that takes an 82-field input object. This stack splits it along its send paths, and each piece reads what it needs.

This layer moves resuming an interrupted run (and releasing held queued runs) into `useComposerResume`. ChatView calls that hook directly. Resume shares the per-route send lock with the other send paths through `draftSendState`, as before. `useComposerSend` no longer takes `resumableRunId`, `hasHeldQueuedRuns`, `interactionMode` or `scrollToEnd`.

| | before | after |
|---|---|---|
| `useComposerSend.ts` lines | 1,916 | 1,823 |
| `useComposerSend` input fields | 82 | 78 |
| `useComposerResume` input fields | — | 19 |

Render boundaries are unchanged: these are hooks inside ChatView, so render counts are unchanged and were not measured.

Tested in this worktree's dev server (isolated `.t3`, throwaway git repo as the project) with the whole stack applied: plain send from a draft (new thread), send with an image, queued follow-up and Ctrl+Enter steer during a running turn, resume of a stopped run, plan refinement and "Implement in a new thread" (legacy plan mode on), and a two-model start (two threads, two worktrees). All replies arrived and nothing errored. Also ran `apps/web` typecheck, lint on changed files (only the pre-existing `prefer-set-has` warning in `useComposerSend.ts` remains) and the React Compiler coverage test for changed files (0 bailouts).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

