Write a command-line tool
Designs and implements a small command-line tool with subcommands, help text, exit codes, config precedence and tests. Use when turning a manual workflow into a reusable command.
A good CLI behaves the way experienced terminal users expect without reading its source. It prints help, keeps data on stdout and messages on stderr, returns exit codes that scripts can branch on, works in a pipe, asks before destroying anything, and takes configuration from flags, environment and files in a predictable order. Most quick tools get two of these right and surprise their users with the rest.
Build a command-line tool in for this purpose:
Planned commands: (if empty, design the smallest command set that covers the purpose).
- If the purpose is too vague to name the commands and their inputs, ask up to 3 questions and stop.
- Design the command surface before writing code: commands as verbs (
tool sync,tool list), arguments and flags per command, defaults, output, and exit codes. Use-h/--helpand--versioneverywhere. Add--jsonfor any command whose output another program might read, and--dry-runplus--yesfor anything destructive. - Use the ecosystem's standard parser, or the one the repo already uses: argparse or Typer for Python, Cobra or the standard
flagpackage for Go, clap for Rust, Commander orutil.parseArgsfor Node. - Configuration precedence, highest first: flags, then environment variables with a tool prefix (
TOOL_*), then a project config file, then a user config file under the platform config directory ($XDG_CONFIG_HOMEon Linux), then defaults. Document it in--helpand in the README. - Behaviour rules:
- Exit codes: 0 success, 1 failure, 2 usage error. Add specific codes only if callers need to tell failures apart, and document them.
- Data to stdout and progress, warnings and errors to stderr. Errors say what failed and what to do next.
- Detect a non-interactive terminal: no colours, spinners or prompts when piped. Respect
NO_COLOR. Accept-for stdin where a file is expected. - On Ctrl-C, stop cleanly, leave no partial files, and exit 130.
- Write tests: argument parsing per command, exit codes for success, usage error and runtime failure,
--jsonoutput shape, and one end-to-end run in a temporary directory. Do not test against the real network or the user's home directory. - Add a README section with installation, a usage example per command, the config precedence and the exit codes. Run the tests and a
--helpsmoke check.
- Keep it small: no plugin system, no global state, and no dependencies beyond the parser and what the purpose truly needs.
- Never print secrets, including in
--verboseor debug output. - Keep business logic in plain functions the CLI layer calls, so it can be tested without a subprocess.
- Before saying the work is done, run the check that proves it (tests, build, type check or the command the user gave) and report the real result.
- If you could not run a check, say so plainly and say which one.
Command surface
| Command | Arguments and flags | Output | Exit codes | Then the config precedence in one line.
Files
A tree, then each file in its own code block.
Tests
One line per test: what it proves.
Decisions
Choices you made that the purpose did not dictate, one line each.
Verification
Commands run (tests, --help) and their actual results.
1 required value still a placeholder; the assistant will ask for it.
details
- kind
- Prompt: a task you run by name to get one finished thing back
- domain
- Software engineering
- category
- Implementation
- level
- Intermediate
- made for
- Software engineer, DevOps / platform engineer, Site reliability engineer
- needs
- repo-read, file-write, shell
- risk
- runs-commands
- version
- v1.0.0 · incubating
- reviewed
- 2026-10-02
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md
use in
npx @hermes-hq/hodios install write-cli-tool --target claude-codenpx skills add hermes-hq/hodios-dist --skill write-cli-tool -a claude-codeclaude plugin marketplace add hermes-hq/hodios-distclaude plugin install hodios-software-engineering@hodiosThe plugin brings every entry in this domain at once.
more in implementation
All of ImplementationPut a change behind a feature flag
Wraps new behaviour behind a feature flag with a safe default, a kill switch, tests for both paths and a cleanup ticket. Use when shipping a risky change incrementally.
add-feature-flagAdd rate limiting to an API
Adds rate limiting to API endpoints with a fitting algorithm, keys, per-tier limits, standard headers, 429 responses and tests. Use when protecting endpoints from abuse or overload.
add-rate-limitingBackend engineer
Acts as a backend engineer focused on correct data handling, clear API contracts, explicit failure modes and services that are easy to operate. Use as a builder or reviewer persona for server code.
backend-engineerBuild a REST endpoint end to end
Implements one HTTP endpoint with route, input validation, handler, error mapping and tests in the project's own framework and conventions. Use when adding an API route.
build-rest-endpointBuild a reusable UI component
Builds a typed, accessible UI component from a description or screenshot, with loading, empty and error states and a usage example. Use when adding a component to a frontend.
build-ui-componentBuild a webhook handler
Implements a webhook receiver with signature checks, replay protection, idempotent processing, fast acknowledgement, async work, retries and tests. Use when integrating Stripe, GitHub or similar.
build-webhook-handler