agentleFS
drinkspillerdrinkspiller/skills/cli_design/SKILL.md

cli-design

Skill1 starsChanged 5 days agoUnlicenseView on GitHub

Best practices for designing command-line interfaces (CLIs). Use when creating, reviewing, or improving CLI tools — covers command structure, naming, flags, help text, output formatting, error handling, robustness, configuration, and Google-specific CLI conventions.

  • Reads credentials

17 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use writing, research and 1 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • alxyrginSkill

    writing

    Создание контента для личного бренда — статьи, посты, туториалы. Use when user asks to "напиши статью", "создай пост", "подготовь контент", "write article", "create content", or when task requires content creation for blogging, LinkedIn, Medium, or other publishing platforms.

    Also in 3 projects that use this

  • NVIDIASkill

    research

    Before designing a feature, research how comparable libraries solve the problem, check best practices, known pitfalls, and upstream changes. Use when starting a new feature, investigating an unfamiliar area, or the user asks to research something.

    Also in 3 projects that use this

  • SentrySkill

    review

    Fixture review skill.

    Also in 3 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

27 rules. 0 are common, 15 are distinctive, and 12 are very specific to this project.

  • 0

    Common

    Most of the 14 edited versions we read keep these.

  • 15

    Distinctive

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Human-first design: If a command is used primarily by humans, design for humans first.

    line 17
  2. Very specific:

    Simple parts that work together: Use stdout/stderr/exit codes correctly so programs compose via pipes.

    line 19
  3. Distinctive:

    Consistency across programs: Follow existing conventions — don't invent new flag names when standard ones exist.

    line 21
  4. Distinctive:

    Say just enough: Don't hang silently. Don't dump pages of debug output.

    line 23
  5. Very specific:

    Prefer noun-verb ordering for multi-level subcommands: docker container create, gcloud compute instances list.

    line 36
  6. Distinctive:

    Use subcommands to reduce complexity of tools with many operations.

    line 41
  7. Distinctive:

    Use standard flag names when they exist:

    line 66
  8. Very specific:

    Use --no- prefix for boolean negations (--reboot / --no-reboot).

    line 81
  9. Very specific:

    When run without required arguments, show concise help: description, one–two examples, common flags, and a pointer to --help.

    line 89
  10. Distinctive:

    After each command completes, suggest what the user might do next:

    line 97
  11. Distinctive:

    If state changes, tell the user what happened and what the new state is.

    line 116
  12. Distinctive:

    Use color to aid scanning, not as decoration:

    line 120
  13. Distinctive:

    Don't overuse — if everything is colored, nothing stands out.

    line 125
  14. Distinctive:

    Use spinners or progress bars for long operations.

    line 130
  15. Distinctive:

    Rewrite errors for humans: Don't dump raw stack traces or internal codes.

    line 135
  16. Distinctive:

    Put the most important information at the end — that's where eyes go.

    line 138
  17. Distinctive:

    Use non-zero exit codes for failures.

    line 139
  18. Very specific:

    Follow the XDG Base Directory spec (~/.config, ~/.cache, etc.).

    line 163
  19. Very specific:

    Read from .env files where appropriate, but don't use them as a substitute for proper config files.

    line 164
  20. Very specific:

    Check standard env vars: NO_COLOR, DEBUG, EDITOR, PAGER, TMPDIR, HTTP_PROXY, HOME, TERM.

    line 168
  21. Distinctive:

    Keep changes additive: Add new flags rather than changing existing ones.

    line 173
  22. Distinctive:

    Don't create time bombs: Avoid hard dependencies on external services that may disappear.

    line 176
  23. Very specific:

    Deployment: Use BinFS (go/binfs) for automated deployment to /google/bin/releases.

    line 188
  24. Very specific:

    Documentation: Create a go/${TOOL_NAME} link pointing to your docs.

    line 190
  25. Very specific:

    Flag consistency: Use the same flag names as peer tools in your ecosystem (e.g., --detach, -c for CL number).

    line 193
  26. Very specific:

    Dangerous operations: Default to --dry_run=true for destructive commands.

    line 195
  27. Very specific:

    CLI frameworks: Use absl.flags (C++/Python), Cobra (Go), picocli (Java), or clikt (Kotlin).

    line 200

“Common” is measured: kept by at least 6 in 10 of the 14 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

CLI Design Guide

Principles and patterns for building well-designed CLI tools, synthesized from industry best practices and Google-internal conventions.

Philosophy

  • Human-first design. If a command is used primarily by humans, design for humans first. Composability with scripts is secondary.
  • Simple parts that work together. Use stdout/stderr/exit codes correctly so programs compose via pipes. Support --json for structured output.
  • Consistency across programs. Follow existing conventions — don't invent new flag names when standard ones exist.
  • Say just enough. Don't hang silently. Don't dump pages of debug output. Show progress, confirm state changes, and keep noise low.
  • Ease of discovery. Comprehensive help, examples, and "next step" suggestions make CLIs learnable without external docs.

Command Structure

Naming

  • Command and subcommand names should be lowercase, single words where possible. Use kebab-case (my-command) if multiple words are unavoidable.
  • Topics are plural nouns, commands are verbs: apps create, containers list, config set.
  • Prefer noun-verb ordering for multi-level subcommands: docker container create, gcloud compute instances list.

