Agent skill

Adding A Command

by caliber-ai-org in caliber-ai-org/ai-setup

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

MITAuto-check passed

Install Adding A Command

skills CLI
$ npx skills add caliber-ai-org/ai-setup --skill adding-a-command -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install caliber-ai-org/ai-setup adding-a-command --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/adding-a-command .claude/skills/adding-a-command && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
adding-a-command
GitHub stars
1.3k
Token cost
~2k tokens
SKILL.md length
671 words
Files
1
Skills in repo
8
Repo updated
First seen
Licence
MIT

At a glance

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

  • Works in 5 steps: Create the command file at… → Handle errors consistently: Wrap… → Import and register in src/cli.ts in the… → …
  • User says add command
  • SKILL.md covers Critical, Instructions, Examples and Common Issues
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Adding A Command is an agent skill from caliber-ai-org/ai-setup. 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.

Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The repository describes itself as: Continuously sync your AI setups with one command. Codebase tailor suited agent skills, MCPs and config files for Claude Code, Cursor, and Codex. The licence is MIT.

When your agent uses it

  • User says add command
  • New CLI command
  • Create subcommand
  • Adds files to src/commands/

Example prompts

  • “Use the adding-a-command skill to create a new CLI command following the Commander.js pattern in src/commands/”
  • “/adding-a-command”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Create the command file at src/commands/{commandName}.ts with named async export.
  2. Handle errors consistently: Wrap error-prone operations in try/catch. Distinguish between user errors and system errors
  3. Import and register in src/cli.ts in the correct location
  4. Define options (if needed)
  5. Verify before proceeding

What it can do on your machine

Read from SKILL.md and the folder at commit f5dbc00. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Adding A Command loads about 2k tokens when it runs. Until then it costs about 95 tokens; SKILL.md has 671 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~95
When it runs · the whole SKILL.md, loaded when a task matches
~2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from caliber-ai-org/ai-setup at commit f5dbc00, republished under its MIT licence (© caliber-ai-org). 671 words, ~1,978 tokens.

