--format plain is for people, and is not a contract — it may improve.
--format json is a stable contract, and is the one an agent or a script reads.
A command with nothing machine-readable to say takes no --format at all: to11 and to11 skill report nothing of their own, init is a conversation, and code prints nothing by design.
What holds in both forms
Nothing goes to stdout except the answer. Progress, warnings and errors go to stderr, so--format json piped into a parser stays valid even when something went wrong.
--help is text on every command, never JSON: it describes a command rather than reporting anything, so there is no data in it to shape.
What --format json promises
Deliberately not the API’s shape. A chosen subset, so the API can change — fields renamed, endpoints reshaped — without breaking a script or an agent reading this output. An API field never reaches it by default; it reaches it because someone added it.
- Additive only. No field is removed or retyped once shipped; new ones are added at the end.
- Absent, not null. An unknown or inapplicable value omits the field.
- Primitives and arrays of them — strings, numbers, booleans, and arrays of strings. Never a nested API object, so no API shape leaks through by accident.
- Stable ordering, so a diff of two runs is meaningful.
to11 skill list
One row per skill and target.
An
unmanaged row carries only what the client knows without reading the
directory: its name, its target, its path and its location. Never a version or
an origin — guessing would be a claim about someone else’s files.
labelVersion is how a pin behind its label shows. The row is unchanged
because configuration is satisfied, and the two numbers say the rest.
to11 skill sync
One row per skill and target. A skill configured for two targets is two rows.
outcome says what the run meant; diskAction and stateAction say what it
did. They are separate because doing nothing to one and something to the other
is an ordinary case rather than an exception — a skill dropped from
configuration whose directory is already gone touches no files and still loses
its record.
outcome is installed, replaced, updated, removed, unchanged,
conflict, dirty, orphaned, unmanaged or failed.
diskAction is install, replace, uninstall or none.
stateAction is add, update, remove or none.
unchanged appears in JSON but not in plain — a machine wants the full set,
a person wants the diff. It still carries version, because what is installed
is a fact whether or not this run wrote it.
failed replaces the outcome, it is not one of them. Every row whose
diskAction is not none can fail, and reason says why: the platform does
not publish the skill, the fetch broke, the write broke, the delete broke. A
failure never reaches a field that means something else, and a run with one
exits 1.
to11 whoami
person is absent and apiKey carries the fingerprint — never the key.
to11 skill store
published is always false — release is what changes that. created distinguishes a new skill from a new version of one, which is the guard against a mistyped slug.
to11 skill release
to11 version
States
One word per state, the same inlist, in sync and in JSON. Every one of
them is decided from three things — whether configuration includes the skill,
whether the state file records it, and whether anything is at the destination —
plus two comparisons between those and --force.
Something at the destination we did not write outranks the version. A
dirty directory is never asked what version it holds, because the answer
cannot change what happens to it.
A rollback needs no special state. The label moved from v7 to v4, so what
is recorded differs from what configuration resolves, and the row reads
7 → 4. The state says a sync will change this, not there is something
newer.
A pin behind its label is unchanged, not a state of its own.
Configuration is satisfied, so there is nothing to do — and the version column
already shows both numbers, so a separate word would be a second way of saying
it.