or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-management.mdcommand-system.mdhelp-system.mdindex.mdoption-system.md
tile.json

command-system.mddocs/

Command System

Define commands with arguments, options, and actions. Supports subcommands, aliases, and flexible argument patterns.

Capabilities

Command Creation

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
});

Argument Patterns

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));
  });

Command Methods

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");

Command Actions

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!");
  });

Default Commands

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
  });

Command Properties

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;
}

Command Validation Methods

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;

Command Execution Flow

  1. Parsing: CAC parses argv to identify matching command
  2. Validation: Checks required arguments and unknown options
  3. Action Execution: Calls command action with parsed arguments
  4. Error Handling: Throws CACError for validation failures
// Error handling example
try {
  cli.parse();
} catch (error) {
  if (error instanceof CACError) {
    console.error(`Command error: ${error.message}`);
  }
  process.exit(1);
}