CLI Anything
Overview
Turn one-off shell ideas into maintainable operator tools.
Prefer the smallest surface that is safe, testable, and pleasant to run locally.
Workflow
Normalize the operator job.
Identify:
- who runs it
- how often it runs
- whether it is non-interactive, prompt-driven, or full-screen terminal UI
- what inputs, outputs, exit codes, and side effects matter
Choose the lightest viable shape.
Start with:
- single shell script for tiny glue tasks
- Python CLI for most local automation
- Node CLI when the repo is already Node-first or needs JS ecosystem packages
- Go CLI when a static binary, concurrency, or very fast startup matters
- terminal UI only when flags and prompts are no longer enough
Design the command contract before coding.
Define:
- command name and subcommands
- required versus optional flags
- default values
- output modes such as human text, JSON, or quiet
- failure behavior and exit codes
Build for safe repetition.
Add:
- clear help text
- input validation close to the boundary
- dry-run mode for destructive actions
- deterministic stdout for piping and automation
- actionable stderr for operators
Add interaction only where it helps.
Prefer:
- flags for automation
- guided prompts for occasional human use
- a small TUI for selection, progress, or approval loops
Keep business logic separate from the interface layer so the same core code can power both CLI and TUI modes.
Verify the tool end to end.
Exercise:
--help
- happy path
- missing-input path
- invalid-flag path
- dry-run or no-op path
- machine-readable output if supported
Framework Selection
Read references/framework-selection.md when choosing an implementation stack.
Use these defaults:
- Choose plain Bash only for short wrappers around existing commands where quoting, portability, and error handling stay simple.
- Choose Python plus
argparse for standard-library-only tools and stable scripts with minimal dependencies.
- Choose Python plus
typer or click for polished multi-command CLIs with rich help, completion, and maintainable command trees.
- Choose Python plus
questionary or InquirerPy for lightweight guided prompts.
- Choose
textual only when the terminal experience genuinely benefits from panes, lists, live progress, or keyboard navigation.
- Choose Node plus
commander or yargs when the surrounding project is already JavaScript or TypeScript-first.
- Choose Go plus
cobra when distribution as a single binary is a real requirement.
Design Rules
- Separate pure operations from argument parsing and presentation.
- Make stdout easy to pipe; send diagnostics to stderr.
- Return non-zero exit codes on operator-relevant failure.
- Prefer explicit flags over positional ambiguity once a command grows.
- Preserve idempotence when possible.
- Keep prompts skippable via flags for automation.
- Offer
--json only if the output is meaningfully structured and stable.
- Avoid full-screen TUIs for workflows that fit a command plus confirmation prompt.
Lightweight Operator Surfaces
Use this escalation path:
- Plain command with flags
- Command plus confirmation or select prompt
- Command plus progress display or table output
- Small TUI with a focused job such as selecting targets, reviewing diffs, or driving a runbook
For operator surfaces:
- Show current state, next action, and consequence clearly.
- Make cancel and back-out paths obvious.
- Avoid hiding file paths, commands, or side effects behind vague labels.
- Keep keyboard flows efficient and discoverable.
Output Pattern
When using this skill, produce:
- a short rationale for the chosen CLI shape
- the command contract
- the implementation
- a quick verification pass
- any follow-up packaging or distribution note if relevant
1---2name: cli-anything3description: Build robust local command-line tools and lightweight interactive operator surfaces. Use when Codex needs to turn a workflow into a reusable CLI, add subcommands or flags, wrap scripts with safer argument handling, create a small terminal UI or guided prompt flow, or choose an implementation approach for local operator tooling in Bash, Python, Node, or Go.4---56# CLI Anything78## Overview910Turn one-off shell ideas into maintainable operator tools.11Prefer the smallest surface that is safe, testable, and pleasant to run locally.1213## Workflow14151. Normalize the operator job.16 Identify:17 - who runs it18 - how often it runs19 - whether it is non-interactive, prompt-driven, or full-screen terminal UI20 - what inputs, outputs, exit codes, and side effects matter21222. Choose the lightest viable shape.23 Start with:24 - single shell script for tiny glue tasks25 - Python CLI for most local automation26 - Node CLI when the repo is already Node-first or needs JS ecosystem packages27 - Go CLI when a static binary, concurrency, or very fast startup matters28 - terminal UI only when flags and prompts are no longer enough29303. Design the command contract before coding.31 Define:32 - command name and subcommands33 - required versus optional flags34 - default values35 - output modes such as human text, JSON, or quiet36 - failure behavior and exit codes37384. Build for safe repetition.39 Add:40 - clear help text41 - input validation close to the boundary42 - dry-run mode for destructive actions43 - deterministic stdout for piping and automation44 - actionable stderr for operators45465. Add interaction only where it helps.47 Prefer:48 - flags for automation49 - guided prompts for occasional human use50 - a small TUI for selection, progress, or approval loops51 Keep business logic separate from the interface layer so the same core code can power both CLI and TUI modes.52536. Verify the tool end to end.54 Exercise:55 - `--help`56 - happy path57 - missing-input path58 - invalid-flag path59 - dry-run or no-op path60 - machine-readable output if supported6162## Framework Selection6364Read [references/framework-selection.md](./references/framework-selection.md) when choosing an implementation stack.6566Use these defaults:67- Choose plain Bash only for short wrappers around existing commands where quoting, portability, and error handling stay simple.68- Choose Python plus `argparse` for standard-library-only tools and stable scripts with minimal dependencies.69- Choose Python plus `typer` or `click` for polished multi-command CLIs with rich help, completion, and maintainable command trees.70- Choose Python plus `questionary` or `InquirerPy` for lightweight guided prompts.71- Choose `textual` only when the terminal experience genuinely benefits from panes, lists, live progress, or keyboard navigation.72- Choose Node plus `commander` or `yargs` when the surrounding project is already JavaScript or TypeScript-first.73- Choose Go plus `cobra` when distribution as a single binary is a real requirement.7475## Design Rules7677- Separate pure operations from argument parsing and presentation.78- Make stdout easy to pipe; send diagnostics to stderr.79- Return non-zero exit codes on operator-relevant failure.80- Prefer explicit flags over positional ambiguity once a command grows.81- Preserve idempotence when possible.82- Keep prompts skippable via flags for automation.83- Offer `--json` only if the output is meaningfully structured and stable.84- Avoid full-screen TUIs for workflows that fit a command plus confirmation prompt.8586## Lightweight Operator Surfaces8788Use this escalation path:891. Plain command with flags902. Command plus confirmation or select prompt913. Command plus progress display or table output924. Small TUI with a focused job such as selecting targets, reviewing diffs, or driving a runbook9394For operator surfaces:95- Show current state, next action, and consequence clearly.96- Make cancel and back-out paths obvious.97- Avoid hiding file paths, commands, or side effects behind vague labels.98- Keep keyboard flows efficient and discoverable.99100## Output Pattern101102When using this skill, produce:103- a short rationale for the chosen CLI shape104- the command contract105- the implementation106- a quick verification pass107- any follow-up packaging or distribution note if relevant