Reference
JSON contracts
If a script is going to depend on lev, pin down the contract first. Every machine-readable command starts with a versioned schema string and a stable outer envelope, so the parser can branch on the document it actually received.
The JSON envelope
JSON-emitting commands write one complete document to stdout. The outer object always has schema and data. Branch on the schema first, then parse the payload for that version.
{
"schema": "lev.cli.verify/v1",
"data": { ... command-specific payload ... }
}lev verify --json > verify.json
schema="$(jq -r '.schema' verify.json)"
case "$schema" in
lev.cli.verify/v1) jq '.data' verify.json ;;
*) echo "unsupported lev schema: $schema" >&2; exit 2 ;;
esacGrouped and direct commands
Some direct commands are short public spellings for grouped commands. Others keep a narrower report or fixed policy surface. Treat each spelling as a separate contract unless the documentation says it shares a schema.
| Grouped command | Grouped schema | Direct command | Direct schema |
|---|---|---|---|
lev inspect environment --json | lev.cli.inspect.environment/v1 | lev doctor --json | lev.cli.inspect.environment/v1 |
lev inspect performance --json | lev.cli.inspect.performance/v1 | lev profile --json | lev.cli.profile/v1 |
lev check --json | lev.cli.check/v1 | lev verify --json | lev.cli.verify/v1 |
lev inspect imports --json | lev.cli.shake/v1 | lev shake --json | lev.cli.shake/v1 |
lev profile keeps the original command-only report; project-wide file rankings and baselines belong to lev inspect performance. lev verify keeps its published phase order and report surface; lev check adds configured tasks and trust policy.
Parsing rules for scripts
Treat the schema string as the versioned contract name. Parse only fields documented for that schema, and preserve the complete JSON document in logs or artifacts when the run matters.
- Branch on
.schemafirst. - Do not infer the schema from the command spelling alone.
- Expect grouped and direct commands to differ when the public UX differs.
- Keep stdout reserved for the JSON document; treat human progress as stderr or terminal-only text.
json="$(lev inspect performance --json --output - --warmup 1 --repeat 3)"
schema="$(printf '%s' "$json" | jq -r '.schema')"
if [ "$schema" = "lev.cli.inspect.performance/v1" ]; then
printf '%s' "$json" | jq '.data.summary'
else
echo "unexpected schema: $schema" >&2
exit 2
fiimport json
import subprocess
doc = json.loads(
subprocess.check_output(
["lev", "verify", "--json"],
text=True,
)
)
if doc["schema"] != "lev.cli.verify/v1":
raise SystemExit(f"unexpected schema: {doc['schema']}")
payload = doc["data"]Both examples identify the contract before reading its payload.
Related references
- Schema inventory lists every documented schema string by command family.
- Finding fields defines the shared finding object and distinguishes severity from policy.
- Exit behavior covers observational commands, drift checks, and preserved child exit codes.