Skip to main content

cli

CLI application design: argument conventions, output streams, exit codes, configuration hierarchy, interactive modes, and terminal UX. Invoke whenever task involves any interaction with command-line tools or terminal applications — building, reviewing, debugging, or designing CLI interfaces.

معلومات المصدر

المستودع
xobotyi/cc-foundry
آخر نشاط في المصدر
٢٣ أغسطس ٢٠٢٦ في ٢٣:٤٦
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٢٢
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
8 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
cli
description
CLI application design: argument conventions, output streams, exit codes, configuration hierarchy, interactive modes, and terminal UX. Invoke whenever task involves any interaction with command-line tools or terminal applications — building, reviewing, debugging, or designing CLI interfaces.
# CLI Design **Programs are composable by default.** stdout carries data, stderr carries diagnostics, exit codes carry status, and signals carry intent. Get the boundaries right and everything else follows. ## References - **Arguments** [`${CLAUDE_SKILL_DIR}/references/arguments.md`] — Full POSIX guidelines, GNU long option table, subcommand patterns, flag design - **Output** [`${CLAUDE_SKILL_DIR}/references/output.md`] — Stream separation details, color codes, ANSI escapes, NO_COLOR spec, pager setup - **Exit codes** [`${CLAUDE_SKILL_DIR}/references/exit-codes.md`] — Standard/extended code tables, signal exit codes, partial success patterns - **Interaction** [`${CLAUDE_SKILL_DIR}/references/interaction.md`] — TTY detection, prompting patterns, confirmation levels, progress display, error format - **Configuration** [`${CLAUDE_SKILL_DIR}/references/configuration.md`] — Full hierarchy, XDG spec, env var catalog, config file formats, secret handling - **Signals** [`${CLAUDE_SKILL_DIR}/references/signals.md`] — Full signal table, SIGPIPE handling, crash-only design, child process signals ## Output Streams This is the single most important convention. Mixing data and diagnostics in stdout is the #1 way to break composability. - **stdout is data.** Primary output goes to stdout -- query results, computed values, formatted data. This is what gets piped to the next command or redirected to a file. - **stderr is diagnostics.** Progress indicators, status messages, warnings, errors, and debug output go to stderr. Users see stderr in the terminal even when stdout is redirected. - **Check each stream independently.** stdout may be piped while stderr is still a TTY. Adapt output format per-stream: human-readable when TTY, machine-parseable when piped. - **No animations when not a TTY.** Disable spinners, progress bars, and color when the target stream is not an interactive terminal. This prevents CI logs from becoming escape-code garbage. - **Print something within 100ms.** Before any network request or long operation, print a status line to stderr. Silence looks like a hang. - **Tell the user what changed.** When a command modifies state, describe what happened and suggest what to do next. ## Arguments - **POSIX short flags, GNU long flags.** Single-letter options use `-x`, multi-letter use `--long-name`. Every short flag must have a long equivalent. Reserve one-letter flags for frequently-used options. - **`--` terminates options.** Everything after `--` is an operand, even if it starts with `-`. This is POSIX Guideline 10 and is non-negotiable. - **Prefer flags over positional arguments.** Flags are self-documenting. Exception: primary action on a single target (`rm file.txt`, `cat file.txt`). Two or more positional args for different things is a design smell. - **`-` means stdin/stdout.** When a command accepts file arguments, `-` means read from stdin (or write to stdout when context is clear). - **Use standard flag names.** `-h`/`--help`, `--version`, `-v`/`--verbose`, `-q`/`--quiet`, `-f`/`--force`, `-n`/`--dry-run`, `-o`/`--output`, `--json`, `--no-color`, `--no-input`. Don't reinvent these. - **Make flags order-independent.** Users add flags by pressing up-arrow and appending. `mycmd --flag subcmd` and `mycmd subcmd --flag` should both work where possible. ## Subcommands - **`noun verb` or `verb noun`, pick one and be consistent.** Don't mix ordering styles. `docker container create` and `docker image pull` follow `noun verb`. - **Support help at every level.** `mycmd --help`, `mycmd subcmd --help`, and `mycmd help subcmd` should all work. - **No catch-all subcommand.** Don't interpret unknown first arguments as an implicit default subcommand. This prevents you from ever adding new subcommands. - **No arbitrary abbreviations.** If `mycmd i` aliases `mycmd install`, you can never add `mycmd init`. Aliases must be explicit and stable. ## Exit Codes - **0 = success, 1 = error, 2 = usage error.** This covers most programs. Only define additional codes when callers need to distinguish specific failure modes. - **Signal exit codes use 128+N.** SIGINT (Ctrl-C) exits 130, SIGTERM exits 143. Preserve this convention so calling scripts can distinguish "user cancelled" from "error." - **Never return 0 on failure.** Scripts depend on exit codes via `$?` and `set -e`. A false success silently breaks pipelines. ## Configuration - **Flags > env vars > project config > user config > system config > defaults.** This is the universal precedence hierarchy. A flag always wins over an env var, which always wins over a config file. - **Follow XDG for user-level files.** Use `$XDG_CONFIG_HOME/myapp/` (default `~/.config/myapp/`), not `~/.myapp`. Respect `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME`. - **Respect well-known environment variables.** `NO_COLOR`, `FORCE_COLOR`, `DEBUG`, `EDITOR`, `PAGER`, `HTTP_PROXY`/`HTTPS_PROXY`, `TMPDIR`, `HOME`, `TERM`, `LINES`, `COLUMNS`. Check these before inventing app-specific alternatives. - **Never read secrets from environment variables.** They leak through `ps`, Docker inspect, systemd, and process listings. Accept secrets via `--password-file`, stdin, or a credential helper. - **Never read secrets from flags.** `--password=secret` leaks into `ps` output and shell history. Use `--password-file` or stdin. ## Color and Terminal Output - **Disable color when:** stdout/stderr is not a TTY (check each independently), `NO_COLOR` is set and non-empty, `TERM=dumb`, or `--no-color` is passed. - **Support `FORCE_COLOR` or `--color`** to override detection and force color output when the user explicitly wants it. - **Use color intentionally.** Red for errors, green for success, yellow for warnings. Don't paint everything -- if everything is colored, nothing stands out. - **Use a color library.** Don't hand-code ANSI escape sequences. Libraries handle NO_COLOR, TERM detection, and cross-platform differences. ## Interactive Behavior - **Only prompt when stdin is a TTY.** If stdin is not interactive, fail with an error telling the user which flag to pass. Never hang waiting for input that will never come. - **Provide `--no-input`.** An explicit flag to disable all prompts. Required for CI/CD, cron, and automation. - **Confirm before destructive actions.** Prompt for `y/N` interactively, require `--force` non-interactively. For severe operations (deleting infrastructure), require typing the resource name. - **Provide `--dry-run`.** For any state-modifying command, let users preview what would happen without executing it. - **Don't echo passwords.** Disable terminal echo when accepting secret input. Provide `--password-file` as a non-interactive alternative. ## Signal Handling - **Respond to SIGINT immediately.** Print "Shutting down..." before starting cleanup. Add a timeout so cleanup can't hang forever. - **Second Ctrl-C skips cleanup.** Tell the user: "press Ctrl+C again to force." Then exit immediately. - **Handle SIGTERM like SIGINT.** Process managers (systemd, Docker, K8s) send SIGTERM before SIGKILL. Complete cleanup within the grace period. - **Handle SIGPIPE silently.** When the user pipes your output to `head`, don't print an error when the pipe closes. Exit quietly with code 141 or 0. - **Design for crash recovery.** Use atomic file operations (write to temp, rename). Check for incomplete state on startup. Don't require cleanup to complete for correctness. ## Help Text - **Support `-h` and `--help`.** Both must show help. Don't overload `-h` for anything else. - **Show concise help with no arguments.** When a command requires arguments and gets none, show a brief description, one or two examples, and a pointer to `--help` for the full listing. - **Lead with examples.** Users read examples first. Show common invocations before the flag catalog. - **Suggest corrections.** When the user types a close misspelling, suggest the correct command. Don't auto-execute the suggestion. - **Support `--version`.** Print the version and exit. Format: program name and version, optionally with build metadata. ## Error Messages - **Structure errors consistently.** Use a format like: `error: <what went wrong>` followed by `hint: <how to fix it>`. - **Be actionable.** Don't say "permission denied" -- say "permission denied; run with sudo or use --config-dir for a writable location." - **Put important information last.** The eye lands at the bottom of output. Put the error summary and fix there, not the stack trace. - **No stack traces by default.** Put them behind `--verbose` or write to a debug log file. Signal-to-noise ratio matters. - **Make bug reporting easy.** For unexpected errors, provide a URL or command to file a bug, pre-populated with diagnostic information. ## Structured Output - **Support `--json` for machine-readable output.** Output well-formed JSON to stdout. Use consistent field names across commands. - **Support `--plain` for scriptable tabular output.** One record per line, no color, no decorations. Useful for `grep` and `awk` pipelines. - **Use a pager for large output.** Pipe through `less -FIRX` when stdout is a TTY. Respect the `PAGER` environment variable. Don't page when output fits one screen. ## Robustness - **Validate input early.** Check arguments and flags before starting work. Report all validation errors at once, not one at a time. - **Make operations idempotent where possible.** Running the same command twice should produce the same result, not an error or doubled state. - **Make operations recoverable.** If the program fails partway through, the user can hit up-arrow and enter to retry from where it left off. - **Set network timeouts.** Allow timeout configuration and have a reasonable default. Never hang indefinitely on a network call. ## Naming - **Lowercase, short, memorable.** `curl` not `DownloadURL`. Use only lowercase letters and hyphens. Keep it easy to type. - **Avoid ambiguous subcommand names.** Don't have both "update" and "upgrade". Use distinct verbs or disambiguate with extra words. ## Future-Proofing - **Keep changes additive.** Add new flags rather than changing existing behavior. If you must break compatibility, warn in advance. - **Warn before deprecation.** When a user invokes a deprecated flag, tell them what to use instead and when the old form will be removed. - **Changing human-readable output is OK.** Encourage `--json` or `--plain` for scripts. Human-readable output is not a stable interface. ## Application When **writing** CLI code: - Apply all conventions silently. Don't narrate each rule. - Use an argument parsing library (clap, cobra, argparse, commander). - Wire up stdout/stderr correctly from the start. Retrofitting is painful. - Handle SIGINT/SIGTERM from day one. Don't defer signal handling. When **reviewing** CLI code: - Check stdout vs stderr usage first. This is the most common mistake. - Verify exit codes match actual success/failure. - Confirm `--help`, `--version`, and `--no-color` are supported. - Look for secret leaks in flags and env vars. ## Integration This skill covers CLI platform concerns -- the interface between a program and the terminal/shell/pipeline. Language-specific implementation details (argument parsing libraries, terminal I/O APIs) come from language skills (golang, javascript, etc.). The coding discipline skill governs general workflow. **Programs are composable when they respect boundaries.**
عرض على GitHub