JSON output
Every command accepts --json and then prints exactly one JSON document on stdout: the envelope. It is a frozen contract (ADR 0003): fields may be added, but removing or retyping a field requires a new schemaVersion.
The envelope
Section titled “The envelope”{ "schemaVersion": 1, "command": "axx steps search", "ok": true, "data": { }}| Field | Type | Meaning |
|---|---|---|
schemaVersion |
number | Envelope version; currently 1. |
command |
string | The command that ran, such as axx run or axx steps search. |
ok |
boolean | true when the command succeeded (exit code 0). |
data |
object | The command’s result. Absent when the command could not produce one. |
errors |
array | Errors that stopped the command. Absent when there are none: a run whose scenarios fail has ok: false and its report in data, without errors. |
The process exit code is the same with or without --json.
Errors
Section titled “Errors”{ "schemaVersion": 1, "command": "axx run", "ok": false, "errors": [ { "code": "AXX-E0202", "message": "invalid tag expression \"@x and\": Tag expression \"@x and\" could not be parsed because of syntax error: Expected operand.", "hint": "use expressions like \"@smoke and not @wip\"", "docs": "https://axx.nimbusxr.us/references/error-codes/#axx-e0202" } ]}| Field | Meaning |
|---|---|
code |
A stable AXX-Exxxx code; see error codes. Branch on this, not on message. |
message |
What went wrong, for humans. |
location |
Optional {file, line, column}, for example a line in axx.yaml or a feature file. |
hint |
Optional: what to do about it. |
docs |
A link to the code’s entry in the error code reference. |
The run report
Section titled “The run report”axx run --json puts the run report in data. --format agent:FILE writes the same object to a file. Only failures are listed, so the size depends on what broke, not on the size of the suite. This example leaves out the failure’s logs and context:
{ "schemaVersion": 1, "axx": "0.1.0", "result": "failed", "durationMs": 7, "counts": { "scenarios": { "failed": 1, "passed": 1 }, "steps": { "failed": 1, "passed": 5 } }, "notRun": 0, "interrupted": false, "failures": [ { "scenario": "fails", "location": "features/demo.feature:6", "status": "failed", "step": { "keyword": "Then", "text": "the response status code is 201", "location": "features/demo.feature:9", "definition": "rest.response.status" }, "error": { "kind": "assertion", "message": "Expected status code <201> but was <200>.", "expected": 201, "actual": 200 }, "rerun": "axx run features/demo.feature:6" } ], "undefined": []}| Field | Meaning |
|---|---|
result |
the worst scenario status: passed, skipped, pending, undefined, ambiguous or failed; interrupted when the run was cancelled |
durationMs |
wall-clock time of the run |
counts |
scenarios and steps by status (passed, failed, skipped, undefined, ambiguous, pending); zero counts are omitted |
notRun |
selected scenarios that did not run, for example after --fail-fast or an interrupt |
interrupted |
true when the run was cancelled |
dryRun |
true for axx run --dry-run; absent otherwise |
failures[] |
one entry per failed, undefined, ambiguous or pending scenario, in feature file order |
failures[].location, .tags, .rerun |
where the scenario is, its tags, and the command that reruns only it |
failures[].step |
the step that failed: keyword, text, location and the id of the matched definition; for a hook, hook is before or after |
failures[].error.kind |
assertion, error, timeout, panic, undefined, ambiguous or pending |
failures[].error.expected, .actual, .diff |
for assertions: the two values, as JSON, and a line diff when they are JSON documents or text of several lines |
failures[].error.stack, .candidates, .suggestions |
the stack of a panic, the matching definitions of an ambiguous step, close expressions for an undefined one |
failures[].logs, .context |
the scenario’s logs (the last 50), and pack context such as the last HTTP request and response |
undefined[] |
undefined steps with suggestions, for writing them correctly |
runErrors[] |
problems found after the scenarios, outside any of them (source: the pack, message); present only when there are some, and they make result failed |
Other commands
Section titled “Other commands”Each command documents its own data. The most useful for scripts and agents:
| Command | data |
|---|---|
axx steps search <q> |
{query, steps[]}; each step has id, pack, expr, variants, keyword, arg, doc, examples, params |
axx validate |
{files, scenarios, steps, problems[], warnings[]}; each problem has kind (undefined, ambiguous, argument), location, text, and a message, suggestions or candidates where they apply; warnings[], present when there are some, are findings of axx lint’s feature checks (kind lint), and hints[] name scenarios whose checks prove little (only a success status, or only that something did not happen); neither changes the exit code |
axx doctor |
{version, config, checks[]}; each check has name, status (ok, warn, fail), detail, hint |
axx env |
{services[], up[]}: the services axx started, each with name, state (running, left over, not cleaned up), pid and its cleanup; up lists those axx up holds |
axx config show |
{file, config, packs[]}: the effective axx.yaml (profiles and -D applied, values of secret-looking keys masked) and the project’s packs |
axx down |
{stopped, cleanedUp}: the services axx up kept running that it stopped, and the services an earlier run left behind that it stopped or cleaned up |
axx lint |
{baseDir, rules[], summary, notes[], hints[]}; hints[], present when there are some, suggest fixture factories and name scenarios whose checks prove little, and never change the exit code |
axx init |
{dryRun, files[], detected, agents}; each file has path, action (create, update, skip), reason; agents, absent with --no-agents, has detected[] (agent ids), skills[] (like files) and mcp[] |
axx mcp install |
{dryRun, change}; change and each entry of axx init’s agents.mcp[] has agent, scope (project, user), path, action (create, update, skip, or manual when command adds the server), reason, command |
axx docs export |
{files[]} |
axx fixtures generate |
{baseDir, dryRun, written[], unchanged[]}: every file the factories generate, relative to baseDir; with --dry-run, written[] is what it would write |
axx fixtures check |
{baseDir, checks, failures[], unmaterialized[]}; each failure has check, code and message; unmaterialized[], present when there are some, are ignored outputs this checkout has not generated yet |
axx fixtures explain <file> <path> |
{file, factory, fixture, path, value, origins[]}; origins[] is the value’s way into the fixture, outermost first, each with kind (identity, reference, expression, fixture, prototype-overlay, prototype, defaults, schema), file, at (where in the file) and detail |
For editors and generated clients, the axx.yaml schema is at /schemas/v0/axx.schema.json.