Hmbown / Hmbown/Codewhale

Decompose tools/subagent/mod.rs (19k lines): ordered extraction plan

Open
#6,293 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.