Skip to content

Extract run-composition logic from cli.py callbacks #243

Description

@pbean

Finding F-2 of the "Brownfield CLI/TUI Refactor Assessment" (local report, gitignored under _bmad-output/implementation-artifacts/).

Evidence

cli.py (2,588 lines) embeds workflow composition in argparse callbacks:

  • cmd_run (cli.py:757-845) builds RunState, validates the worktree, and wires the Engine inline.
  • _make_adapters (cli.py:125) and _platform_preflight (cli.py:214) are shared composition helpers living in the CLI module.
  • cmd_sweep (cli.py:1056) and cmd_resume (cli.py:1229) repeat the pattern.

Run composition is untestable without argparse, and the TUI can only reuse it by argv round-trip.

Recommendation — two PRs

PR 1 (cmd_run): create src/bmad_loop/runsetup.py (single module — do NOT create a services/ package) holding the adapter factory, platform preflight, and RunState/Engine composition as typed functions; cmd_run becomes parse → call runsetup → render.

PR 2 (cmd_resume + cmd_sweep): extend the same pattern to the remaining logic-heavy callbacks. Scope guard (assessment anti-goals): do NOT touch thin render-only callbacks (status/list/decisions/attach/etc.) — that would be pass-through layering.

Ordering

Sessions 6-7 of the refactor program. PR 2 requires PR 1 merged (verify on main).

Traps

  • The run subcommand's argv surface must not change — tui/launch.py round-trips through CLI argv; grep it for the flags it composes before touching anything.
  • tests/test_cli.py monkeypatches cli.* names (e.g. cli._make_adapters) — keep those names importable from cli.py as re-exports/delegators so tests stay untouched and green.
  • ruff F401 autofix deletes re-exports — pin with noqa: F401, verify with trunk check --no-fix.
  • Behavior-preserving moves only; no CHANGELOG (not user-visible).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions