Skip to content
Back to skills

Add Cli Command

ASecurity

Use when a ticket adds or changes a command-line interface — a new subcommand, flag, or output format for the repo's CLI tool — and it must follow the CLI's existing conventions for arguments, exit codes, JSON output, help text, and tests. Invoke for "add a `foo bar` command", "add a --json flag", "the CLI should print X", or any change under a cli/ or bin/ entry point.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 28, 2026
ai-agentspythonrustgojavarubyshellbashnodeapibackend

Works with

  • terminal
  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add tmj-90/gaffer --skill add-cli-command --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Cli Command?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add Cli Command
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tmj-90-add-cli-command/badge)](https://www.skillsdirectory.com/skills/tmj-90-add-cli-command)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add-cli-command
description: Use when a ticket adds or changes a command-line interface — a new subcommand, flag, or output format for the repo's CLI tool — and it must follow the CLI's existing conventions for arguments, exit codes, JSON output, help text, and tests. Invoke for "add a `foo bar` command", "add a --json flag", "the CLI should print X", or any change under a cli/ or bin/ entry point.
stack: [node, python, go, rust, java, csharp, ruby, bash]
area: backend
---

# Add a CLI command

A CLI is an API whose consumers are humans at a terminal and scripts in a pipeline.
Scripts depend on the exit code, the stdout format and the flag names; humans depend on
the help text and error messages. Follow the tool's existing conventions first and the
Command Line Interface Guidelines (clig.dev) where the tool is silent.

## Steps

1. **Read a sibling command.** Find the entry point and command registry (Commander,
   yargs, Click, Typer, Cobra, clap, picocli, System.CommandLine) and copy an existing
   command's parsing, validation, output and exit handling. Call `search_lore` for the
   CLI's JSON envelope, error format and exit-code table.
2. **Design the surface and write `--help` first.** Match the tool's naming (`ticket
   create`, not `createTicket`). Positional arguments only for the one thing the command
   acts on; everything else is a long flag, with a short alias only where siblings use
   one. Reuse standard names: `-h/--help`, `--version`, `--json`, `-q/--quiet`,
   `-f/--force`, `-n/--dry-run`, `--no-input`, `--no-color`. Help leads with a usage
   line and one or two examples. If the help is hard to write, the surface is wrong.
3. **Validate before doing any work.** Parse and validate every argument, reject
   unknown flags, and fail with a one-line message naming the bad input and the fix.
   Exit codes: `0` success, non-zero on any failure, and the tool's usage-error code
   (commonly `2`) for bad arguments. Never exit 0 after printing an error.
4. **Separate output streams.** stdout carries the result only; errors, warnings,
   progress and logs go to stderr. `--json` prints exactly one JSON document (or the
   tool's documented NDJSON) on stdout and nothing else, including on failure if the
   envelope defines an error shape. Disable colour and spinners when stdout is not a
   TTY, when `NO_COLOR` is set, or with `--no-color`.
5. **Be safe to script.** Prompt only when stdin is a TTY and `--no-input` is absent;
   otherwise fail with the flag that supplies the answer. Destructive or remote-changing
   actions confirm interactively or require `--force`; offer `--dry-run` when siblings
   do. Make re-runs safe (idempotent where possible) and give network calls a timeout.
   On Ctrl-C, stop promptly and exit non-zero (130 by convention).
6. **Keep the command thin.** Parse, call the same service or core the API uses, render.
   Business logic in the handler cannot be reused or unit-tested without a process.
   If the command writes shared files or state that another invocation, the server or
   a worker may write concurrently, follow the `concurrency-and-async` skill (atomic
   temp-and-rename, a real lock).
7. **Handle configuration and secrets.** Read config through the repo's config spine
   (the `add-config-option` skill), never raw env reads, and honour the siblings' `--config`/`--db`
   overrides. Never accept a secret as a flag value (it lands in shell history and `ps`);
   read it from a file, stdin or the configured secret source. Never print secrets.
8. **Test at both levels.** Unit-test the core logic. Spawn the real binary for the
   contract, one test per AC that exercises the AC's own behaviour, and assert:
   - exit code for success, a usage error and an operational failure;
   - `--json` stdout parses as JSON with the documented shape, and stderr carries
     diagnostics without polluting stdout;
   - the error message for bad input; `--help` lists the new command or flag;
   - non-TTY behaviour: no prompt, no colour; a missing answer fails with a message
     naming the flag that supplies it.

   Update the CLI reference or usage block if the repo keeps one.
9. **Evidence** with the `record-evidence` skill: the test run, `--help` output, and a
   sample invocation with its exit code.

## Done when

- The new surface matches sibling naming, parser and envelope; help and docs updated.
- Every failure path exits non-zero; stdout under `--json` is pure JSON.
- Spawned-binary tests cover exit codes, output shape and error text for each AC.

## Anti-patterns

- `console.log` of progress to stdout; mixing a banner into JSON output.
- `process.exit(0)` in a catch block; swallowing an error and printing a warning.
- Interactive prompts that hang in CI; secrets passed as `--token=…`.
- Tests that only call the handler function and never the real binary.

## Capture lore

This skill is one of the places durable, reusable knowledge naturally surfaces:
**While matching the sibling commands you learn the CLI's envelope, exit-code and flag conventions — the contract scripts already depend on.** That kind of fact is *lore*. Capture it via the **lore-capture
protocol in your brief** (`CLAUDE.factory.md`, step 11 "Memory contribution"):
call the Memory MCP `suggest_lore` once at the close of your work — reusable
conventions, gotchas, decisions, and boundaries only, never per-ticket trivia.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…