WebCLI

Open Specification · Draft v0.1

WebCLI Spec

A standard for building CLIs that LLMs already understand — no fine-tuning, no prompt engineering, no docs in context.

$ mycli --help
Usage: mycli [OPTIONS] COMMAND [ARGS]...

Options:
  -v, --verbose    Enable verbose output
  -q, --quiet      Suppress non-error output
      --version    Show version and exit
  -h, --help       Show this message and exit

Commands:
  init      Initialize a new project
  build     Build the project
  deploy    Deploy to target environment

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

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-verbose pair
  • Value flags: --output FILE or --output=FILE (both must work)
  • Short aliases: -v for --verbose, -o for --output
  • Stacking short flags: -xvf must 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:

CodeMeaning
0Success
1General error / no results (grep-style)
2Misuse / bad arguments
126Permission denied
127Command 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

Help Format

A conformant help block has exactly these sections, in this order:

  1. Usage lineUsage: TOOL [OPTIONS] COMMAND [ARGS]...
  2. Description — one sentence, present tense
  3. Options — two-space indent, aligned columns, defaults in brackets
  4. Commands — two-space indent, one-line descriptions
  5. Examples (optional but recommended)

All sections are separated by a single blank line. No ANSI color codes in --help output unless --color=always is explicitly set.

Non-conformant patterns

Help text emitted to stderr, missing -h alias, required flags not listed, and undocumented subcommands all break LLM zero-shot accuracy.

Flag Style

Flags must be lowercase, hyphen-separated (no underscores, no camelCase).

PatternConformantNon-conformant
Long flag--dry-run--dryRun, --dry_run
Value flag--output FILE--output:FILE
Negation--no-color--disable-color
Repeatable-v -v -v or -vvv--verbosity=3

Output Contracts

Machine-readable output must be opt-in, not default. The --json flag (following npm's pattern) is the standard mechanism.

$ tool list             # human-readable table
$ tool list --json      # newline-delimited JSON objects
$ tool list --quiet     # only names, one per line (grep-friendly)

The --quiet mode (single values, one per line) is the most LLM-understood piping primitive.

Error Messages

Errors go to stderr. Format: Error: <what went wrong>. <what to do>.

Error: no such file 'config.yaml'. Run 'tool init' to create one.

Include the failed invocation hint in the error message. LLMs generate recovery shell commands directly from error text — this pattern is saturated from git, npm, and pip.

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/webcli/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
  • Reference implementations: Examples in Python (Click), Go (Cobra), and Node.js (Commander) are in progress

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.