Define commands with arguments, options, and actions. Supports subcommands, aliases, and flexible argument patterns.
Add commands to the CLI with flexible argument patterns and configuration.
/**
* Add a command to the CLI
* @param rawName - Command name with arguments like 'build <entry> [output] [...files]'
* @param description - Command description for help
* @param config - Optional command configuration
* @returns Command instance for method chaining
*/
command(rawName: string, description?: string, config?: CommandConfig): Command;
interface CommandConfig {
/** Allow unknown options in this command */
allowUnknownOptions?: boolean;
/** Don't use option default values in parsed options */
ignoreOptionDefaultValue?: boolean;
}Usage Examples:
// Basic command
cli.command("build", "Build the project");
// Command with required argument
cli.command("deploy <environment>", "Deploy to environment");
// Command with optional argument
cli.command("serve [port]", "Start development server");
// Command with variadic arguments
cli.command("lint [...files]", "Lint files");
// Complex command with mixed arguments
cli.command("build <entry> [output] [...assets]", "Build with assets");
// Command with configuration
cli.command("dev", "Development mode", {
allowUnknownOptions: true,
ignoreOptionDefaultValue: true
});CAC supports various argument patterns using bracket notation.
/**
* Argument patterns in command names:
* - <arg>: Required argument
* - [arg]: Optional argument
* - [...args]: Variadic argument (must be last)
* - Multiple patterns can be combined
*/Examples:
// Required arguments
cli.command("copy <source> <destination>", "Copy files")
.action((source, dest, options) => {
// source and dest are guaranteed to be present
});
// Optional arguments
cli.command("serve [port]", "Start server")
.action((port, options) => {
// port may be undefined
const actualPort = port || 3000;
});
// Variadic arguments
cli.command("delete [...files]", "Delete files")
.action((files, options) => {
// files is an array of all remaining arguments
files.forEach(file => fs.unlinkSync(file));
});Methods available on Command instances for configuration and behavior.
/**
* Set custom usage text for the command
* @param text - Usage text
* @returns Command instance for chaining
*/
usage(text: string): Command;
/**
* Allow unknown options for this command
* @returns Command instance for chaining
*/
allowUnknownOptions(): Command;
/**
* Ignore default values for options in this command
* @returns Command instance for chaining
*/
ignoreOptionDefaultValue(): Command;
/**
* Set version for this command
* @param version - Version string
* @param customFlags - Custom version flags
* @returns Command instance for chaining
*/
version(version: string, customFlags?: string): Command;
/**
* Add an example for this command
* @param example - Example string or function
* @returns Command instance for chaining
*/
example(example: CommandExample): Command;
/**
* Add command alias
* @param name - Alias name (cannot contain brackets)
* @returns Command instance for chaining
*/
alias(name: string): Command;Usage Examples:
cli
.command("build <entry>", "Build application")
.usage("build <entry> [options]")
.alias("compile")
.allowUnknownOptions()
.example("build src/app.js --minify")
.version("2.1.0");Define the behavior when a command is executed.
/**
* Set the action callback for when command is matched
* @param callback - Action function receiving parsed arguments and options
* @returns Command instance for chaining
*/
action(callback: ActionCallback): Command;
type ActionCallback = (
...args: (string | string[] | number | number[])[]
) => any;
/**
* Action callback receives:
* - Individual arguments based on command pattern
* - Final argument is always the options object
* - Variadic arguments are passed as arrays
*/Usage Examples:
// Simple action
cli
.command("hello <name>", "Say hello")
.action((name, options) => {
console.log(`Hello ${name}!`);
});
// Action with multiple arguments
cli
.command("copy <src> <dest>", "Copy file")
.action((src, dest, options) => {
if (options.verbose) {
console.log(`Copying ${src} to ${dest}`);
}
// Copy logic here
});
// Action with variadic arguments
cli
.command("process [...files]", "Process files")
.action((files, options) => {
// files is an array
files.forEach(file => {
console.log(`Processing ${file}`);
});
});
// Async actions are supported
cli
.command("deploy <env>", "Deploy application")
.action(async (env, options) => {
console.log(`Deploying to ${env}...`);
await deployTo(env);
console.log("Deployment complete!");
});Create commands that run when no specific command is matched.
/**
* Create a default command by omitting the command name
* Use brackets to define arguments for the default command
*/Usage Examples:
// Default command with arguments
cli
.command("[...files]", "Process files")
.action((files, options) => {
if (files.length === 0) {
console.log("No files specified");
return;
}
// Process files
});
// Default command with options only
cli
.command("", "Default behavior")
.option("--config <file>", "Config file")
.action((options) => {
// Default behavior
});Access command state and metadata.
interface Command {
/** Command options array */
readonly options: Option[];
/** Command alias names */
readonly aliasNames: string[];
/** Parsed command name (without brackets) */
readonly name: string;
/** Parsed command arguments with metadata */
readonly args: CommandArg[];
/** Command action callback */
readonly commandAction?: ActionCallback;
/** Custom usage text */
readonly usageText?: string;
/** Command version */
readonly versionNumber?: string;
/** Command examples */
readonly examples: CommandExample[];
/** Reference to CLI instance */
readonly cli: CAC;
/** Check if this is the default command */
readonly isDefaultCommand: boolean;
/** Check if this is the global command */
readonly isGlobalCommand: boolean;
}
interface CommandArg {
required: boolean;
value: string;
variadic: boolean;
}Methods for runtime validation and checking.
/**
* Check if a command name matches this command
* @param name - Command name to test
* @returns True if name matches command or aliases
*/
isMatched(name: string): boolean;
/**
* Check if an option is registered in this command
* @param name - Option name to check
* @returns Option instance if found, undefined otherwise
*/
hasOption(name: string): Option | undefined;
/**
* Check if the parsed arguments meet required argument count
* Throws CACError if insufficient required arguments provided
*/
checkRequiredArgs(): void;
/**
* Check if the parsed options contain any unknown options
* Throws CACError for unknown options (unless allowUnknownOptions is true)
*/
checkUnknownOptions(): void;
/**
* Check if required string-type options have values
* Throws CACError for missing required option values
*/
checkOptionValue(): void;
/**
* Output help message for this command
*/
outputHelp(): void;
/**
* Output version for this command
*/
outputVersion(): void;// Error handling example
try {
cli.parse();
} catch (error) {
if (error instanceof CACError) {
console.error(`Command error: ${error.message}`);
}
process.exit(1);
}