Subcommands

  • Use subcommands to reduce complexity of tools with many operations.
  • Be consistent across subcommands — same flag names, similar output formats.
  • Don't have ambiguous commands like "update" and "upgrade".
  • Don't allow arbitrary abbreviations — they prevent adding new commands.
  • Don't have a catch-all subcommand — it blocks future expansion.

Arguments & Flags

Prefer Flags to Args

Flags are self-documenting and order-independent. Positional args are OK only for simple, unambiguous primary actions (e.g., rm file.txt, cd dir).

# Bad — which is source, which is destination?
mycli deploy production jira

# Good — self-documenting
mycli deploy --environment=production --product=jira

Flag Conventions

  • Always provide long-form flags (--help, not just -h).
  • Reserve short flags for the most common options only.
  • Use standard flag names when they exist:
FlagMeaning
-h, --helpShow help (never overload)
--versionShow version
-q, --quietSuppress non-essential output
-v, --verboseIncrease output detail
-f, --forceSkip confirmations
-n, --dry-runPreview without executing
-o, --outputOutput file or format
--jsonOutput as formatted JSON
--no-colorDisable color output
--no-inputDisable interactive prompts
  • Use --no- prefix for boolean negations (--reboot / --no-reboot).
  • Never read secrets from flags — use --password-file or stdin instead.

Help & Documentation

Help Text

  • Display help for -h, --help, and (for git-like tools) help subcommand.
  • When run without required arguments, show concise help: description, one–two examples, common flags, and a pointer to --help.
  • Show full help with all flags when --help is passed.
  • Lead with examples — users prefer them over prose.
  • Show most common commands first, then group the rest.

Suggesting Next Steps

After each command completes, suggest what the user might do next:

✓ App created successfully.
  Next: deploy with `mycli deploy --app=myapp`

Output Design

Stdout vs Stderr

  • stdout: Primary output and machine-readable data.
  • stderr: Log messages, progress, errors, and diagnostics.

Human-Readable First

  • Detect TTY to decide output format: rich for terminals, plain for pipes.
  • Support --plain for grep/awk-compatible tabular output.
  • Support --json for structured, parseable output.
  • If state changes, tell the user what happened and what the new state is.

Color

Use color to aid scanning, not as decoration:

  • Red: errors. Yellow: warnings. Other colors: structure/emphasis.
  • Disable color when: not a TTY, NO_COLOR is set, TERM=dumb, or --no-color is passed.
  • Don't overuse — if everything is colored, nothing stands out.

Progress

  • Print something within 100ms so the user knows it's working.
  • Use spinners or progress bars for long operations.
  • Break long tasks into visible steps with status for each.

Error Handling

  • Rewrite errors for humans. Don't dump raw stack traces or internal codes.
  • Explain what went wrong and how to fix it: Can't write to file.txt. Try: chmod +w file.txt
  • Put the most important information at the end — that's where eyes go.
  • Use non-zero exit codes for failures. Map codes to distinct failure modes.
  • For unexpected errors, offer a way to submit a bug report with pre-populated context.

Robustness

  • Validate input early and fail with clear messages before side effects.
  • Make operations idempotent — rerunning should be safe.
  • Set network timeouts with sensible defaults.
  • Make it recoverable — pressing ↑ Enter should pick up where it left off.
  • Handle Ctrl-C gracefully — clean up or exit immediately.
  • Make it crash-only — if you can defer cleanup to the next run, do so.

Configuration Hierarchy

Configuration should layer, with more specific sources overriding general ones:

PrioritySourceUse For
1 (highest)FlagsPer-invocation settings
2Environment variablesPer-session or machine-specific settings
3Project config fileShared, version-controlled project settings
4User config filePersonal defaults (~/.config/myapp/)
  • Follow the XDG Base Directory spec (~/.config, ~/.cache, etc.).
  • Read from .env files where appropriate, but don't use them as a substitute for proper config files.
  • Never read secrets from environment variables — they leak into logs, ps output, and child processes.
  • Check standard env vars: NO_COLOR, DEBUG, EDITOR, PAGER, TMPDIR, HTTP_PROXY, HOME, TERM.

Future-proofing

  • Keep changes additive. Add new flags rather than changing existing ones.
  • Warn before breaking changes. Deprecate flags with in-tool warnings and migration instructions before removing them.
  • Don't create time bombs. Avoid hard dependencies on external services that may disappear.
  • Changing human-readable output is OK — encourage --json in scripts for stability.

Google-Specific Patterns

For deeper Google-internal guidance, see references/google_cli_patterns.md.

Key highlights:

  • Deployment: Use BinFS (go/binfs) for automated deployment to /google/bin/releases. Don't require users to blaze build manually.
  • Documentation: Create a go/${TOOL_NAME} link pointing to your docs.
  • Defaults: Make the tool work with minimal flags. Don't assume the current working directory is the google3 root — infer it.
  • Flag consistency: Use the same flag names as peer tools in your ecosystem (e.g., --detach, -c for CL number).
  • Dangerous operations: Default to --dry_run=true for destructive commands. Force explicit specification of targets like --spanner_database.
  • Readable invocations: Make commands read like sentences: diffle -c cl/123 --for server --against embedded.
  • CLI frameworks: Use absl.flags (C++/Python), Cobra (Go), picocli (Java), or clikt (Kotlin). See go/go-style/best-practices#complex-clis.

Reporting Issues

Report bugs or improvements for this skill at Agent Skill: cli_design. See the skill_issue skill for instructions on filing and triaging skill bugs.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.