home / skills / outfitter-dev / agents / cli-development-guidelines

cli-development-guidelines skill

/plugins/cli-dev/skills/cli-development-guidelines

This skill helps you design and audit robust CLI tools with proper IO, exit codes, and user-friendly help.

npx playbooks add skill outfitter-dev/agents --skill cli-development-guidelines

Review the files below or copy the command above to add this skill to your agents.

Files (9)
SKILL.md
3.6 KB
---
name: cli-development-guidelines
description: This skill should be used when designing, implementing, or reviewing CLI tools, or when flags, subcommands, help text, exit codes, or `--cli-dev` are mentioned.
license: CC-BY-SA-4.0 (docs, adapted from clig.dev); MIT (scripts)
compatibility: Scripts use Python 3.10+ (scripts/cli_audit.py).
metadata:
  version: "0.1.0"
  upstream: "clig.dev + POSIX/GNU/Heroku/12-factor + Agent Skills spec"
---
# CLI Development Guidelines

## When to activate this skill

- You are *designing*, *implementing*, or *reviewing* a command-line tool.
- The user mentions (explicitly or implicitly): `--help`, flags, subcommands, exit codes, stdout/stderr, piping, JSON output, color, prompts, config files, env vars, “works in CI”, install/uninstall, telemetry.

## What this skill produces

- A *CLI contract* (what users can rely on): commands, flags, IO behavior, exit codes, config/env, examples, and safety behavior.
- Draft *help output* and docs structure (example-first).
- A *compliance audit* (when runnable) using `scripts/cli_audit.py`.

## Non-negotiable CLI citizenship

- Exit codes:
  - `0` on success.
  - Non-zero on failure (and ideally meaningful, documented codes).
- Streams:
  - `stdout` is for primary output and machine-readable output.
  - `stderr` is for errors, warnings, progress, and “what I’m doing” messaging.
- Discoverability:
  - `--help` (and usually `-h`) shows help and exits.
  - `--version` prints version and exits.
- Interactivity:
  - Prompts only when `stdin` is a TTY.
  - Provide `--no-input` to force non-interactive behavior.
- Scripting friendliness:
  - No ANSI color / spinners when output isn’t a TTY.
  - Support `NO_COLOR` and `--no-color`.
  - Consider `--json` and `--plain` for stable output.

## Workflow

### Sketch the CLI contract first

- Start from the user’s jobs-to-be-done (what they’re trying to accomplish).
- Decide:
  - Command shape: single command vs subcommands (`noun verb` is common).
  - Inputs: args vs flags vs stdin vs prompts vs config/env.
  - Outputs: human default, plus machine modes (`--json`, `--plain`, `--quiet`).
  - Safety: confirmations, `--dry-run`, `--force`, secret handling.

Use:
- [CLI reference](references/REFERENCE.md)
- [CLI spec template](templates/cli-command-spec-template.json)

### Implement with safe defaults

- Use a CLI parsing library (don’t hand-roll).
- Make “boundary-crossing” actions explicit:
  - Network calls
  - Writing files not explicitly provided
  - Mutating remote state
- Avoid footguns:
  - Don’t accept secrets via flags or environment variables.
  - Don’t print stack traces by default.
  - Don’t assume TTY (detect it).

### Validate and iterate

- Run an automated sanity check (when possible):
  - `python scripts/cli_audit.py -- <your-cli> [subcommand]`
- Fix in this order:
  - Broken stdout/stderr separation
  - Incorrect exit codes
  - Help that’s missing or undiscoverable
  - Unsafe defaults (destructive ops, secrets, hidden network writes)
  - Unscriptable output (no stable modes)

Use:
- [Checklist](references/CHECKLIST.md)
- `scripts/cli_audit.py`

## Reference library

- Core reference: [references/REFERENCE.md](references/REFERENCE.md)
- Quick audit checklist: [references/CHECKLIST.md](references/CHECKLIST.md)
- Evaluation prompts: [references/EVAL_PROMPTS.md](references/EVAL_PROMPTS.md)

## Templates and scripts

- CLI spec template: `templates/cli-command-spec-template.json`
- Help text template: `templates/help-text-template.md`
- Error message template: `templates/error-message-template.md`
- Audit a CLI: `scripts/cli_audit.py`

Overview

This skill helps design, implement, and review command-line interfaces (CLIs) to be predictable, scriptable, and safe. It encapsulates a CLI contract, example-first help text, and a runnable compliance audit to catch common pitfalls. Use it whenever flags, subcommands, help, exit codes, or non-interactive behavior are in scope.

How this skill works

The skill inspects the intended user jobs-to-be-done and produces a concrete CLI contract listing commands, flags, I/O behavior, exit codes, and safety controls. It drafts help output and documentation structure with examples-first guidance. When the CLI is runnable, it runs an automated compliance audit (scripts/cli_audit.py) and reports fixes prioritized by impact.

When to use it

  • Designing a new CLI or refactoring command shapes and flags
  • Implementing help text, exit codes, or machine-readable output modes
  • Reviewing a CLI for scripting friendliness, TTY behavior, or safety defaults
  • Adding or auditing JSON/plain output, color controls, or --no-input behavior
  • Preparing a CLI for CI use, piping, or automated audits

Best practices

  • Sketch a CLI contract first: commands, inputs, outputs, exit codes, and safety behavior
  • Always separate stdout (primary/machine output) from stderr (errors, progress, logs)
  • Make destructive or boundary-crossing actions explicit and opt-in (confirmations, --dry-run, --force)
  • Detect TTY and disable colors/spinners when not TTY; honor NO_COLOR and provide --no-color
  • Provide stable machine modes like --json and --plain and a --no-input for CI

Example use cases

  • Generate a CLI contract for a new tool including flags, env, examples, and documented exit codes
  • Draft help and man-style examples-first documentation from a command spec
  • Run the automated CLI audit to find stdout/stderr mixups, missing help or wrong exit codes
  • Evaluate an existing CLI for CI readiness: non-interactive flags, NO_COLOR behavior, and --json output
  • Implement safe defaults: avoid secrets as flags, suppress stack traces by default

FAQ

What exit codes should my CLI use?

Return 0 on success and non-zero on failure; document meaningful non-zero codes where helpful.

When should I prompt the user?

Only prompt when stdin is a TTY. Provide a --no-input option to force non-interactive behavior for CI and scripts.