cli-design
Design a CLI interface: args, flags, help, output, errors, exit codes, config.
Install
npx skills add https://github.com/notque/vexjoy-agent/tree/main/skills/engineering/cli-design
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install notque-vexjoy-agent@llmmart
git clone https://github.com/notque/vexjoy-agent.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole notque/vexjoy-agent collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
CLI Design
Design a command-line tool's interface before implementation: human-first, script-friendly, Linux-only. Output is a compact spec the user or an agent can implement directly. Rubric source: clig.dev (rebuilt as references/clig-checklist.md).
Deep References
| When | Load | Content |
|---|---|---|
| Phase 2: applying design rubric | references/clig-checklist.md |
CLI design checklist condensed from clig.dev |
Workflow
Phase 1: SCOPE
Lock the interface with the minimum questions. Proceed with the conventions in Phase 2 when the user is unsure.
- Command name and one-sentence purpose.
- Primary user: humans, scripts, or both.
- Input sources: args vs stdin; files vs URLs. Secrets travel via file or stdin, because flags leak through
psand shell history. - Output contract: human text,
--json,--plain, exit codes. - Interactivity: prompts allowed?
--no-inputneeded? confirmation for destructive ops? - Config model: flags, env, config file; precedence.
Gate: name, purpose, and I/O contract are known. Proceed only when gate passes.
Phase 2: DESIGN
Load references/clig-checklist.md and apply it as the default rubric. For each section, pick the convention and record it in the spec. Diverge from a convention only deliberately, and document the divergence in the spec — interfaces are contracts, and surprising contracts break scripts.
Phase 3: DELIVER
Produce the spec from this skeleton. Drop a section only when it genuinely has no content; fill every other section.
- Name and one-liner: command name plus a single sentence of purpose
- Usage line: the synopsis as
--helpwill print it, global flags and subcommand slot included - Subcommands: purpose of each, whether it mutates state, whether re-running it is safe
- Args/flags table: columns for name, type, default, required?, example
- I/O contract: primary data and machine-readable output on stdout; everything else (errors, progress, logs) on stderr
- Exit codes: map each failure mode to a code — success
0, failure1, bad usage2; mint extra codes only for cases scripts must distinguish - Safety:
--dry-run, confirmation rules,--force,--no-input - Env/config: env vars; config file path; precedence order with flags highest, then env, project config, user config, system
- Examples: enough invocations to cover the common flows; show at least one pipeline or stdin use
Gate: every flag used in the examples appears in the flags table, and every failure mode shown maps to an exit code.
Constraints
- Stay at spec altitude: when the request is "design the interface," deliver the spec and stop. Implementation is a separate task.
- Keep the spec language-agnostic. Recommend a parsing library only when asked.
- Target Linux. Skip Windows/macOS path, signal, and packaging concerns.
Error handling
Request mixes design and implementation
Cause: user says "design and build." Solution: deliver the spec first, get confirmation, then implement against it.
Spec balloons past one page
Cause: subcommand sprawl or speculative flags. Solution: cut flags that lack a named user need; defaults should serve most users without aliases.
Files (vexjoy-agent)
-
references
-
clig-checklist.md 4.6 KB
# CLI Design Checklist Condensed from the Command Line Interface Guidelines (https://clig.dev/, CC BY-SA). Rebuilt for this toolkit: Linux-only, spec-focused. Apply each section while filling the spec skeleton in SKILL.md. ## Philosophy - Human-first: optimize default output for humans; keep scripts working via stable modes (`--json`, `--plain`, exit codes). - Composability: assume your output becomes someone else's input. Respect stdio, exit codes, signals. - Consistency: reuse standard flag names and conventions; break a convention only deliberately and document why. - Say just enough: make progress visible, keep success output brief. - Conversation: design for trial-and-error loops — previews, dry runs, recoverable errors, suggested next commands. ## Basics - Use a real argument-parsing library (built-in or reputable), because hand-rolled parsers drift from conventions. - Exit `0` on success, non-zero on failure; map the few failure modes callers branch on. - Primary output to stdout; messages, logs, and errors to stderr. ## Help - Support `-h` and `--help`; help ignores other args. - On missing required args: concise usage + 1–2 examples + pointer to `--help`. - Subcommand CLIs: support `mycmd help sub` and `mycmd sub --help`. - Lead help with examples; list common flags first. ## Output - Detect TTY: human formatting when interactive, plain when piped. - Offer `--plain` (stable line-based) and/or `--json` for parsing. - On state change, say what changed and the new state. - `-q/--quiet` trims success output when scripts want silence. - Color: use sparingly; disable when stdout is not a TTY, `NO_COLOR` is set, `TERM=dumb`, or `--no-color` given. - Animations and progress bars only when stdout is a TTY. ## Errors - Catch expected errors and rewrite for humans; reserve stack traces for `--debug`, because traces scare users and bury the fix. - Keep signal-to-noise high; group repeated errors; put the most important line last. - On unexpected crash: point to debug log location and bug-report path. ## Arguments and flags - Prefer flags over positional args; positionals only for one obvious repeated item (`rm a b c`). - Every flag has a long form; reserve one-letter forms for the most common. - Standard names: | Flag | Meaning | |---|---| | `-h, --help` | help | | `--version` | version to stdout | | `-q, --quiet` | less output | | `-v, --verbose` | more output (`-v` means verbose, version stays long-form) | | `-d, --debug` | debug output | | `-f, --force` | skip confirmation | | `-n, --dry-run` | preview only | | `--json` | structured output | | `-o, --output <file>` | output path | | `--no-input` | disable prompts | - Support `-` for stdin/stdout where input/output is a file. - Secrets travel via `--secret-file` or stdin, because flag values leak through `ps` and shell history. - Defaults serve most users without aliases. ## Interactivity - Prompt only when stdin is a TTY. - `--no-input`: prompts off; missing required input fails with an actionable message. - Password prompts disable echo. - Destructive ops: interactive confirmation; non-interactive requires `--force`. ## Subcommands - Use subcommands when complexity demands; share global flags, config, and help. - Pick noun-verb or verb-noun and stay consistent. - Keep pairs sharply distinct (`update` vs `upgrade`); reject ambiguous abbreviations, because accepted abbreviations become contracts. ## Robustness - Validate early; fail fast with a clear message. - Print something within 100ms, especially before network I/O. - Timeouts on network calls, configurable. - Make reruns safe: idempotent where possible, crash-only recovery where feasible. - Ctrl-C exits fast with bounded cleanup; a second Ctrl-C may force, and says so. ## Configuration and environment - Per-invocation: flags. Per-user: env or XDG config file. Per-project: checked-in config file. - Precedence (high → low): flags > env > project config > user config > system config. - Env var names: uppercase, digits, underscores. Respect `NO_COLOR`, `DEBUG`, `EDITOR`, `PAGER`, `TERM`, `TMPDIR`, `HOME`. - Modify other programs' config only with consent; prefer adding new files over editing existing ones. ## Future-proofing - Args, flags, subcommands, config, env vars, and output modes are contracts. Keep changes additive; deprecate loudly and early with a migration path. - Let human output evolve; keep `--plain`/`--json` stable for scripts. ## Naming and distribution - Name: short, lowercase, memorable, easy to type, low collision risk. - Prefer a single binary or a self-contained script; make uninstall easy. - Telemetry only with explicit opt-in consent, stating what, why, and retention.
-
-
SKILL.md 3.7 KB
--- name: cli-design description: "Design a CLI interface: args, flags, help, output, errors, exit codes, config." user_invocable: false # default -- router-dispatched, not user-typed allowed-tools: - Read - Write - Grep - Glob - Bash routing: triggers: - "design a CLI" - "CLI interface" - "command line tool design" - "CLI flags" - "CLI spec" - "argument parsing design" - "exit codes" category: engineering pairs_with: - testing - code-quality --- # CLI Design Design a command-line tool's interface before implementation: human-first, script-friendly, Linux-only. Output is a compact spec the user or an agent can implement directly. Rubric source: clig.dev (rebuilt as `references/clig-checklist.md`). ## Deep References | When | Load | Content | |---|---|---| | Phase 2: applying design rubric | `references/clig-checklist.md` | CLI design checklist condensed from clig.dev | ## Workflow ### Phase 1: SCOPE Lock the interface with the minimum questions. Proceed with the conventions in Phase 2 when the user is unsure. - Command name and one-sentence purpose. - Primary user: humans, scripts, or both. - Input sources: args vs stdin; files vs URLs. Secrets travel via file or stdin, because flags leak through `ps` and shell history. - Output contract: human text, `--json`, `--plain`, exit codes. - Interactivity: prompts allowed? `--no-input` needed? confirmation for destructive ops? - Config model: flags, env, config file; precedence. **Gate:** name, purpose, and I/O contract are known. Proceed only when gate passes. ### Phase 2: DESIGN Load [references/clig-checklist.md](references/clig-checklist.md) and apply it as the default rubric. For each section, pick the convention and record it in the spec. Diverge from a convention only deliberately, and document the divergence in the spec — interfaces are contracts, and surprising contracts break scripts. ### Phase 3: DELIVER Produce the spec from this skeleton. Drop a section only when it genuinely has no content; fill every other section. 1. **Name and one-liner**: command name plus a single sentence of purpose 2. **Usage line**: the synopsis as `--help` will print it, global flags and subcommand slot included 3. **Subcommands**: purpose of each, whether it mutates state, whether re-running it is safe 4. **Args/flags table**: columns for name, type, default, required?, example 5. **I/O contract**: primary data and machine-readable output on stdout; everything else (errors, progress, logs) on stderr 6. **Exit codes**: map each failure mode to a code — success `0`, failure `1`, bad usage `2`; mint extra codes only for cases scripts must distinguish 7. **Safety**: `--dry-run`, confirmation rules, `--force`, `--no-input` 8. **Env/config**: env vars; config file path; precedence order with flags highest, then env, project config, user config, system 9. **Examples**: enough invocations to cover the common flows; show at least one pipeline or stdin use **Gate:** every flag used in the examples appears in the flags table, and every failure mode shown maps to an exit code. ## Constraints - Stay at spec altitude: when the request is "design the interface," deliver the spec and stop. Implementation is a separate task. - Keep the spec language-agnostic. Recommend a parsing library only when asked. - Target Linux. Skip Windows/macOS path, signal, and packaging concerns. ## Error handling ### Request mixes design and implementation Cause: user says "design and build." Solution: deliver the spec first, get confirmation, then implement against it. ### Spec balloons past one page Cause: subcommand sprawl or speculative flags. Solution: cut flags that lack a named user need; defaults should serve most users without aliases.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.