# refactor\(web\): ChatView's draft machine routing lives in useDraftEnvironmentRouting · PR \#22728 · pingdotgg/t3code

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

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

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: refactor/chatview-draft-environment-routing

Target branch: refactor/chatview-activity-banners

Head commit: 7483af891cd7a34bc9f3c661a49d3af59b42574b

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

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

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

## Description

---

Automatic load balancing and the manual machine switch both decide one thing: which machine an unsent draft runs on. That state, its effect, and the in-flight switch refs took about 180 lines of ChatView.

`chat/useDraftEnvironmentRouting.ts` now holds them. It also owns the `useLoadBalancedEnvironment`, `useProjects` and `useScratchProject` reads that only this flow used. ChatView gets back the auto label, the switch and auto callbacks, the busy flag, and the pending-switch reader that `onSend` checks.

This layer moves code only and doesn't change render boundaries.

| | previous layer | this layer |
|---|---|---|
| ChatView.tsx lines | 7,533 | 7,372 |

Tests: `vp test run src/reactCompilerCoverage.test.ts` for ChatView and every new file (0 bailouts), `tsc-rs --noEmit` for apps/web, and oxlint on the changed files.

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

