VOOZH about

URL: https://deepwiki.com/guanguans/ai-commit/4.2-command-architecture

⇱ Command Architecture | guanguans/ai-commit | DeepWiki


Loading...
Menu

Command Architecture

This page documents the command registration system, the three application commands (CommitCommand, ConfigCommand, ThanksCommand), and the patterns they use to integrate with the Laravel Zero console kernel.

For end-user documentation of what these commands do, see 3.1 For command flags and options as a user reference, see 3.2 For how the underlying ConfigManager and GeneratorManager work, see 4.4 and 4.3 respectively.


Command Registration

Command registration is controlled by a single file: config/commands.php The Laravel Zero kernel reads this file at boot time to configure the console application.

Command registration configuration structure:

KeyPurpose
defaultCommand class to run when no command name is provided
pathsDirectory paths scanned for Command subclasses
addIndividual command classes to register explicitly
hiddenCommands that remain runnable but are not listed in help output
removeCommands from service providers to exclude entirely

The paths key points to app_path('Commands'), so any class in app/Commands/ that extends Illuminate\Console\Command is automatically registered. The default key is set to App\Commands\CommitCommand::class, meaning running the ai-commit binary with no subcommand invokes CommitCommand directly.

Several framework-internal commands are placed in the hidden list, including SummaryCommand, HelpCommand, and scheduling commands, keeping the list output clean.

Sources: config/commands.php1-95


Command registration flow:


Sources: config/commands.php1-95


Command Class Hierarchy and Dependencies

All three application commands extend LaravelZero\Framework\Commands\Command, which itself extends Illuminate\Console\Command.

Class and dependency diagram:


Sources: app/Commands/CommitCommand.php32-45 app/Commands/ConfigCommand.php30-47 app/Commands/ThanksCommand.php18-44


CommitCommand

File: app/Commands/CommitCommand.php
Signature: commit

CommitCommand is the primary application command and the default command. It receives GeneratorManager through constructor injection (resolved by the service container) and acquires a ConfigManager instance via config('ai-commit'), which returns the singleton bound in AppServiceProvider.

Option Definition Pattern

CommitCommand overrides configure() rather than using the $signature string to define its inputs, allowing programmatic default values sourced directly from ConfigManager at instantiation time.

Options defined in configure():

OptionShortTypeDefault source
pathOPTIONAL argumentConfigManager::localPath('')
--commit-optionsVALUE_IS_ARRAYconfigManager.commit_options
--diff-optionsVALUE_IS_ARRAYconfigManager.diff_options
--generator-gVALUE_REQUIREDconfigManager.generator
--prompt-pVALUE_REQUIREDconfigManager.prompt
--no-editVALUE_NONE
--no-verifyVALUE_NONE
--config-cVALUE_OPTIONAL
--dry-runVALUE_NONE
--diffVALUE_OPTIONAL

Sources: app/Commands/CommitCommand.php132-190

Lifecycle Methods

CommitCommand uses two lifecycle hooks provided by Symfony Console:

  • initialize(InputInterface, OutputInterface) — Called before interact() and handle(). If --config is given, it calls configManager->replaceFrom($configFile) to layer in a custom config file, then re-applies commit_options, diff_options, generator, and prompt from the merged config onto the input options.

  • handle() — The main execution body. It chains a series of tap() calls on a Collection instance, where each tap performs one step: verify git repo, get cached diff, choose commit type, generate message, confirm with user, and finally run git commit.

  • complete(CompletionInput, CompletionSuggestions) — Provides shell completion values. For --generator, it suggests keys from configManager.generators; for --prompt, keys from configManager.prompts.

Sources: app/Commands/CommitCommand.php52-105 app/Commands/CommitCommand.php198-216 app/Commands/CommitCommand.php113-124

handle() Execution Chain


Sources: app/Commands/CommitCommand.php52-105


ConfigCommand

File: app/Commands/ConfigCommand.php
Signature: config

ConfigCommand manages reading and writing of configuration files. It acquires ConfigManager the same way as CommitCommand: via config('ai-commit').

Actions

The command defines a required action argument. Supported values are stored in the private constant ACTIONS:

ActionBehavior
setconfigManager->set($key, $value) then putFile()
getconfigManager->get($key) or full toJson() if no key
unsetconfigManager->forget($key) then putFile()
resetRe-reads config/ai-commit.php defaults, replaces one key or all, then putFile()
listIterates configManager->toDotArray() and prints each dot-notation key and value
editOpens the config file in a detected or specified editor via Symfony\Component\Process\Process

An unrecognized action throws UnsupportedConfigActionException.

Target File Resolution

The configFile() private method determines which config file the action applies to:

  1. If --file is provided, use that path.
  2. If --global is set, use ConfigManager::globalPath().
  3. Otherwise, default to ConfigManager::localPath() (the local .ai-commit.json).

Lifecycle

The initialize() method ensures the global config file exists before any action runs. If ConfigManager::globalPath() does not exist, it calls configManager->putGlobal() to create it.

Sources: app/Commands/ConfigCommand.php30-221


ThanksCommand

File: app/Commands/ThanksCommand.php
Signature: thanks

A minimal command. It prompts the user to star the GitHub repository and, on affirmative response, opens the URL using the platform-appropriate shell command (open, start, or xdg-open). It has no options or arguments beyond the standard ones inherited from the base class.

Sources: app/Commands/ThanksCommand.php18-44


Common Patterns Across Commands

ConfigManager acquisition

Both CommitCommand and ConfigCommand retrieve ConfigManager in their constructors using:


This relies on the ConfigManager singleton being bound to the 'ai-commit' config key by AppServiceProvider during boot (see 4.1).

configure() over $signature

Both CommitCommand and ConfigCommand override configure() and call $this->setDefinition(...) with InputArgument and InputOption objects. This pattern allows default values to be computed dynamically from ConfigManager at construction time, which is not possible with a static $signature string.

Shell completion

Both CommitCommand and ConfigCommand implement complete(CompletionInput $input, CompletionSuggestions $suggestions). This method is called by Symfony Console's completion mechanism and returns contextually appropriate values for option and argument completion.

Sources: app/Commands/CommitCommand.php113-124 app/Commands/ConfigCommand.php122-139 app/Commands/CommitCommand.php132-190 app/Commands/ConfigCommand.php152-162


Summary Table

Command classSignatureDefault?Key dependenciesKey outputs
CommitCommandcommitYesGeneratorManager, ConfigManagergit commit execution
ConfigCommandconfigNoConfigManagerConfig file read/write
ThanksCommandthanksNoNoneBrowser URL open

Sources: config/commands.php27 app/Commands/CommitCommand.php35 app/Commands/ConfigCommand.php37 app/Commands/ThanksCommand.php21