Skip to main content

16. Modular CLI Command Structure

Status: Accepted Date: 2025-07-06

Context

The kaido-cli tool is expected to grow and include many commands, each with its own logic, options, and responsibilities (e.g., fdd:validate, rules:deploy, adr:create). Placing all command logic into a single large file or a few large files would quickly become unmanageable, difficult to debug, and a bottleneck for extension.

Decision

We will adopt a modular structure where each command is implemented in its own dedicated file/module. We will leverage the Commander.js library's recommended approach for scalable command structures.

  1. Main Entry Point (index.ts): This file will be responsible for setting up the main program object and dynamically loading command modules from the commands directory.
  2. Command Modules: Each command will be in its own file (e.g., fdd-validate.command.ts). This module will define its own command, options, and action handler, and then export the configured Command object.
  3. Registration: The main entry point will iterate over these modules and register them with the main program.

For example, a command like fdd:validate would be implemented in src/commands/fdd/validate.ts, keeping its logic completely isolated.

Consequences

Positive:

  • Maintainability: Each command is self-contained, making it easy to find, update, and debug its logic without impacting other commands.
  • Scalability: Adding a new command is as simple as creating a new file and registering it. The system is designed for growth.
  • Testability: Individual command modules can be unit-tested in isolation more easily than if they were part of a monolith.
  • Readability: The codebase is cleaner, more organized, and easier for developers to navigate.

Negative:

  • File Proliferation: This approach leads to a larger number of small files, which might be perceived as clutter.
  • Boilerplate: Each new command file requires some boilerplate code to set up the command with Commander.js.

Mitigation:

  • Code Generation: Use code generation tools, scripts, or IDE snippets to scaffold new command files with the required boilerplate, reducing manual setup.
  • Shared Utilities: Create shared utility functions for common tasks (e.g., file reading, logging, error handling) that can be imported by any command module. This promotes DRY principles and reduces code duplication across commands.