Skip to content

refactor(cmd): split commands.rs into per-domain modules - #48

Merged
duyetbot merged 1 commit into
mainfrom
cursor/009-split-commands-4ce0
Sep 6, 2026
Merged

refactor(cmd): split commands.rs into per-domain modules#48
duyetbot merged 1 commit into
mainfrom
cursor/009-split-commands-4ce0

Conversation

@duyet

@duyet duyet commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Why

src/commands.rs held every command plus TUI plumbing in one 4,271-line file. Concurrent features collided there, and reviews mixed unrelated domains. The internal seams were already run_* per command, so this is a mechanical split with no behavior change.

Closes #24.

Scope

  • Add src/cmd/ with auth, login, models, usage, config_tui, launch, account, keys, menu, and dispatch.
  • src/commands.rs is a 154-line shim: run(), dispatch(), and the cmd imports. Target was ≤ 300 lines.
  • pub mod cmd; in src/lib.rs (alphabetically between channel and commands). Public entry stays commands::run.
  • Unit tests moved with their code: persist_login_tests in login.rs, picker catalog tests in models.rs, launcher tests in dispatch.rs.
  • No function renames. No command behavior change. Version stays 0.1.x.

Tradeoffs

Shared helpers that would cycle menuconfig_tui or modelslaunch live in dispatch.rs as a leaf: config_path, CreditsCache, catalog_lookup_enabled, tool_command_for, persist_tool_command, launcher_last_tool. RoutingField lives next to toggle_agent_routing_field in models.rs. pub(crate) on moved items is the crate-internal surface; nothing new is public outside the crate.

Blast Radius

Every CLI command still enters through commands::run. Callers in src/main.rs are unchanged. Reviewers should spot-check a few function bodies against main (ignore pub(crate) and rustfmt wraps on longer signatures). Do not merge release-please #15.

