cli.md

 1# CLIs
 2
 3Choose the smallest CLI shape that will still feel good to use. Prefer boring,
 4explicit command structure over clever frameworks, generated wrappers, or hidden
 5magic.
 6
 7## Shape choices
 8
 9- **One or two flags, server-style binary**: the ecosystem's standard flag parser
10  is usually enough.
11- **User-facing command with help/version/completions/subcommands**: use a mature
12  command framework plus a polished help/error layer when the ecosystem has one.
13- **Interactive prompts**: add a prompt library only when prompts are central, not
14  for a single confirmation.
15- **Full-screen interaction**: this is a TUI; read [tui.md](tui.md).
16
17## Config and version policy
18
19- Read config at the boundary, validate early, and store it in typed domain
20  structures.
21- Prefer explicit config discovery. Avoid magical precedence unless the project
22  truly needs layering.
23- Default precedence is flag, then environment variable, then config file.
24- Default config path is `$XDG_CONFIG_HOME/<app-name>/config.toml`, falling back
25  to `~/.config/<app-name>/config.toml` when `XDG_CONFIG_HOME` is unset.
26- Do not add exact version plumbing just for its own sake. Add project-owned
27  version resolution when the version appears in release artifacts, package
28  metadata, MCP metadata, tests, or multiple user-visible surfaces.
29
30## UX rules
31
32- Human text goes to stderr when stdout may be piped.
33- Machine output needs an explicit `--json`, `--jsonl`, or equivalent.
34- Destructive commands need names and help text that make the effect obvious.
35- Interactive commands need a non-interactive path for scripts and CI.
36
37## Go path
38
39For Go CLIs, read [golang/index.md](golang/index.md) first and follow its CLI
40chain. Do not jump straight to `golang/cli.md`; the index intentionally forces
41the Go baseline, mise, and library context before CLI specifics.