All animus commands that accept --json wrap their output in the animus.cli.v1 envelope. This contract provides a stable, machine-readable interface for scripts, CI pipelines, and MCP tool integrations.
The schema field is always the string literal "animus.cli.v1". This value is defined as a constant (CLI_SCHEMA_ID) in the protocol crate and is shared across all producers.
Written to stdout.
{
"schema": "animus.cli.v1",
"ok": true,
"data": <T>
}| Field | Type | Description |
|---|---|---|
schema |
string |
Always "animus.cli.v1" |
ok |
boolean |
Always true for success |
data |
T |
Command-specific payload (object, array, or simple value) |
The data field varies by command. For simple acknowledgments it may be {"message": "ok"}. For queries it contains the full result object or array.
Simple acknowledgment:
{
"schema": "animus.cli.v1",
"ok": true,
"data": { "message": "task TASK-001 status updated to in-progress" }
}Query result:
{
"schema": "animus.cli.v1",
"ok": true,
"data": {
"id": "TASK-001",
"title": "Fix login bug",
"status": "in-progress",
"priority": "high"
}
}Written to stderr.
{
"schema": "animus.cli.v1",
"ok": false,
"error": {
"code": "<error_code>",
"message": "<human-readable message>",
"exit_code": <N>
}
}| Field | Type | Description |
|---|---|---|
schema |
string |
Always "animus.cli.v1" |
ok |
boolean |
Always false for errors |
error.code |
string |
Machine-readable error category (see Exit Codes) |
error.message |
string |
Human-readable error description |
error.exit_code |
integer |
Process exit code (1-5) |
error.details |
object? |
Optional structured context (present only when available) |
| code | exit_code | Meaning |
|---|---|---|
"internal" |
1 | Unclassified or unexpected error |
"invalid_input" |
2 | Bad arguments or values |
"not_found" |
3 | Resource does not exist |
"conflict" |
4 | State conflict |
"unavailable" |
5 | Service unreachable |
{
"schema": "animus.cli.v1",
"ok": false,
"error": {
"code": "internal",
"message": "daemon failed to start",
"exit_code": 1,
"details": {
"startup_log_tail": "error: panic in scheduler loop"
}
}
}The details field is omitted (not present) when no structured context is available.
The schema field enables future evolution. Consumers should check schema == "animus.cli.v1" before parsing. If the schema changes (e.g., "animus.cli.v2"), the envelope structure may differ.
Within animus.cli.v1, the envelope shape is stable:
ok,schemaare always present.- Success always has
data. - Error always has
errorwithcode,message, andexit_code.
The JSON envelope is serialized in compact form (no pretty-printing, no newlines) to ensure single-line output suitable for line-oriented log processing.
# Capture success data
data=$(animus subject get --kind task --id task:TASK-001 --json 2>/dev/null)
echo "$data" | jq '.data.status'
# Capture error
animus subject get --kind task --id task:NONEXISTENT --json 2>err.json
cat err.json | jq '.error.code'See also: Exit Codes, Global Flags.