Problem
crates/tui/src/main.rs has grown into a second architecture map instead of a CLI entrypoint. At filing it was 11,549 lines (workspace 0.8.67, with 334 commits touching it since 2026-01-01); at v0.9.1 it is 14,878 lines and still hot — 14 commits touched it in the three days 2026-07-16..18 alone. Every command family lives beside the entrypoint, so unrelated CLI work conflicts in one file and new features land next to whichever helper was closest. The fix is mechanical: keep main.rs as the clap entrypoint and runtime bootstrap, and move command families whole into a new crates/tui/src/cli/ module tree.
Current evidence
Measured at v0.9.1 (2026-07-18), crates/tui/src/main.rs (14,878 lines; it is the [[bin]] codewhale-tui crate root, so all 113 top-level mod declarations at lines 25–137 must stay):
- Clap surface:
struct Cli (169), enum Commands with 27 subcommands (243–358: Doctor, SessionDiagnostics, Setup, RemoteSetup, Completions, Sessions, Init, Login, Logout, Auth, Models, Speech, Exec, Fleet, WorkflowTool, Review, Pr, Apply, Eval, Scorecard, Mcp, Execpolicy, Features, Sandbox, Serve, Resume, Fork), then ~1,000 lines of arg structs/enums through ~1285 (ExecArgs 359, FleetArgs 515, SetupArgs 816, DoctorArgs 847, ServeArgs/ServeBindHost 1032/1078, McpCommand 1125, SandboxArgs 1248).
- Dispatch:
fn main() (1286), run_async_main (1382).
- Command families, in file order:
run_eval (2050), run_scorecard (2123), run_fleet_command (2172), setup/init templates (run_setup 2882, run_setup_status 3150, run_setup_clean 3326, WriteStatus 2583, CleanPlan 2858), run_session_diagnostics (3365), the doctor family — the single largest block — run_doctor (3421) plus 40 doctor_* helper fns and report types through run_doctor_json/doctor_timeout_recovery_lines (5192–5788), run_execpolicy_command (5789), run_features_command (5795), run_models (5804), run_speech (5836), sessions/auth (list_sessions 6084, init_project 6153, run_login/run_logout 6234/6244, resolve_session_id/fork_session/pick_session_id 6261–6383), review/PR (run_review 6384, run_pr 6583, gh helpers 6639–6844), run_apply (6845), run_mcp_command (6886–7419), run_sandbox_command (7420), terminal-mode + checkpoint + project-config merge helpers (7542–8030), run_interactive (8031), and the exec family (resolve_cli_auto_route 8229, run_one_shot 8318, exec-stream receipts 8434–9315, run_workflow_tool_command 8636, run_exec_agent 9316–~10020).
- Inline test modules ride along:
speech_cli_tests (5968) and a ~4,860-line tail (10021–14878: serve_bind_host_tests, doctor_legacy_state_tests, doctor_setup_state_tests, doctor_endpoint_tests, terminal_mode_tests, interactive_startup_tests, project_config_tests, doctor_mcp_tests, doctor_live_probe_tests, setup_helper_tests, pr_prompt_tests — 193 tests).
crates/tui/src/cli/ does not exist yet. Note the existing crates/tui/src/commands/ is the user slash-command system — an unrelated concern — so the new tree must be named cli/ to avoid collision.
Scope
Mostly code motion; create module skeletons first, then move cohesive blocks whole (each family with its inline test module):
crates/tui/src/cli/args.rs — Cli, Commands, and all clap arg structs/enums/value parsers (169–1285).
crates/tui/src/cli/setup.rs — setup/init template generation and write-status reporting (2882–3364 plus WriteStatus/CleanPlan), with setup_helper_tests.
crates/tui/src/cli/serve.rs — serve/MCP bind-mode validation (ServeArgs, ServeBindHost, run_mcp_command 6886–7419), with serve_bind_host_tests and doctor_mcp_tests where they follow the code.
crates/tui/src/cli/doctor.rs — run_doctor + the doctor_* helper/report family (3421–5788) and its test modules; also a home for run_session_diagnostics, eval/scorecard routing if convenient.
crates/tui/src/cli/fleet.rs — run_fleet_command and Fleet arg types.
crates/tui/src/cli/exec.rs — exec prompt/model/tool-surface resolution and the one-shot/exec-stream/workflow-tool family (8180–10020).
main.rs keeps: module declarations, fn main, run_async_main dispatch, run_interactive, and small adapters into cli::*.
Start with the low-coupling families (setup, serve) before touching main() dispatch, per the 2026-07-02 handoff notes.
Key files
crates/tui/src/main.rs
crates/tui/Cargo.toml (bin target codewhale-tui, path src/main.rs)
crates/tui/src/commands/mod.rs (existing slash-command tree — do not merge into it)
Acceptance criteria
Verification
cargo test -p codewhale-tui --bin codewhale-tui --locked doctor_
cargo test -p codewhale-tui --bin codewhale-tui --locked setup_helper
cargo test -p codewhale-tui --bin codewhale-tui --locked serve_bind_host
cargo run -p codewhale-tui -- --help
cargo fmt
Diff the --help output (and one subcommand per moved family) against a pre-change capture.
Out of scope
- Renaming, merging, or re-flagging any subcommand.
- Touching
crates/tui/src/commands/ (user slash commands).
- Moving the 113 library
mod declarations out of the bin root (that is a lib/bin split, a different issue).
Related
Triage note: body restructured for agent execution on 2026-07-18; prior comment refinements folded in. Original wording preserved in edit history.
Problem
crates/tui/src/main.rshas grown into a second architecture map instead of a CLI entrypoint. At filing it was 11,549 lines (workspace 0.8.67, with 334 commits touching it since 2026-01-01); at v0.9.1 it is 14,878 lines and still hot — 14 commits touched it in the three days 2026-07-16..18 alone. Every command family lives beside the entrypoint, so unrelated CLI work conflicts in one file and new features land next to whichever helper was closest. The fix is mechanical: keepmain.rsas the clap entrypoint and runtime bootstrap, and move command families whole into a newcrates/tui/src/cli/module tree.Current evidence
Measured at v0.9.1 (2026-07-18),
crates/tui/src/main.rs(14,878 lines; it is the[[bin]] codewhale-tuicrate root, so all 113 top-levelmoddeclarations at lines 25–137 must stay):struct Cli(169),enum Commandswith 27 subcommands (243–358: Doctor, SessionDiagnostics, Setup, RemoteSetup, Completions, Sessions, Init, Login, Logout, Auth, Models, Speech, Exec, Fleet, WorkflowTool, Review, Pr, Apply, Eval, Scorecard, Mcp, Execpolicy, Features, Sandbox, Serve, Resume, Fork), then ~1,000 lines of arg structs/enums through ~1285 (ExecArgs359,FleetArgs515,SetupArgs816,DoctorArgs847,ServeArgs/ServeBindHost1032/1078,McpCommand1125,SandboxArgs1248).fn main()(1286),run_async_main(1382).run_eval(2050),run_scorecard(2123),run_fleet_command(2172), setup/init templates (run_setup2882,run_setup_status3150,run_setup_clean3326,WriteStatus2583,CleanPlan2858),run_session_diagnostics(3365), the doctor family — the single largest block —run_doctor(3421) plus 40doctor_*helper fns and report types throughrun_doctor_json/doctor_timeout_recovery_lines(5192–5788),run_execpolicy_command(5789),run_features_command(5795),run_models(5804),run_speech(5836), sessions/auth (list_sessions6084,init_project6153,run_login/run_logout6234/6244,resolve_session_id/fork_session/pick_session_id6261–6383), review/PR (run_review6384,run_pr6583, gh helpers 6639–6844),run_apply(6845),run_mcp_command(6886–7419),run_sandbox_command(7420), terminal-mode + checkpoint + project-config merge helpers (7542–8030),run_interactive(8031), and the exec family (resolve_cli_auto_route8229,run_one_shot8318, exec-stream receipts 8434–9315,run_workflow_tool_command8636,run_exec_agent9316–~10020).speech_cli_tests(5968) and a ~4,860-line tail (10021–14878:serve_bind_host_tests,doctor_legacy_state_tests,doctor_setup_state_tests,doctor_endpoint_tests,terminal_mode_tests,interactive_startup_tests,project_config_tests,doctor_mcp_tests,doctor_live_probe_tests,setup_helper_tests,pr_prompt_tests— 193 tests).crates/tui/src/cli/does not exist yet. Note the existingcrates/tui/src/commands/is the user slash-command system — an unrelated concern — so the new tree must be namedcli/to avoid collision.Scope
Mostly code motion; create module skeletons first, then move cohesive blocks whole (each family with its inline test module):
crates/tui/src/cli/args.rs—Cli,Commands, and all clap arg structs/enums/value parsers (169–1285).crates/tui/src/cli/setup.rs— setup/init template generation and write-status reporting (2882–3364 plusWriteStatus/CleanPlan), withsetup_helper_tests.crates/tui/src/cli/serve.rs— serve/MCP bind-mode validation (ServeArgs,ServeBindHost,run_mcp_command6886–7419), withserve_bind_host_testsanddoctor_mcp_testswhere they follow the code.crates/tui/src/cli/doctor.rs—run_doctor+ thedoctor_*helper/report family (3421–5788) and its test modules; also a home forrun_session_diagnostics, eval/scorecard routing if convenient.crates/tui/src/cli/fleet.rs—run_fleet_commandand Fleet arg types.crates/tui/src/cli/exec.rs— exec prompt/model/tool-surface resolution and the one-shot/exec-stream/workflow-tool family (8180–10020).main.rskeeps: module declarations,fn main,run_async_maindispatch,run_interactive, and small adapters intocli::*.Start with the low-coupling families (setup, serve) before touching
main()dispatch, per the 2026-07-02 handoff notes.Key files
crates/tui/src/main.rscrates/tui/Cargo.toml(bin targetcodewhale-tui, pathsrc/main.rs)crates/tui/src/commands/mod.rs(existing slash-command tree — do not merge into it)Acceptance criteria
main.rscontains the entrypoint, top-level dispatch, and runtime bootstrap, with no command-family implementation block larger than a small adapter.codewhale --helpand each subcommand's--helpbyte-identical before/after, modulo nothing).Verification
Diff the
--helpoutput (and one subcommand per moved family) against a pre-change capture.Out of scope
crates/tui/src/commands/(user slash commands).moddeclarations out of the bin root (that is a lib/bin split, a different issue).Related
Triage note: body restructured for agent execution on 2026-07-18; prior comment refinements folded in. Original wording preserved in edit history.