# Adding A Command

Creates a new CLI command following the Commander.js pattern in src/commands/.

- Repository: https://github.com/caliber-ai-org/ai-setup (1310 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-09-24
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -g -a claude-code -y`
Codex: `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -g -a codex -y`
Cursor: `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -g -a cursor -y`
Gemini CLI: `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add caliber-ai-org/ai-setup`

## Description

Creates a new CLI command following the Commander.js pattern in src/commands/. Handles command registration in src/cli.ts, telemetry tracking via tracked() wrapper, and option parsing. Use when user says add command, new CLI command, create subcommand, or adds files to src/commands/. Do NOT use for modifying existing commands or fixing bugs in existing commands.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Adding a Command

## Critical

- **Export pattern**: Command must export a named async function: `export async function myCommand(options?: OptionType)`. Never use default exports.
- **Registration in cli.ts**: Every command must be imported and registered with `.command()` chain in `src/cli.ts`, wrapped with `tracked()` for telemetry.
- **Error signaling**: Use `throw new Error('__exit__')` to exit gracefully without printing the error message. Use chalk for user-facing messages.
- **Options typing**: Commands receiving options must define a TypeScript interface for those options. Pass options as a destructured object parameter.

## Instructions

1. **Create the command file** at `src/commands/{commandName}.ts` with named async export.
   - Signature: `export async function {commandName}Command(options?: { optionName?: optionType }) { ... }`
   - Import only what you need (avoid kitchen-sink imports).
   - Return void (handle all output via console.log or chalk).
   - Verify the file follows the naming convention: camelCase function + "Command" suffix.

2. **Handle errors consistently**: Wrap error-prone operations in try/catch. Distinguish between user errors and system errors:
   - User error (bad input): `console.error(chalk.red('message')); throw new Error('__exit__');`
   - System error (missing dependency): `throw new Error('Detailed error message');`, this will print and exit with code 1.
   - Parse-like errors: Use ora spinner with `.fail()` before throwing.
   - This step prevents double error printing in bin.ts.

The rest: https://github.com/caliber-ai-org/ai-setup/blob/HEAD/.agents/skills/adding-a-command/SKILL.md
