CLI Help Text skill for Codex
A --help screen users can copy from. Codex captures the current help and error output, then rewrites each command's help around the tasks users actually run: a one-line purpose, standard usage syntax, two to five runnable examples, options with units and real defaults, environment variables and a docs link. Usage errors name the fix and suggest typos, and snapshot tests pin the output so it cannot drift.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- cli-help-text Installs to ~/.agents/skills/cli-help-text/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install cli-help-text The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project cli-help-text Installs to .agents/skills/cli-help-text/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/cli-help-text.zipunzip -o cli-help-text.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) cli-help-text PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $cli-help-text, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Writes and fixes command-line help - the usage line, command and option descriptions, defaults, environment variables, examples and "see also" - for --help output, subcommand help, usage errors and man pages, following POSIX/GNU usage syntax and clig.dev conventions. Covers argparse, Click/Typer, Commander, clap and Cobra, man page generation with help2man, scdoc or pandoc, and snapshot tests so help never drifts. Use when a CLI's --help is confusing or incomplete, when adding commands or flags, when writing a man page, or when usage errors leave users stuck.
Use it when
- A command-line tool's --help output is confusing, outdated or missing examples
- New commands or flags are being added and need consistent help
- The tool needs a man page or better usage-error messages
Use something else when
- You are building the CLI itself (parsing, packaging, npx): use cli-tool-building
- The problem is runtime error wording rather than usage help: use error-messages
How to check the result
Every --help exits 0 on stdout within 80 columns, every example runs against a fixture, usage errors exit non-zero on stderr with a fix, and help snapshot tests pass.
The mistake it prevents
Typing default values into help strings by hand, so the help says one default while the code silently uses another.
Help text is done when a user who types tool --help can run the common task correctly
from what they see on one screen, can find any flag by scanning, and a mistyped command
tells them exactly how to recover. Examples do more work than descriptions; most users
copy the example closest to their goal.
Inspect first
cat AGENTS.md 2>/dev/null | head -60
./tool --help; ./tool <subcommand> --help; ./tool --bogus; echo "exit=$?"
rg -l "argparse|import click|typer|commander|yargs|clap::|spf13/cobra|urfave/cli" --glob '!node_modules' | head
ls man docs/man *.1 2>/dev/null
Capture the current help output to a file before changing anything; it becomes the baseline for the diff and the snapshot test.
Anatomy of —help
Order sections by what users need first:
Sync a local folder to an Acme bucket, uploading only changed files.
Usage: acme sync [OPTIONS] <SOURCE> <BUCKET>
Examples:
acme sync ./site my-bucket Upload changes in ./site
acme sync ./site my-bucket --dry-run Show what would change, upload nothing
acme sync ./data my-bucket --delete Also delete remote files missing locally
Arguments:
<SOURCE> Local directory to read from
<BUCKET> Destination bucket name (not a URL)
Options:
-n, --dry-run Print planned changes without uploading
--delete Delete remote files that do not exist in SOURCE
-j, --jobs <N> Parallel uploads [default: 8]
--exclude <GLOB> Skip matching paths; repeatable
-q, --quiet Only print errors
-h, --help Print help
Environment:
ACME_TOKEN API token (required unless --token is given)
Docs: https://docs.acme.dev/cli/sync
Rules:
- First line: one sentence, what the command does, from the user’s view. No “This command…”.
- Usage line:
<required>,[optional],...for repeatable,|for alternatives,[OPTIONS]as a placeholder. Real program name, notmain.py. - Examples near the top (2-5), each with a short comment; the most common task first,
then the most dangerous flag shown with its safe partner (
--dry-run). - Option descriptions: start with a verb or noun phrase, no trailing period, under
~60 characters, state the unit and the default (
[default: 8]). - Value placeholders name the kind of value:
<N>,<FILE>,<GLOB>,<DURATION>. - Group options when there are more than ~12 (Output, Network, Auth). Put rarely used flags under “Advanced” or into the long help only.
- Environment variables and config files that change behaviour are listed.
- Link to full docs at the end.
- Fit 80 columns; wrap descriptions, never the usage line mid-token.
Short vs long help
Many frameworks support both: -h shows a summary, --help the full text (clap does
this natively with about vs long_about). If you only have one, keep it to roughly one
screen and push detail to the man page or docs.
Usage errors
$ acme sync ./site
error: missing required argument <BUCKET>
Usage: acme sync [OPTIONS] <SOURCE> <BUCKET>
For more information, try 'acme sync --help'.
- Errors go to stderr;
--helpoutput goes to stdout with exit code 0. - Exit code 2 for usage errors is the common convention (argparse, clap, Click use it); document exit codes if scripts depend on them.
- Name the exact problem, show the short usage, point to
--help. Do not dump the full help on every error. - Suggest the closest match for typos:
unknown command 'snyc'. Did you mean 'sync'?(built into clap, Cobra and Commander; argparse needssuggest_on_error=True, Python 3.14+). For the wording of non-usage runtime errors see$error-messages.
Framework notes
| Framework | Where help text lives | Useful knobs |
|---|---|---|
| argparse | description=, epilog=, help= per argument | RawDescriptionHelpFormatter keeps example formatting; metavar= for placeholders; %(default)s in help strings |
| Click / Typer | Function docstring, help= on options | \b line in docstrings stops rewrapping of example blocks; show_default=True; epilog= |
| Commander | .description(), .option(flags, desc, default) | .addHelpText('after', examples), .showHelpAfterError() |
| clap (derive) | /// doc comments on struct and fields | #[command(about, long_about, after_help)], value_name, #[arg(default_value_t)] |
| Cobra | Use, Short, Long, Example fields | Short drives the parent’s command list; keep it under ~50 chars |
parser = argparse.ArgumentParser(
prog="acme sync",
description="Sync a local folder to an Acme bucket, uploading only changed files.",
epilog="Examples:\n acme sync ./site my-bucket --dry-run\n\nDocs: https://docs.acme.dev/cli/sync",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-j", "--jobs", type=int, default=8, metavar="N",
help="parallel uploads (default: %(default)s)")
Man pages
Write a man page when the tool is installed system-wide or packaged for distros. Standard section order: NAME, SYNOPSIS, DESCRIPTION, OPTIONS, EXIT STATUS, ENVIRONMENT, FILES, EXAMPLES, SEE ALSO, BUGS.
| Source | Command |
|---|---|
Generate from --help | help2man ./acme -o acme.1 (quick, inherits help quality) |
| Hand-written, readable source | scdoc < docs/acme.1.scd > acme.1 |
| Markdown source | pandoc docs/acme.1.md -s -t man -o acme.1 |
| Rust / clap | clap_mangen in a build script or xtask |
| Python / argparse | argparse-manpage |
man ./acme.1 # preview
mandoc -T lint acme.1 # structural lint where mandoc is installed
Generate man pages and shell completions at build or release time so they never drift from the code. Installing tools such as help2man or scdoc needs network or a package manager; ask before installing.
Workflow
- [ ] 1. Capture current help for every command and a few error cases
- [ ] 2. List the top 3 user tasks per command (from docs, issues, README)
- [ ] 3. Rewrite: first line, usage, examples, options with defaults, env vars, link
- [ ] 4. Fix usage errors: precise message, short usage, --help pointer, typo suggestions
- [ ] 5. Add or regenerate the man page and completions if the project ships them
- [ ] 6. Add snapshot tests for help output
- [ ] 7. Run every example from the help against a test fixture
Snapshot tests
def test_sync_help(snapshot, capsys):
with pytest.raises(SystemExit) as exc:
main(["sync", "--help"])
assert exc.value.code == 0
assert capsys.readouterr().out == snapshot
Equivalents: trycmd or snapbox for Rust, golden files plus a custom -update test flag in
Go, Jest/Vitest toMatchSnapshot() for Node. Set a fixed terminal width (COLUMNS=80)
in tests; many frameworks wrap to the terminal.
Gotchas
- Help that documents flags removed two versions ago because text is duplicated in the
README; generate README excerpts from the real
--help. - Defaults stated in prose that differ from the code default. Use the framework’s default interpolation instead of typing the value.
- Dangerous flags (
--force,--delete) described without the consequence. - Colour and bold in help when stdout is not a TTY, or when
NO_COLORis set. - Placeholder names that differ between usage line and option list (
<file>vsPATH). - Hidden flags still reachable but undocumented; either document or remove.
Verification
tool --helpand everytool <cmd> --helpexit 0, print to stdout, fit 80 columns.- Every example in help runs successfully against a fixture (or is a documented
destructive example shown with
--dry-run). - A usage error exits non-zero, prints to stderr, and names the fix.
- Snapshot tests pass and fail when a flag description changes.
- Man page previews correctly and lints clean.
Report
**Commands updated:** sync, pull, auth login (help + usage errors)
**Examples added:** 9, all executed against tests/fixtures/site
**Man page:** acme.1 generated with scdoc from docs/acme.1.scd at build time
**Tests:** 4 help snapshots (COLUMNS=80)
**Behaviour notes:** --jobs default is 8 in code; README said 4, README updated from --help What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "CLI Help Text"
short_description: "A --help screen users can copy from"
default_prompt: "$cli-help-text Our CLI's --help is a wall of flags; rewrite it with examples and grouped options" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.