4. Output
Source 04-output.md
- stdout carries data only. stderr carries the
error, warnings, and-verbosediagnostics. - Formats for
-output:text,json,yaml,md.yamlis encouraged but optional, to keep a CLI simple to implement.jsonis needed by every CLI, since it is the default when stdout is not a TTY.textis mandatory, since it is the default on a TTY.mdis encouraged but optional, and it is cheap to produce, sincetextis already built from markdown.- Summary:
jsonandtextmandatory,mdandyamlencouraged but optional. - A CLI that does not support
yamlfails-output yamlwithunsupported(exit 12),parameter: -output, and a fix that lists the formats it does support.describelists the supported formats for each CLI (section 8). - There is no separate
resourceformat. A resource is part of theresultpayload injsonoryaml. text: the human rendering. The CLI writes markdown-like structured text and renders it for the terminal (see Colour below).md: raw markdown, written as is.json,yaml: theresult/errorenvelopes.
- Summary:
- Default format:
textwhen stdout is a TTY,jsonotherwise.-outputalways overrides. (Same as clig.dev and Arcjet.)- Only stdout decides the default format. Colour is decided per stream (a redirected stderr gets no colour even if stdout is a TTY).
- Known weakness: the same command can print different things depending on how it runs, and TTY detection can mislead. An agent under a pseudo-terminal (ConPTY on Windows) can look like a human, and a person piping to
lessgets JSON. - Mitigation: agents, scripts, tests, and examples that depend on the shape pass
-output jsonexplicitly. Generated skills anddescribetell agents to do this (section 8). - Rejected for now: JSON always by default, with a user setting to switch humans to
text.
- Success is wrapped:
{"result": <payload>}. Injsonandyamloutput, a one-shot command prints exactly one object with aresultmember on stdout. It is the mirror of{"error": ...}on stderr (section 5). So a caller checks one rule:resultmeans success,errormeans failure.- Warnings. A command that succeeds but has something worth telling the caller returns a
warningslist besideresult:{"result": ..., "warnings": [{"kind": "deprecated", "message": "..."}]}. Each warning has a shortkindand amessage, and may carryparameter. The exit code stays 0. Intextandmd, warnings are shown as lines in the human form on stderr (**Warning:** message). A command with nothing to warn about omitswarnings. textandmdoutput are for humans and are not wrapped.- Exit code
0always comes withresult. A non-zero exit never hasresulton stdout (the exception isconfirmation_required, which is aresult, see section 6). - What goes inside
resultis up to the CLI. The spec does not force one payload shape.- A CLI that deals with resources returns the resource in the shape it defines, for example for something just created or updated.
- A CLI returning plain query results returns a list/array or a bare object.
describestates which shape each command returns (section 8).
- Warnings. A command that succeeds but has something worth telling the caller returns a
-field(repeatable) limits fields insideresultto save agent context. Theresultwrapper stays.- Colour.
- Every CLI must honour the
NO_COLORenvironment variable. When it is set and not empty, no colour or other ANSI styling is written, to stdout or stderr.-no-colorandTERM=dumbhave the same effect. - No colour, spinners, or decoration when not a TTY.
jsonandyamloutput never has colour. - Implicit structured text uses styling instead of marks. When the CLI writes its human rendering (
text, which is the default on a TTY) and styling is on, the renderer shows each span like this, and the markdown marks (`,**,*) are not written:- bold spans are written in bold (ANSI bold).
- the other spans, code spans and italics, are shown with colour (a different colour for each kind).
- plain text is left unstyled.
- Explicit
-output mdis raw markdown. No colour, and the marks are included, so the output is valid markdown to paste into a file or a viewer. This holds on a TTY too.
- Every CLI must honour the