Open Specification · Draft v0.1
WebCLI Spec
40%+
of public repos contain git
majority
of API docs use curl examples
2016–2024
docker in nearly every DevOps tutorial
LLMs have seen their flag conventions, subcommand structures, and output formats billions of times. Build your CLI to match well-known patterns so LLMs can invoke it correctly from just a name and a task description.
WebCLI-compliant
$ webcli contact list --output json
[
{"id": "c_1a2b", "name": "Priya Mehta",
"company": "Acme Corp", "stage": "qualified"},
{"id": "c_3c4d", "name": "Luis Vargas",
"company": "Beta Inc", "stage": "proposal"}
]
$ webcli deal create \
--contact c_1a2b \
--value 24000 \
--stage proposal
Deal d_9f1e created.
Non-compliant
$ webcli --listContacts
Priya Mehta (Acme Corp) [qualified]
Luis Vargas (Beta Inc) [proposal]
$ webcli --createDeal \
--contactId=c_1a2b \
--dealValue=24000 \
--dealStage=proposal
Success!
No affiliation
This specification is an independent research project. It has no affiliation with, endorsement from, or relationship to any company or product referenced herein, including but not limited to Git, Docker, npm, pip, curl, OpenSSH, GNU make, or GNU wget. All trademarks are the property of their respective owners.
What is WebCLI? ¶
When a developer asks an LLM to write a shell script using git, curl, or docker,
the model gets it right: flags, subcommands, output format and all. It doesn't need documentation
in the prompt. It already knows.
That's not magic. It's saturation. These tools have appeared billions of times in pre-2024 training data: in READMEs, Stack Overflow answers, blog posts, CI configs, and shell scripts. The patterns are baked in.
WebCLI is a specification for building new CLIs that match those saturated patterns closely enough that LLMs already "know" how your tool works from day one, without any training, documentation injection, or special prompting.
Scope
WebCLI covers command-line interface design: help text format, flag conventions, subcommand structure, exit codes, and output contracts. It does not prescribe implementation language or framework.
The 10 Canonical CLIs ¶
The WebCLI spec is derived from analyzing the help output and thousands of example invocations of the ten CLIs most heavily represented in LLM pre-training corpora. These tools define the pattern language that models internalize.
| CLI | Domain | Key Patterns |
|---|---|---|
git |
Version control | Verb subcommands, --flag, porcelain output mode |
bash |
Shell / scripting | Exit codes, pipelines, -e/-x/-o pipefail |
curl |
HTTP / transfer | Single-letter + long flags, -o/-X/-H idioms |
npm |
Package management | Noun subcommands, --save-dev, JSON output via --json |
docker |
Containers | Object-verb subcommands (docker image ls), --format |
pip |
Python packages | Verb subcommands, -r requirements.txt, --dry-run |
grep |
Text search | POSIX short flags, stdin/stdout contract, exit code 1 = no match |
ssh |
Remote access | -p PORT, -i keyfile, user@host positional |
wget |
File download | Long flags preferred, -O output, -q quiet mode |
make |
Build system | Target nouns, -C dir, -j N, dry-run via -n |
Research & Evidence ¶
The WebCLI spec is grounded in empirical analysis, not opinion. For each of the 10 canonical CLIs, two documents were produced: the complete help output as emitted by the tool, and 100 real-world example invocations covering basic to advanced usage. All 20 documents were then analyzed to surface the flag conventions, subcommand structures, output contracts, and verb vocabularies that appear most consistently, and therefore carry the highest density in LLM pre-training corpora.
The synthesis of that analysis is cli_design_patterns.md,
which serves as the primary source of truth for the spec. Every design rule on this page can be
traced back to a specific pattern observed across multiple tools in the evidence below.
Methodology
For each CLI: (1) full help text was captured from the tool itself, (2) 100 representative invocations were documented, spanning everyday use through advanced scripting patterns. The resulting 20 documents were cross-referenced to identify conventions present across the majority of tools: the patterns LLMs have encountered most often.
| CLI | Domain | Help output | 100 examples |
|---|---|---|---|
git |
Version control | git_help.md | git_example.md |
bash |
Shell / scripting | bash_help.md | bash_example.md |
curl |
HTTP / transfer | curl_help.md | curl_example.md |
npm |
Package management | npm_help.md | npm_example.md |
docker |
Containers | docker_help.md | docker_example.md |
pip |
Python packages | pip_help.md | pip_example.md |
grep |
Text search | grep_help.md | grep_example.md |
ssh |
Remote access | ssh_help.md | ssh_example.md |
wget |
File download | wget_help.md | wget_example.md |
make |
Build system | make_help.md | make_example.md |
Core Principles ¶
Five design rules distilled from the 10 canonical CLIs. A conformant CLI follows all five.
1. Help Output ¶
Help text must be emitted on --help (and -h) to stdout, and follow a
consistent structure that models have seen millions of times:
Usage: TOOL [OPTIONS] COMMAND [ARGS]...
<one-line description>
Options:
-f, --flag Description of flag [default: value]
-h, --help Show this message and exit
Commands:
verb Short description of verb
Models parse this structure implicitly. Deviate from it and the LLM will hallucinate flags that don't exist.
2. Flag Conventions ¶
Every flag must have a long form. Short forms are optional but follow POSIX single-character conventions when present.
- Boolean flags:
--verbose/--no-verbosepair - Value flags:
--output FILEor--output=FILE(both must work) - Short aliases:
-vfor--verbose,-ofor--output - Stacking short flags:
-xvfmust be equivalent to-x -v -f
3. Subcommand Structure ¶
Use verb subcommands for actions (init, build, deploy, list, get, set, delete).
Prefer flat over nested. If nesting is necessary, follow the docker object-verb pattern: tool resource action.
$ tool init # verb
$ tool config get # object-verb (docker-style)
$ tool config set KEY=VALUE
4. Exit Codes ¶
Exit codes must be consistent and documented. Models infer script logic from exit code conventions:
| Code | Meaning |
|---|---|
0 | Success |
1 | General error / no results (grep-style) |
2 | Misuse / bad arguments |
126 | Permission denied |
127 | Command not found |
5. stdout / stderr ¶
Actionable output goes to stdout. Logs, warnings, and progress go to stderr. This is the invariant that makes pipelines work, and the one LLMs assume without being told.
$ tool build 2>/dev/null | jq . # works only if stdout is clean JSON
Specification ¶
Normative language
The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119.
The following design rules are derived directly from cross-analysis of the ten canonical CLIs. Each rule identifies the pattern that appears most consistently across the training corpus, and therefore carries the highest confidence weight in LLM representations.
§1 Universal Flags ¶
These flags appear across all or nearly all of the ten canonical CLIs. LLMs will predict them with near-certainty.
| Flag | Long form | Appears in | Confidence |
|---|---|---|---|
-h | --help | git, curl, npm, docker, pip, grep, ssh, wget, make | Highest |
-v | --verbose | curl, pip, wget, ssh, make, bash | Very high |
-V | --version | curl, pip, wget, make, npm | Very high |
--version | git, curl, npm, docker, pip, wget, make | Highest | |
-q | --quiet | curl, pip, wget, grep, make | High |
-s | --silent | curl, wget, make | High |
-o | --output | curl, wget, make | High |
-f | --file / --force | curl, make, git, wget | High |
-n | --dry-run | curl, make (--just-print), git | High |
-r | --recursive | grep, wget, pip | High |
-i | --include / --ignore-case | grep, curl | Medium |
-e | --regexp / --execute | grep, wget | Medium |
-d | --debug | pip, wget, docker | Medium |
-C | --directory | make, curl, git | Medium |
Design rule
Implementations MUST support -h/--help, -v/--verbose, --version, -q/--quiet, -o/--output, and -n/--dry-run. These are the flags an LLM will guess first, always.
§2 Subcommand Structure ¶
Pattern A: <tool> <verb> <noun>: dominant in high-level tools (git, docker, npm, pip)
git commit -m "message"
docker run -d nginx
npm install lodash
pip install requests
Verbs are simple English: run, build, push, pull, install, uninstall, list, show, create, delete, start, stop, logs. Nouns are resource names: container, image, network, volume, package, branch, tag.
Pattern B: <tool> [flags] <target>: dominant in low-level/Unix tools (curl, grep, ssh, wget, make)
curl -X POST -H "Content-Type: application/json" https://api.example.com
grep -rn "TODO" ./src
ssh -p 2222 user@hostname
wget -O file.tar.gz https://example.com/
No subcommands: the primary action is implied by the tool. Options modify behavior; positional arguments are targets.
Design rule
Use <tool> <verb> <noun> (Pattern A) if building a multi-resource CLI. If your CLI manages resources (users, projects, configs, jobs), use Pattern A. If it is a single-purpose utility (search, fetch, convert), use Pattern B. Most modern CLIs (gh, aws, kubectl, terraform) use Pattern A.
§3 Help Access Patterns ¶
| Pattern | Examples | LLM confidence |
|---|---|---|
<tool> <subcommand> --help | docker run --help, pip install --help | Highest |
<tool> help <subcommand> | git help commit, npm help install | High |
<tool> -h | grep -h, make -h | High |
<tool> --help | curl --help, wget --help | Highest |
Design rule
Support both <tool> <subcommand> --help and <tool> --help. The docker/npm pattern of <subcommand> --help is the most commonly seen in training data.
§4 Output Conventions ¶
| Convention | Adoption | Notes |
|---|---|---|
| Errors → stderr | All 10 | Allows clean piping of stdout |
| Data/output → stdout | All 10 | Enables piping to jq, grep, etc. |
| Exit code 0 = success | All 10 | POSIX standard |
| Exit code non-zero = failure | All 10 | Enables && / || chaining |
-q/--quiet suppresses stdout | 8/10 | Silent for scripting |
-v/--verbose adds detail | 8/10 | Debugging aid |
--dry-run/-n previews actions | 6/10 | Safety before destructive ops |
Design rule
Implementations MUST write errors to stderr and output to stdout. Implementations MUST return exit code 0 on success and non-zero on failure. This is the single most universal convention across all ten tools.
§5 JSON Output ¶
Four of the ten tools support structured JSON output, and this pattern is rapidly converging:
| Tool | JSON output flag |
|---|---|
docker | docker inspect (JSON by default), docker ps --format json |
npm | npm list --format=json, npm outdated --json |
pip | pip list --format=json, pip outdated --format=json |
curl | --write-out for metadata; body is pass-through |
git | --format=json not native, but --porcelain for parseable output |
Emerging standard: --output json or --format json.
Design rule
Data-returning subcommands SHOULD support --output json (or --format json). LLMs will attempt to pipe output to jq; implementations MUST emit clean, valid JSON to stdout when this flag is set.
§6 Verb Vocabulary ¶
The most LLM-saturated action verbs, ranked by frequency across all ten tools' help output and examples:
| Rank | Verb | Tools using it |
|---|---|---|
| 1 | install | npm, pip, make (install target) |
| 2 | run | docker, npm, make |
| 3 | build | docker, npm, make |
| 4 | push | git, docker |
| 5 | pull | git, docker, npm |
| 6 | list / ls | docker, npm, pip |
| 7 | show | git, pip, docker (inspect) |
| 8 | create | docker, git (branch) |
| 9 | delete / rm / remove | docker, git, npm |
| 10 | update | npm, pip, docker |
| 11 | start | npm, docker |
| 12 | stop | docker, npm |
| 13 | logs | docker |
| 14 | init | git, npm, docker |
| 15 | config | git, npm, pip, docker |
| 16 | login | docker, npm |
| 17 | logout | docker, npm |
| 18 | version | git, docker, npm, pip |
| 19 | help | git, npm, pip, make |
| 20 | status | git, npm (doctor/audit) |
Design rule
Use verbs from this table. Do not invent new verbs. LLMs will predict these correctly. Avoid: execute (use run), enumerate (use list), erase (use delete).
§7 Flag Naming Conventions ¶
Short flags (-x): single character, preceded by single dash. Can be combined: -rf, -vvv, -aux. Used for frequently-typed, well-known flags.
Long flags (--flag-name): lowercase with hyphens (not underscores), preceded by double dash. Can take a value: --output=file.json or --output file.json.
Value separator: Both --flag=value and --flag value are used across the ten tools. Supporting both is safest.
Boolean flags:
- Positive:
--verbose,--force,--recursive - Negative:
--no-color,--no-cache,--no-verify - Pattern
--no-<flag>is used by curl, wget, docker, npm
Design rule
Short flags for the most common options (-v, -q, -o, -f, -h). Long flags for everything else. Use --no-<flag> to negate boolean flags. Use hyphens, not underscores, in long flag names.
§8 Positional Argument Conventions ¶
| Tool | Positional args |
|---|---|
git | git commit <pathspec> |
grep | grep [pattern] [file...] |
curl | curl [options] <url> |
ssh | ssh [options] <destination> [command] |
make | make [options] [target...] |
docker | docker run [options] <image> [command] |
Options come before positional arguments. Multiple positional args are common (files, URLs, targets).
Design rule
Put positional arguments after all flags. The most important positional arg comes last (or first if it is a resource name in <verb> <noun> commands).
§9 Configuration Layering ¶
All ten tools support configuration at multiple layers, in priority order (highest to lowest):
- Command-line flags — all 10 tools
- Environment variables — curl (
CURL_CA_BUNDLE), docker (DOCKER_HOST), npm (NPM_TOKEN), git (GIT_DIR) - Per-project config file — git (
.git/config), npm (.npmrc), make (Makefile) - User config file — git (
~/.gitconfig), npm (~/.npmrc), pip (~/.config/pip/pip.conf), curl (~/.curlrc) - System config file — ssh (
/etc/ssh/ssh_config), git (/etc/gitconfig)
Design rule
Support all three primary layers: CLI flags > env vars > config file. LLMs will expect MYTOOL_<FLAG> env vars and a ~/.mytoolrc or ~/.config/mytool/config file.
§10 Piping & Composability ¶
The most frequently seen piping patterns in training data:
# Pipe to jq (JSON output)
docker inspect container | jq '.NetworkSettings.IPAddress'
npm list --json | jq '.dependencies | keys'
# Pipe to grep (filter output)
docker ps | grep "nginx"
git log --oneline | grep "fix:"
pip list | grep "requests"
# Pipe to xargs (act on output)
docker ps -q | xargs docker stop
git diff --name-only | xargs grep "TODO"
# Silent with exit status check
curl -sf https://api.example.com/health && echo "OK"
make -q && echo "Up to date"
# Redirect output to file
git log > commits.txt
npm list > packages.txt
Design rule
Design for composability from the start. Stdout must be clean, pipeable lines or JSON; never mixed with progress/status. Use --quiet to suppress all non-data output for scripting. Give exit codes clear, documented meanings.
§11 Summary: Recommended Conventions ¶
A conformant LLM-fluent CLI applies all of the following:
| Decision | Recommended choice | Reason |
|---|---|---|
| Subcommand structure | <tool> <verb> <noun> | git/docker/npm pattern (highest LLM training density) |
| Help | --help and <subcommand> --help | Universal |
| Version | --version | Universal |
| Verbosity | -v / --verbose | 8/10 tools |
| Silence | -q / --quiet | 8/10 tools |
| Output file | -o / --output | curl, wget, make |
| Dry run | --dry-run or -n | make, curl, git |
| Force | -f / --force | git, docker, npm |
| JSON output | --output json | docker, npm, pip pattern |
| Config | --config <file> | curl, wget pattern |
| Errors | stderr | All 10 |
| Exit codes | 0 = success, non-zero = failure | All 10 |
| Flag naming | --kebab-case | All 10 |
| Flag negation | --no-<flag> | curl, wget, docker, npm |
| Env vars | MYTOOL_<FLAG> | docker, npm, git pattern |
| Verb vocabulary | From §6 table | Highest LLM saturation |
Why It Works ¶
LLMs don't learn tools from documentation at inference time. They learn from the statistical distribution
of patterns in training data. When your CLI matches the patterns of git, curl,
and docker, the model's internal representations transfer directly.
This is the same principle as transfer learning in neural networks, except the "model" is already trained, and you're designing your tool to land in a high-density region of its learned pattern space.
Training data saturation
git appears in an estimated 40%+ of all public GitHub repositories. curl appears
in the majority of API documentation examples. docker is in nearly every DevOps tutorial
published between 2016 and 2024. These tools define what a CLI is, in the model's representation space.
A conformant WebCLI tool will be correctly invoked, piped, and scripted by an LLM with no documentation in context: just the tool name and a task description. Non-conformant CLIs require documentation injection, fine-tuning, or repeated correction.
Get Involved ¶
WebCLI is an open specification. Contributions, corrections, and RFCs are welcome.
- GitHub: github.com/webclihq/spec — spec source, issues, and discussions
- Propose an RFC: Open an issue with the
[RFC]prefix to propose a spec change - Conformance testing: A reference CLI linter (
webcli-lint) is planned for v0.2
Status
This is a draft specification. Sections marked with [RFC] are open for community input. The spec will reach v1.0 when at least three independent conformant CLIs exist in the wild.