Output contract

ACTIVE
APPLIES TO: EVERY GENERATED CLI
SOURCE: src/core/cli.ts

Summary

RuleBehaviour
InputFlags and positionals. Nothing prompts or waits on stdin.
--jsonExactly one JSON object on stdout, success or failure.
stderrProgress and logs only. stdout carries the result and nothing else.
Exit codes0 success, 1 failure, 2 usage error.
describeEvery command, flag, default and example, as JSON.
--helpUsage, flags and examples for one command, as text.

The --json envelope

With --json, stdout gets one line of JSON. On success:

SUCCESS
{"ok": true, "command": "hello", "result": {"greeting": "Hello, Ada!"}}

result is whatever the command returned, or null if it returned nothing. On failure:

FAILURE
{"ok": false, "command": "hello", "error": {"code": "usage", "message": "Missing required flag: --name.", "hint": "Example: my-cli hello --name Ada --json"}}

hint is present only when there is one. details appears when a command fails with structured data, such as the findings of a check that didn't pass. command is null if the failure happened before a command was chosen. Check ok or the exit code; both always agree.

Without --json, results print as text: the command's render function if it has one, otherwise a key: value listing. Errors print to stderr as error: ... and hint: ....

Exit codes

CodeMeaningTypical error.code
0Success. Also --help, describe and --version.none
1The command ran and failed.the command's own code, e.g. target_not_empty; internal for an unexpected exception
2Bad input: unknown command, unknown flag, missing required flag, invalid value. Running with no arguments also prints help and exits 2.usage

describe and help

my-cli describe

Prints the whole CLI as pretty-printed JSON: name, about, the contract, global flags, and each command with its usage line, flags (name, short, type, required, default, description) and examples. It is always JSON, with no envelope, and needs no --json. Read it once at the start of a session instead of guessing flags.

my-cli hello --help
my-cli help hello

Both print one command's usage, flags, global flags and examples as text. Add --json to get the same information as that command's entry from describe, inside the envelope. my-cli --help lists all commands.

Flags

Global flags work on every command: --json and -h, --help. -v or --version works as the first argument.

String flags take a value: --name Ada or --name=Ada. Boolean flags take none: --shout, never --shout true. Unknown flags are a usage error, so a typo fails instead of being ignored. Missing booleans are false; missing strings take their default or are left undefined.

No prompts

Nothing asks a question. A missing required flag is an immediate usage error (exit 2) whose hint is the command's first example, so the caller learns the right invocation from the failure itself.

Using it from scripts

my-cli hello --name Ada --json | jq -r .result.greeting
my-cli hello --json || echo "failed with $?"
> Hello, Ada!
> failed with 2