Download SKILL.mdSave it as .claude/skills/adding-a-command/SKILL.md (or your agent's skills folder).
name
adding-a-command
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.
paths
src/commands/**/*.ts, src/cli.ts

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.
  3. Import and register in src/cli.ts in the correct location:

    • Add import at the top: import { {commandName}Command } from './commands/{commandName}.js';
    • Register the command in the appropriate section (main commands, or nested under a group like sources).
    • For main commands: .command('{kebab-name}').description('...').option(...).action(tracked('{kebab-name}', {commandName}Command))
    • For subcommands (like sources add): sources.command('add').description(...).action(tracked('sources:add', sourcesAddCommand))
    • Key: Wrap handler with tracked('{command-name}', handler) for automatic telemetry.
    • Verify the command name in tracked() uses kebab-case for main commands and colon-separated for subcommands.
  4. Define options (if needed):

    • Add .option() chains before .action(): .option('--flag', 'Description') or .option('--opt <value>', 'Description')
    • For parsed options (like comma-separated agents), add a parse function: .option('--opt <value>', 'Description', parseFunction)
    • Pass options to handler: .action(tracked('name', (opts) => command(opts)))
    • Define TypeScript interface for the options object.
    • Verify option names use camelCase (Commander converts kebab-case flags to camelCase).
  5. Verify before proceeding:

    • Function exports correctly and is imported in cli.ts.
    • Command is registered with tracked() wrapper.
    • Output uses chalk for colors, not plain console.log.
    • Error paths throw new Error('__exit__') for user errors.

Examples

Example 1: Simple command (status)

User says: "Add a command to show config status"

Actions taken:

  1. Create src/commands/status.ts with statusCommand() export
  2. Import and register in src/cli.ts with tracked() wrapper

Result: caliber status displays config status; caliber status --json outputs JSON.

Code example:

typescript
import chalk from 'chalk';
import { loadConfig } from '../llm/config.js';

export async function statusCommand(options?: { json?: boolean }) {
  const config = loadConfig();
  
  if (options?.json) {
    console.log(JSON.stringify({ configured: !!config }, null, 2));
    return;
  }
  
  console.log(chalk.bold('Status'));
  console.log(`  LLM: ${chalk.green(config?.provider || 'Not configured')}`);
}

Registration in src/cli.ts:

typescript
import { statusCommand } from './commands/status.js';
program
  .command('status')
  .description('Show config status')
  .option('--json', 'Output as JSON')
  .action(tracked('status', statusCommand));

Show full SKILL.md (277 more words)Show less
Example 2: Subcommand with arguments

User says: "Add a sources add subcommand"

Actions taken:

  1. Create src/commands/sources.ts with sourcesAddCommand() export
  2. Register under sources group with tracked('sources:add', ...)

Result: caliber sources add ../lib adds a source.

Code example:

typescript
export async function sourcesAddCommand(sourcePath: string) {
  if (!fs.existsSync(sourcePath)) {
    console.log(chalk.red(`Path not found: ${sourcePath}`));
    throw new Error('__exit__');
  }
  const existing = loadSourcesConfig(process.cwd());
  existing.push({ type: 'repo', path: sourcePath });
  writeSourcesConfig(process.cwd(), existing);
  console.log(chalk.green(`Added ${sourcePath}`));
}

Registration:

typescript
const sources = program.command('sources');
sources
  .command('add')
  .argument('<path>', 'Path to add')
  .action(tracked('sources:add', sourcesAddCommand));

Example 3: Command with option parsing

User says: "Add init with --agent flag supporting comma-separated values"

Actions taken:

  1. Create parseAgentOption() parser in src/cli.ts
  2. Create src/commands/init.ts with initCommand(options)
  3. Register with custom parser

Result: caliber init --agent claude,cursor passes parsed array to handler.

Parser code:

typescript
function parseAgentOption(value: string) {
  const agents = value.split(',').map(s => s.trim().toLowerCase());
  if (agents.length === 0) {
    console.error('Invalid agent');
    process.exit(1);
  }
  return agents;
}

program.command('init')
  .option('--agent <type>', 'Agents (comma-separated)', parseAgentOption)
  .action(tracked('init', initCommand));

Common Issues

Issue: "SyntaxError: The requested module does not provide an export named 'myCommand'"

  • Cause: Function not exported or exported as default instead of named.
  • Fix: Use export async function myCommand(...) (not export default).

Issue: Command appears in help but crashes when run

  • Cause: Handler not wrapped with tracked() or function import mismatch.
  • Fix: Verify import name matches function export. Wrap with tracked('command-name', handler).

Issue: "Error: exit" appears in output for user errors

  • Cause: Throwing generic error instead of using error exit pattern.
  • Fix: Use console.error(chalk.red('message')); throw new Error('__exit__'); for user-facing errors.

Issue: --dry-run flag not recognized

  • Cause: Option not declared with .option() or wrong camelCase in interface.
  • Fix: Add .option('--dry-run', 'Description') and ensure options interface has dryRun?: boolean.

Issue: Subcommand crashes but parent command works

  • Cause: Using program.command() instead of groupVar.command() for subcommands.
  • Fix: Register on group: const sources = program.command('sources'); sources.command('add')...

Issue: Telemetry not appearing

  • Cause: Handler not wrapped with tracked() or wrong command name.
  • Fix: Ensure .action(tracked('{kebab-case}', handler)) wraps handler. Use colon for subcommands like 'sources:add'.

Issue: "Cannot find module" with relative imports

  • Cause: Using .ts extension in imports.
  • Fix: Always use .js extension: import { x } from '../lib/file.js' (required for ESM).

© caliber-ai-org, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/adding-a-command of caliber-ai-org/ai-setup.

Open the folder on GitHubat commit f5dbc00

Compare with similar skills

Adding A Command next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Adding A Command compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Adding A Command this skillcaliber-ai-org/ai-setup1.3k—~2kAutomated safety check: PassMIT
Golang Patternsaffaan-m/ECC276k—~1.1kAutomated safety check: PassMIT
Kotlin Exposed Patternsaffaan-m/ECC276k4 repos~5.5kAutomated safety check: PassMIT
Dotnet Patternsaffaan-m/ECC276k1 repos~2.3kAutomated safety check: PassMIT
Fastapi Patternsaffaan-m/ECC276k—~2.3kAutomated safety check: PassMIT
Python Patternsaffaan-m/ECC276k—~2.3kAutomated safety check: PassMIT

Similar skills

  • Golang Patterns

    affaan-m/ECC

    Go-specific design patterns and best practices including functional options, small interfaces, dependency injection, concurrency patterns, error handling, and package organization.

    276k GitHub stars~1.1k tokensUpdated 4 days ago
    DevelopmentAuto-check passed
  • JetBrains Exposed ORM patterns including DSL queries, DAO pattern, transactions, HikariCP connection pooling, Flyway migrations, and repository pattern.

    276k GitHub starsUsed in 4 repos~5.5k tokens
    DatabasesAuto-check passed
  • Dotnet Patterns

    affaan-m/ECC

    Idiomatic C and .NET patterns, conventions, dependency injection, async/await, and best practices for building robust, maintainable .NET applications.

    276k GitHub starsUsed in 1 repo~2.3k tokens
    DevelopmentAuto-check passed
  • Fastapi Patterns

    affaan-m/ECC

    FastAPI patterns for async APIs, dependency injection, Pydantic request and response models, OpenAPI docs, tests, security, and production readiness.

    276k GitHub stars~2.3k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed
  • Python Patterns

    affaan-m/ECC

    Python-specific design patterns and best practices including protocols, dataclasses, context managers, decorators, async/await, type hints, and package organization.

    276k GitHub stars~2.3k tokensUpdated 4 days ago
    DevelopmentAuto-check passed
  • Patterns

    sickn33/agentic-awesome-skills

    Reference document for monopoly patterns. An agent skill from sickn33/agentic-awesome-skills.

    47k GitHub starsUsed in 1 repo~2.6k tokens
    Backend & APIsAuto-check passed

More from caliber-ai-org/ai-setup

All 8 skills in this repo
  • Caliber Testing

    caliber-ai-org/ai-setup

    Writes Vitest tests following project patterns: tests/ directories, vi.mock() for module mocking with vi.hoisted() for test-time factories, global LLM mock from src/test/setup.ts, environment…

    1.3k GitHub stars~3.2k tokensUpdated 15 days ago
    Auto-check passed
  • Find Skills

    caliber-ai-org/ai-setup

    Discovers and installs community skills from the public registry.

    1.3k GitHub stars~593 tokensUpdated 15 days ago
    Auto-check passed
  • LLM Provider

    caliber-ai-org/ai-setup

    Adds a new LLM provider implementing LLMProvider interface with call() and stream() methods.

    1.3k GitHub stars~2.7k tokensUpdated 15 days ago
    Auto-check passed
  • Save Learning

    caliber-ai-org/ai-setup

    Saves user instructions as persistent learnings for future sessions.

    1.3k GitHub stars~626 tokensUpdated 15 days ago
    Auto-check passed
  • Scoring Checks

    caliber-ai-org/ai-setup

    Add a new deterministic scoring check in src/scoring/checks/ that evaluates config quality.

    1.3k GitHub stars~3k tokensUpdated 15 days ago
    Auto-check passed
  • Setup Caliber

    caliber-ai-org/ai-setup

    Sets up Caliber for automatic AI agent context sync. An agent skill from caliber-ai-org/ai-setup.

    1.3k GitHub stars~1.9k tokensUpdated 15 days ago
    Auto-check passed

Questions about Adding A Command

What does Adding A Command do?

Creates a new CLI command following the Commander.js pattern in src/commands/. Adding A Command is an agent skill from caliber-ai-org/ai-setup.js pattern in src/commands/.

When should I use Adding A Command?

Adding A Command fits situations like: user says add command; new CLI command; create subcommand; adds files to src/commands/.

How do I install Adding A Command in Claude Code?

Run `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -a claude-code`. Or copy the skill folder (skills/adding-a-command in caliber-ai-org/ai-setup) into .claude/skills/adding-a-command in your project. Claude Code loads it when a task matches its description.

How do I install Adding A Command in Codex?

Run `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -a codex`. Or copy the skill folder (skills/adding-a-command in caliber-ai-org/ai-setup) into .agents/skills/adding-a-command in your project. Codex loads it when a task matches its description.

Can I use Adding A Command in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add caliber-ai-org/ai-setup --skill adding-a-command -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/adding-a-command, .gemini/skills/adding-a-command, .github/skills/adding-a-command and .opencode/skills/adding-a-command in your project.

What does Adding A Command need to run?

SKILL.md names no scripts, command-line tools or credentials: Adding A Command is instructions for the agent only.

Does Adding A Command access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Adding A Command safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Adding A Command use?

Adding A Command is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Adding A Command use?

About 2k tokens (SKILL.md is roughly 7.9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Adding A Command?

Skills that share tags, products or a category with Adding A Command: Golang Patterns (affaan-m/ECC, 276k stars), Kotlin Exposed Patterns (affaan-m/ECC, 276k stars), Dotnet Patterns (affaan-m/ECC, 276k stars) and Fastapi Patterns (affaan-m/ECC, 276k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Adding A Command?

caliber-ai-org (a GitHub organization) maintains it in caliber-ai-org/ai-setup, which has 1,301 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 24, 2026.

Source: caliber-ai-org/ai-setup on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.