Verification

  • wc -l src/commands.rs → 154

  • cargo test --locked --all-targets → 186 lib + 68 cli + 7 release_lock

  • cargo fmt --check → exit 0

  • cargo clippy --locked --all-targets -- -D warnings → no new hits under src/cmd/ or src/commands.rs (baseline warnings remain in upgrade.rs / spawn.rs / http.rs, owned by chore(dx): enforce clippy and rustfmt in CI #45)

  • cargo build --locked --target wasm32-unknown-unknown --no-default-features → exit 0

  • control-anyr launch + doctor → all ok

  • Driven isolated anyr --help, --version, whoami, menu --dump-tui, config --dump-tui, auth --help → exit 0; help still lists CORE COMMANDS / LAUNCH; whoami masks the fixture key; menu dump shows LAUNCH / claude / CONFIGURE; config dump shows ACCOUNT / MODEL / AGENT / GENERAL

  • Version stays on 0.1.x (do not introduce 0.2 / 1.0)

  • Do not auto-merge release-please PRs

Open in Web Open in Cursor 

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

anyr size and startup

Startup is wall time for a cold anyr --version / anyr --help (median of 21 runs). Size is the stripped release binary, or the .wasm for the browser demo.

Size budget: anyr-linux-x86_64 must stay ≤ 4.0 MiB (4194304 bytes) stripped.

Asset Kind Size --version median --help median
anyr-darwin-arm64 native 2.8 MiB 4.41 ms 3.9 ms
anyr-darwin-x86_64 native 3.0 MiB 53.54 ms 50.88 ms
anyr-linux-arm64 native 2.8 MiB 0.7 ms 0.74 ms
anyr-linux-x86_64 native 3.1 MiB 1.03 ms 1.02 ms
anyr-windows-x86_64.exe native 2.5 MiB 9.47 ms 9.74 ms
anyr.wasm wasm 178.7 KiB

Budget check: ok

raw timings
[
  {
    "asset": "anyr-darwin-arm64",
    "kind": "native",
    "path": "/Users/runner/work/cli/cli/anyr-darwin-arm64",
    "bytes": 2927912,
    "size": "2.8 MiB",
    "version": "0.1.11 (built 2026-09-06 03:03:57)",
    "target": "aarch64-apple-darwin",
    "os": "macos-latest",
    "startup_version": {
      "n": 21,
      "min_ms": 3.99,
      "median_ms": 4.41,
      "p95_ms": 5.09,
      "mean_ms": 4.48
    },
    "startup_help": {
      "n": 21,
      "min_ms": 3.11,
      "median_ms": 3.9,
      "p95_ms": 5.63,
      "mean_ms": 4.05
    }
  },
  {
    "asset": "anyr-darwin-x86_64",
    "kind": "native",
    "path": "/Users/runner/work/cli/cli/anyr-darwin-x86_64",
    "bytes": 3133856,
    "size": "3.0 MiB",
    "version": "0.1.11 (built 2026-09-06 03:03:59)",
    "target": "x86_64-apple-darwin",
    "os": "macos-latest",
    "startup_version": {
      "n": 21,
      "min_ms": 45.33,
      "median_ms": 53.54,
      "p95_ms": 67.97,
      "mean_ms": 54.59
    },
    "startup_help": {
      "n": 21,
      "min_ms": 40.69,
      "median_ms": 50.88,
      "p95_ms": 58.45,
      "mean_ms": 50.48
    }
  },
  {
    "asset": "anyr-linux-arm64",
    "kind": "native",
    "path": "/home/runner/work/cli/cli/anyr-linux-arm64",
    "bytes": 2888744,
    "size": "2.8 MiB",
    "version": "0.1.11 (built 2026-09-06 03:03:12)",
    "target": "aarch64-unknown-linux-gnu",
    "os": "ubuntu-24.04-arm",
    "startup_version": {
      "n": 21,
      "min_ms": 0.66,
      "median_ms": 0.7,
      "p95_ms": 0.82,
      "mean_ms": 0.72
    },
    "startup_help": {
      "n": 21,
      "min_ms": 0.68,
      "median_ms": 0.74,
      "p95_ms": 0.79,
      "mean_ms": 0.74
    }
  },
  {
    "asset": "anyr-linux-x86_64",
    "kind": "native",
    "path": "/home/runner/work/cli/cli/anyr-linux-x86_64",
    "bytes": 3228256,
    "size": "3.1 MiB",
    "version": "0.1.11 (built 2026-09-06 03:03:17)",
    "target": "x86_64-unknown-linux-gnu",
    "os": "ubuntu-latest",
    "startup_version": {
      "n": 21,
      "min_ms": 1.0,
      "median_ms": 1.03,
      "p95_ms": 1.05,
      "mean_ms": 1.03
    },
    "startup_help": {
      "n": 21,
      "min_ms": 0.99,
      "median_ms": 1.02,
      "p95_ms": 1.11,
      "mean_ms": 1.04
    }
  },
  {
    "asset": "anyr-windows-x86_64.exe",
    "kind": "native",
    "path": "D:\\a\\cli\\cli\\anyr-windows-x86_64.exe",
    "bytes": 2673152,
    "size": "2.5 MiB",
    "version": "0.1.11 (built 2026-09-06T03:04:35Z)",
    "target": "x86_64-pc-windows-msvc",
    "os": "windows-latest",
    "startup_version": {
      "n": 21,
      "min_ms": 8.88,
      "median_ms": 9.47,
      "p95_ms": 10.64,
      "mean_ms": 9.7
    },
    "startup_help": {
      "n": 21,
      "min_ms": 8.7,
      "median_ms": 9.74,
      "p95_ms": 11.12,
      "mean_ms": 9.76
    }
  },
  {
    "asset": "anyr.wasm",
    "kind": "wasm",
    "path": "/home/runner/work/cli/cli/target/wasm-pkg/anyr_cli_bg.wasm",
    "bytes": 183006,
    "size": "178.7 KiB",
    "version": "wasm",
    "target": "wasm32-unknown-unknown",
    "os": ""
  }
]

Move the per-command implementations out of the 4500-line commands.rs into
focused modules under src/cmd/ (account, auth, config_tui, dispatch, keys,
launch, login, menu, models, usage). commands.rs keeps only run() + dispatch()
and re-exports from cmd; lib.rs registers pub mod cmd.

Pure structural move: every function, struct, enum, impl and test block from
commands.rs lands in exactly one cmd module with pub(crate) visibility so the
siblings that call it still resolve. No behavior changes (286 tests green,
clippy clean, release bin 3.07 MiB).

Closes #24.
@duyetbot
duyetbot force-pushed the cursor/009-split-commands-4ce0 branch from 536c37c to 2eecf28 Compare September 6, 2026 03:01
@duyetbot
duyetbot merged commit 0f51b8a into main Sep 6, 2026
9 checks passed
@duyetbot
duyetbot deleted the cursor/009-split-commands-4ce0 branch September 6, 2026 03:20
duyetbot pushed a commit that referenced this pull request Sep 6, 2026
Rebased onto post-split main (#48): the commands.rs hunks now land in their
per-domain cmd/ modules (run_whoami→usage, run_keys→keys, run_launch→launch,
launcher_uses_palette/persist_tool_command→dispatch,
run_config_tui/settings_tab_index/fill_agent_settings→config_tui,
run_menu→menu, dispatch cursor/cline/windsurf→stub).

Kept tip-of-main UX (#50-#54) where PR #52's #51-era assumptions diverged:
- help stays examples-first + the 'help commands' map (commands_help()
  retained); --help no longer dumps CORE COMMANDS.
- the compact HUD stays the default launcher, so the palette-only 'empty
  agents shows install' assertion was dropped (the HUD always offers
  Launch claude).
- config_reset_row's ToolCommand row keeps main's interactive prompt rather
  than PR #52's reset-to-default (newer UX); the should_persist_command guard
  is still applied so bare builtins are no longer written to config.

Carried forward the rest of PR #52: skip_confirm/--ok alias, confirmation
skips in keys, claude_fable display in whoami, settings tab via
ANYR_TUI_TAB, ToolCommand Install→Mapping, yolo via tool.extra_flag,
should_persist_command, plus the parse/relay/spawn/tui fixes and tests.
duyetbot pushed a commit that referenced this pull request Sep 6, 2026
Rebased onto post-split main (#48): the commands.rs hunks now land in their
per-domain cmd/ modules (run_whoami→usage, run_keys→keys, run_launch→launch,
launcher_uses_palette/persist_tool_command→dispatch,
run_config_tui/settings_tab_index/fill_agent_settings→config_tui,
run_menu→menu, dispatch cursor/cline/windsurf→stub).

Kept tip-of-main UX (#50-#54) where PR #52's #51-era assumptions diverged:
- help stays examples-first + the 'help commands' map (commands_help()
  retained); --help no longer dumps CORE COMMANDS.
- the compact HUD stays the default launcher, so the palette-only 'empty
  agents shows install' assertion was dropped (the HUD always offers
  Launch claude).
- config_reset_row's ToolCommand row keeps main's interactive prompt rather
  than PR #52's reset-to-default (newer UX); the should_persist_command guard
  is still applied so bare builtins are no longer written to config.

Carried forward the rest of PR #52: skip_confirm/--ok alias, confirmation
skips in keys, claude_fable display in whoami, settings tab via
ANYR_TUI_TAB, ToolCommand Install→Mapping, yolo via tool.extra_flag,
should_persist_command, plus the parse/relay/spawn/tui fixes and tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plan 009: Split commands.rs into per-domain modules

3 participants