caarlos0/dotfiles/cli-design

Claude Code and agent skill by caarlos0/dotfiles

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Design and review command-line interfaces for usability, automation, safety, accessibility, and long-term compatibility. Use when adding or changing commands, flags, help, output, prompts, configuration, or exit behavior.

Install

npx vskill@latest install caarlos0/dotfiles/cli-design

SKILL.md

CLI Design

Treat a CLI as both a human interface and a stable automation API. Follow repository instructions and existing command conventions before introducing a new grammar, output format, exit status, or configuration mechanism.

Define the contract first

Before implementation, identify separately:

  1. The human workflows: discovery, common use, mistakes, recovery, and advanced

use.

  1. The automation workflows: unattended execution, input, output parsing,

failure handling, and composition with other tools.

  1. The public contract: commands, options, operands, defaults, streams, exit

statuses, prompts, environment variables, configuration, and structured output.

Write representative invocations before choosing a parser or framework:

text
tool [global-options] <command> [command-options] [operands]

Use noun/verb subcommands when they fit the domain, but preserve an established project grammar. Prefer a shallow, regular hierarchy over many special cases.

Design predictable commands

  • Give commands and long options lowercase, descriptive, spellable names.
  • Use commands for actions and options for parameters or behavior modifiers.
  • Keep the same concept named and spelled consistently across commands.
  • Reserve short options for frequent operations and provide a descriptive long

equivalent. Do not assign every option a short form.

  • Prefer explicit options over ambiguous positional arguments. Use positional

operands when their meaning and order are obvious.

  • Support -- before operands so names beginning with - remain addressable.
  • Where file operands make sense, consider - as stdin or stdout and document

the exact behavior.

  • Decide whether options may appear after operands, whether short options may be

grouped, and how optional values parse. Document and test the decision.

  • Do not accept arbitrary command abbreviations. Suggest likely corrections,

but never silently execute a guessed command.

  • Treat aliases as compatibility interfaces. Add one only when it is worth

supporting for the lifetime of the CLI.

  • Avoid implicit catch-all behavior that turns a typo into another valid,

potentially destructive operation.

Familiar options such as --help, --version, --quiet, --verbose, --output, --json, --color, --no-input, and --dry-run should retain their conventional meaning.

Make help useful at the point of failure

  • Provide -h and --help at every command level unless an established

compatibility contract prevents it.

  • Help must exit successfully without performing normal work, loading remote

data, or requiring valid credentials or configuration.

  • Order help for scanning: purpose, usage, common examples, common options,

remaining options or commands, then further documentation.

  • Lead with realistic examples, including piped or unattended use where

relevant.

  • Show defaults, accepted values, units, repetition rules, conflicts, and

whether an option can be supplied through configuration or environment.

  • For invalid input, explain the specific problem and show only the relevant

usage or hint. Do not print the entire manual after every typo.

  • Distinguish parse errors from operational failures.
  • For large CLIs, keep default help concise and provide a full-help or reference

tier.

  • Generate help, shell completion, and reference documentation from the same

command model where practical so they cannot drift.

Completion must tolerate incomplete input and must be fast, non-interactive, side-effect-free, and safe when configuration, credentials, or the network are unavailable. Avoid remote completion unless it is explicitly bounded and has a local fallback.

Keep the stream contract strict

  • Write requested result data to stdout.
  • Write diagnostics, warnings, prompts, progress, and debug information to

stderr.

  • Do not write headings, notices, progress, or ANSI control sequences into

machine-readable stdout.

  • Assert stdout, stderr, and exit status independently in tests.
  • Keep --quiet limited to nonessential messaging. It must not change result

semantics, suppress required errors, or turn failure into success.

  • Send verbose or debug diagnostics to stderr and redact secrets.

Human-readable tables and prose may evolve for usability. Do not require scripts to parse them. When automation is expected, provide an explicit stable format such as:

  • JSON for one bounded result;
  • JSON Lines for streamed records or events;
  • plain delimited fields where JSON is excessive;
  • templates or field selection for user-controlled rendering;
  • NUL-delimited output when values may contain whitespace or newlines.

Document machine-output fields, types, nullability, encoding, framing, ordering, and compatibility policy. If ordering is not guaranteed, say so. Human and machine renderers should consume the same application result rather than implementing behavior separately.

Define exit behavior deliberately

Return zero only for documented success. Use a small, stable, documented set of nonzero statuses rather than exposing arbitrary internal errors.

Decide explicitly how the command reports:

  • invalid usage;
  • operational failure;
  • authentication or authorization failure;
  • missing resources;
  • empty or no-match results;
  • cancellation or interruption;
  • partial success;
  • accepted or pending asynchronous work.

Do not let partial success look like full success. Report completed and failed items separately and choose an exit status that allows automation to detect the failure.

Follow established shell conventions where applicable, but do not invent portable meaning for every numeric status. Document the statuses that callers are expected to branch on.

