Decompose tools/subagent/mod.rs (19k lines): ordered extraction plan
- Dominant language
- Rust
- Stars
- 41k
- Forks
- 3.6k
- Avg merge
- 13h 59m
- Merged PRs (30d)
- 299
Description
## What
`crates/tui/src/tools/subagent/mod.rs` is ~19,200 lines / 360 top-level items;
its `tests.rs` sibling is ~23,200 lines. Every subagent fix pays the tax of
finding the defect site in a file no one can hold in their head, and every
edit risks unrelated coupling through `use super::*`. Extraction has started
(`advisor`, `budget_handback`, `coord`, `delivery`, `lifecycle`, `mailbox`,
`naming`, `worktree` are already siblings) but the bulk is still one file.
## How to split it (leaf clusters first, pure moves, one slice per commit)
Order by dependency direction — each slice must compile and pass the
subagent suite on its own, with no behavior change:
1. **Done:** `fallback_partial_text` + `tool_target_preview` →
`budget_handback.rs` (commit `7307f2302c`).
2. **Budget context cluster** (`child_wall_time_exhausted_reason`,
`child_runtime_budget_context`, `child_budget_pacing_notice`, ~80 lines) →
`budget_handback.rs` or a new `budgets.rs`.
3. **Summary/spill cluster** (`subagent_summary_char_budget`,
`stamp_subagent_summary*`, `spill_subagent_final_report`,
`summarize_subagent_result`, ~110 lines) → new `summary.rs`.
4. **Model routing cluster** (`configured_model_*`,
`resolve_subagent_assignment_route`, `subagent_reasoning_effort_*`,
~470 lines) → new `routing.rs`.
5. **Usage/accounting cluster** (`record_provider_response_usage`,
`refresh_usage_note`, `priced_usd_microusd`, `AgentRunUsage` helpers,
~220 lines) → new `usage.rs`.
6. **Tool admission policy** (`is_unbounded_shell_run`,
`reject_network_reaching_input`, `mutation_paths`, `build_allowed_tools`,
~320 lines of pure predicates) → new `admission.rs`.
7. **Checkpoint/persistence cluster** (`SubAgentCheckpoint`,
`PersistedSubAgent*`, `build_subagent_checkpoint`, …) → new
`checkpoint.rs`.
8. **`SubAgentToolRegistry` impl** (~1,400 lines, the single biggest block) →
new `tool_registry.rs`, after 6 removes its predicate dependencies.
9. **Spawn/parse cluster** (`SpawnRequest`, `parse_*`, launch) →
`lifecycle.rs` or new `spawn.rs`.
10. **Manager core + run loop** stay in `mod.rs` last; split `tests.rs` to
mirror whatever modules exist by then.
## Rules for each slice
- Pure move: `pub(super)` visibility, qualified call sites, zero behavior
change, subagent suite green before commit.
- Migrate all callers or do not start the slice (no shims, no re-exports
left behind "temporarily").
- New code goes in the new home from day one; `mod.rs` only shrinks.
## Acceptance
- [ ] `mod.rs` holds only the manager core + run loop (target: under 5,000 lines)
- [ ] Every slice above landed as behavior-preserving commits with green gates
- [ ] `tests.rs` split to mirror the module layout
- [ ] Related: #6034 (the `crate::config` monolith is the same disease one layer down)
Contributor guide
Research direction
Start with crates/tui/src/tools/subagent/mod.rs, the existing sibling modules, and the ordered extraction plan; inspect the budget context cluster first. Run the subagent suite after each pure move and migrate callers without temporary shims. Done means mod.rs contains only the manager core and run loop, tests.rs mirrors the modules, and all listed slices have green behavior-preserving commits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100