4.3 KiB
Context
The rusty-claude-cli application currently suffers from having a massive entry point. The src/main.rs file is over 6,200 lines long, combining CLI argument parsing, configuration loading, API interaction, terminal UI rendering, tool execution, and permission prompting. This violates the Single Responsibility Principle, making the codebase difficult to navigate, test, and maintain. Compiling a single massive file also creates a bottleneck for the Rust compiler.
Goals / Non-Goals
Goals:
- Break down
src/main.rsinto smaller, logically grouped modules following Domain-Driven Design (DDD). - Establish clear dependency boundaries between these new modules.
- Maintain 100% backward compatibility with the existing CLI behavior.
- Ensure all existing tests pass (
cargo test). - Improve incremental compilation times.
Non-Goals:
- Introducing any new CLI features, commands, or behaviors.
- Rewriting the internal logic of functions (beyond fixing visibility
pub(crate)and imports). - Modifying the underlying
api,runtime, ortoolscrates.
Decisions
1. Target Directory Structure
We will adopt the following module structure:
src/main.rs: Stripped down to the bare minimum. Containsfn main(), top-levelmoddeclarations, and the root routing logic.src/cli/: Handles command-line input.parser.rs:parse(),CliAction,parse_acp_args(), etc.suggestions.rs: Spell checking and command suggestions (suggest_slash_commands,levenshtein_distance).
src/config/: Configuration and model validation.models.rs:resolve_model_alias(),validate_model_syntax(), etc.
src/execution/: Core engine logic.executor.rs:CliToolExecutor,execute_runtime_tool().client.rs:AnthropicRuntimeClient,build_runtime().stream.rs: API streaming responses (consume_stream(),response_to_events()).
src/permissions/: Security policies.prompter.rs:CliPermissionPrompter,permission_policy().
src/diagnostics/: System health checks.mod.rs:DiagnosticCheck,DiagnosticLevel.
src/ui/: Terminal interactions.progress.rs:CliHookProgressReporter,describe_tool_progress().
Rationale: This structure separates concerns naturally. The cli handles user input, config manages state, execution orchestrates the logic, and ui handles the output.
2. Incremental Extraction Strategy
Instead of moving all code in one massive cut-and-paste operation, the refactoring will proceed in topological order from the leaves to the root:
- Extract leaf nodes with few dependencies (e.g.,
diagnostics,config/models.rs,cli/suggestions.rs). - Extract intermediate nodes (e.g.,
permissions,ui/progress.rs). - Extract core components (
execution). - Extract the top-level parser (
cli/parser.rs). - Update
main.rsto route to these modules.
Rationale: Attempting to split everything simultaneously often leads to overwhelming compiler errors regarding missing imports or circular dependencies. Step-by-step extraction ensures that cargo check can validate each step.
3. Visibility Changes
Moved structures and functions that were previously private within main.rs will be updated to pub(crate) so they can be accessed across the new module boundaries within the crate, without exposing them publicly outside the crate.
Risks / Trade-offs
- Risk: Circular Dependencies. Code currently co-located in
main.rsmight have hidden cyclic dependencies that will become apparent when split into separate files.- Mitigation: Ensure a strict dependency graph:
clidepends onexecutionandconfig;executiondepends onpermissions,ui, andconfig. If cycles are found, we may need to introduce shared generic interfaces or move shared types to a commontypes.rsormodels.rsmodule.
- Mitigation: Ensure a strict dependency graph:
- Risk: Broken Unit Tests. Tests residing at the bottom of
main.rsmight break when functions are moved.- Mitigation: Move unit tests alongside the code they test into their respective new modules. Verify with
cargo testafter each module extraction.
- Mitigation: Move unit tests alongside the code they test into their respective new modules. Verify with
- Risk: Extensive Import Updates. Every file will need its
usestatements heavily updated.- Mitigation: Rely on the Rust compiler and IDE diagnostics to find and fix missing imports iteratively.