Handle broken pipes as normal pipeline termination when the platform and command semantics permit it. Do not replace useful output with a stack trace because a downstream command stopped reading.

Write actionable errors

Expected user-facing failures should answer:

  1. What failed?
  2. Why did it fail?
  3. What can the user do next?

Use domain language rather than parser, transport, or stack internals. Include the relevant resource, option, configuration source, or rejected value without revealing secrets.

  • Put the primary error first and actionable hints afterward.
  • Name the exact replacement option or command when suggesting a fix.
  • Show concise contextual usage for usage errors.
  • Preserve the underlying cause for debugging without dumping a stack trace by

default.

  • Group repeated failures when one explanation applies to many items.
  • Never catch an error merely to return success-shaped output or an empty

result.

Represent errors structurally inside the application, with a stable category or code, user message, optional hints, underlying cause, and exit status. Render them only at the process boundary.

Keep TTY behavior presentational

Detect stdin, stdout, and stderr independently. They may point to different kinds of destinations.

TTY state may control:

  • color and styling;
  • paging;
  • wrapping and headings;
  • buffering;
  • progress animation;
  • whether prompting is possible.

TTY state must not silently change the selected resources, operation, result schema, or other command semantics.

  • Disable cursor motion, animation, and paging when their output stream is not

a terminal unless explicitly forced.

  • Never prompt unless both input and prompt output are usable terminals.
  • Keep redirected and CI output linear and stable.
  • Support NO_COLOR, TERM=dumb, and an explicit color mode such as

--color=auto|always|never.

  • Never encode meaning with color alone. Pair it with text, symbols, or

structure.

  • Sanitize untrusted terminal control sequences before displaying external

data.

  • Restore terminal state after cancellation and failure.

Use a pager only for long human-readable output, only when appropriate for the output destination, and provide a way to disable it. Do not page structured output.

Make interactivity optional

Every prompt must have a complete unattended equivalent through an option, operand, stdin, configuration, or environment variable.

  • Provide --no-input or an equivalent control when commands might prompt.
  • In non-interactive mode, fail immediately and name the missing input and its

replacement option.

  • Display prompt defaults explicitly. Destructive choices should default to the

safe answer.

  • Do not infer consent merely because stdin is closed or output is redirected.
  • Keep prompt wording, accepted answers, and cancellation behavior consistent.
  • Treat Ctrl-C as cancellation: stop starting new work, restore terminal state,

and return the documented cancellation status.

Do not make a full-screen or interactive selector the only route to an operation. Share application logic between interactive and non-interactive adapters. Use tui-design when the task specifically involves a full-screen terminal interface.

Scale safety to consequences

For risky operations, show the target, scope, count, and consequences before execution or confirmation.

  • Do not confirm low-risk actions that the user explicitly requested.
  • Use a yes/no confirmation for moderate risk.
  • Require a typed resource name or similarly strong confirmation for broad,

destructive, externally visible, or hard-to-reverse operations.

  • Prefer reliable undo over confirmation when undo is genuinely available.
  • Provide --dry-run for bulk, remote, destructive, or otherwise

hard-to-reverse operations.

  • Make dry-run follow real selection, validation, and planning paths; only the

final side effect should differ.

  • Keep --force narrow. It may bypass a named confirmation or conflict, but

must not bypass validation, authentication, or authorization.

  • Make retries and idempotency deliberate for remote mutations. Do not repeat an

operation automatically unless duplicate execution is safe or detectable.

Never accept secrets through ordinary argv when a safer channel is available; process arguments may be visible to other processes, logs, and shell history. Prefer hidden prompts, stdin, restricted files, file descriptors, credential stores, or secret managers.

Invoke subprocesses with argument vectors. Never build a shell command by interpolating untrusted values, and use -- before untrusted operands when the target command supports it.

Make configuration explainable

Define and test one precedence order. A strong default, from lowest to highest, is:

text
built-in defaults
< system configuration
< user configuration
< project or workspace configuration
< environment variables
< command-line options

Adapt the order when the product has an established contract, but document it.

  • Preserve the source of each effective value for diagnostics.
  • Report malformed configuration with the file, field, and source location.
  • Do not silently ignore an invalid higher-precedence value and fall back to a

lower one.

  • Define whether maps, lists, and repeated values merge or replace.
  • Provide a way to inspect effective configuration and provenance when the

system is complex.

  • Separate configuration, data, state, cache, and runtime files.
  • Follow platform conventions; use XDG base directories on Unix-like systems

where appropriate.

  • Load expensive or failure-prone configuration lazily so --help,

--version, and static completion remain reliable.

Environment variable names and configuration paths are public interfaces. Changing them requires the same compatibility care as changing an option.

Keep the CLI adapter thin

Separate command mechanics from application behavior:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
222
Repository forks
12
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/caarlos0/dotfiles/cli-design/badge)](https://verified-skill.com/skills/caarlos0/dotfiles/cli-design)

Something wrong with this skill or its page? Tell us.