# afdata CLI reference
<!-- Generated by `afdata --docs`. Do not edit by hand. -->
A naming convention that lets AI agents understand your data without being told what it means, plus a CLI and library for reading and safely editing structured JSON, TOML, YAML, dotenv, and INI documents.
`afdata` is compiled from a closed `cli-spec-v1` registry: one source for argv parsing, typed invocation values, which parameter combinations are legal, output contracts, and help. An invocation runs only when it matches exactly one registered combination.
## Global arguments
AFDATA registers these; no command declares them, and the syntax in [Commands](#commands) leaves them out.
| Argument | Where | What it does |
|---|---|---|
| `--help` | every command | Every legal shape of that command, complete, plus its subcommands. JSON by default; `--output plain` for a terminal. |
| `--version` | afdata only | Name, version, and build identity as one protocol result. |
| `--docs` | afdata only | This document, rendered from the registry. |
| `--output <FORMAT>` | per output contract | Render as json, yaml, plain (default `json`). |
| `--output-to <DESTINATION>` | per output contract | Route results and diagnostics to split, stdout, stderr (default `split`). |
| `--stdout-file <PATH>`, `--stderr-file <PATH>` | per output contract | Append that stream to a file instead. |
Success output is protocol events, on those terms, unless a command's own **Output** line says otherwise.
A **shape** is one legal set of arguments that may appear together, under a stable id. Where a command has more than one, each id is a heading below. `--help` returns them all at once, so discovering a command costs one call; there is no recursive mode across commands, and this document is that view.
## Commands
- [`afdata add`](#afdata-add) — Add an element to a keyed list
- [`afdata emit error`](#afdata-emit-error) — Emit a terminal error event
- [`afdata emit log`](#afdata-emit-log) — Emit a diagnostic log event
- [`afdata emit result`](#afdata-emit-result) — Emit a terminal result event
- [`afdata get`](#afdata-get) — Read a document or one value as an AFDATA result
- [`afdata keys`](#afdata-keys) — List child names as raw lines, without their parent path
- [`afdata lint`](#afdata-lint) — Lint structured data for deterministic AFDATA issues
- [`afdata paths`](#afdata-paths) — List each child's full dot-path as raw lines
- [`afdata remove`](#afdata-remove) — Remove a keyed-list element by slug
- [`afdata render`](#afdata-render) — Render JSON or JSONL through AFDATA redaction and formatting
- [`afdata set`](#afdata-set) — Set a value at a dot-path, creating missing object parents
- [`afdata shell bash`](#afdata-shell-bash) — Print the sourceable Bash authoring kit
- [`afdata skill install`](#afdata-skill-install) — Install the bundled Agent Skill
- [`afdata skill status`](#afdata-skill-status) — Report whether the bundled Agent Skill is installed and current
- [`afdata skill uninstall`](#afdata-skill-uninstall) — Remove an afdata-managed Agent Skill
- [`afdata skill validate`](#afdata-skill-validate) — Validate an Agent Skill
- [`afdata unset`](#afdata-unset) — Remove one document entry
- [`afdata validate`](#afdata-validate) — Validate protocol-v1 events or a finite event stream
- [`afdata value`](#afdata-value) — Read one scalar as raw stdout bytes
### `afdata add`
Add an element to a keyed list
```
afdata add <FILE> <KEY> <SLUG> [<FIELD=VALUE>...] --slug-field <FIELD> [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>]
```
| Argument | Meaning |
|---|---|
| `FILE` | Document file to mutate |
| `KEY` | Dot-path to the keyed list |
| `SLUG` | New element slug |
| `FIELD=VALUE` | Additional string fields |
| `--slug-field` | Field that identifies each list element |
| `--input-format` | Document format override |
### `afdata emit error`
Emit a terminal error event
```
afdata emit error <CODE> <MESSAGE> [--hint <HINT>] [--retryable]
```
| Argument | Meaning |
|---|---|
| `CODE` | Stable error code |
| `MESSAGE` | Error message |
| `--hint` | Suggested corrective action |
| `--retryable` | Mark the failure safe to retry |
### `afdata emit log`
Emit a diagnostic log event
```
afdata emit log <debug|info|warn|error> <MESSAGE>
```
| Argument | Meaning |
|---|---|
| `LEVEL` | debug, info, warn, or error |
| `MESSAGE` | Human-readable message |
### `afdata emit result`
Emit a terminal result event
```
afdata emit result <MESSAGE>
```
| Argument | Meaning |
|---|---|
| `MESSAGE` | Result message |
### `afdata get`
Read a document or one value as an AFDATA result
```
afdata get <FILE> [<KEY>] [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>] [--secret-name <FIELD>...]
```
| Argument | Meaning |
|---|---|
| `FILE` | Document file, or - for stdin |
| `KEY` | Optional dot-path |
| `--input-format` | Document format override |
| `--secret-name` | Extra exact field name to redact |
### `afdata keys`
List child names as raw lines, without their parent path
```
afdata keys <FILE> [<KEY>] [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>] [--missing-ok] [--null]
```
Output: raw bytes on success; rejects `--output` and `--output-to`; redirect with `--stdout-file` or `--stderr-file`. Failures are still strict JSON on stderr.
| Argument | Meaning |
|---|---|
| `FILE` | Document file, or - for stdin |
| `KEY` | Optional container dot-path |
| `--input-format` | Document format override |
| `--missing-ok` | Succeed with no output when KEY is absent |
| `--null` | Use NUL separators |
### `afdata lint`
Lint structured data for deterministic AFDATA issues
```
afdata lint <INPUT> [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>] [--min-severity <warning|error>]
```
| Argument | Meaning |
|---|---|
| `INPUT` | Input file, or - for stdin |
| `--input-format` | Document format override |
| `--min-severity` | Lowest severity to report; `error` drops the heuristic checks |
### `afdata paths`
List each child's full dot-path as raw lines
```
afdata paths <FILE> [<KEY>] [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>] [--missing-ok] [--null]
```
Output: raw bytes on success; rejects `--output` and `--output-to`; redirect with `--stdout-file` or `--stderr-file`. Failures are still strict JSON on stderr.
| Argument | Meaning |
|---|---|
| `FILE` | Document file, or - for stdin |
| `KEY` | Optional container dot-path |
| `--input-format` | Document format override |
| `--missing-ok` | Succeed with no output when KEY is absent |
| `--null` | Use NUL separators |
### `afdata remove`
Remove a keyed-list element by slug
```
afdata remove <FILE> <KEY> <SLUG> --slug-field <FIELD> [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>]
```
| Argument | Meaning |
|---|---|
| `FILE` | Document file to mutate |
| `KEY` | Dot-path to the keyed list |
| `SLUG` | Element slug |
| `--slug-field` | Field that identifies each list element |
| `--input-format` | Document format override |
### `afdata render`
Render JSON or JSONL through AFDATA redaction and formatting
```
afdata render <INPUT> [--secret-name <FIELD>...]
```
| Argument | Meaning |
|---|---|
| `INPUT` | Input file, or - for stdin |
| `--secret-name` | Extra exact field name to redact |
### `afdata set`
Set a value at a dot-path, creating missing object parents
#### `set-value` — Set one typed scalar or JSON value
```
afdata set <FILE> <KEY> <VALUE> [--value-type <string|number|bool|json>] [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>]
```
#### `set-null` — Set the key to null; takes no VALUE
```
afdata set <FILE> <KEY> --value-type null [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>]
```
#### `set-secret` — Set the key from a secret source, never from argv
```
afdata set <FILE> <KEY> --secret-from <SOURCE> [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `FILE` | Document file to mutate |
| `KEY` | Dot-path to set |
| `VALUE` | Value to write |
| `--value-type` | Exact VALUE type |
| `--secret-from` | Read a secret string from stdin, prompt, fd:N, or env:VAR |
| `--input-format` | Document format override |
### `afdata shell bash`
Print the sourceable Bash authoring kit
```
afdata shell bash
```
Output: raw bytes on success; rejects `--output` and `--output-to`; redirect with `--stdout-file` or `--stderr-file`. Failures are still strict JSON on stderr.
### `afdata skill install`
Install the bundled Agent Skill
#### `skill-install-all` — Install into every agent that supports the scope
```
afdata skill install [--agent all] [--scope <personal|workspace>] [--force]
```
#### `skill-install-agent` — Install into one named agent; only this shape accepts --skills-dir
```
afdata skill install --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <PATH>] [--force]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--agent` | Target agent |
| `--scope` | Skill scope |
| `--skills-dir` | Explicit directory; only valid with one concrete agent |
| `--force` | Overwrite or remove an unmanaged skill |
### `afdata skill status`
Report whether the bundled Agent Skill is installed and current
#### `skill-status-all` — Report on every agent that supports the scope
```
afdata skill status [--agent all] [--scope <personal|workspace>]
```
#### `skill-status-agent` — Report on one named agent; only this shape accepts --skills-dir
```
afdata skill status --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <PATH>]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--agent` | Target agent |
| `--scope` | Skill scope |
| `--skills-dir` | Explicit directory; only valid with one concrete agent |
### `afdata skill uninstall`
Remove an afdata-managed Agent Skill
#### `skill-uninstall-all` — Remove from every agent that supports the scope
```
afdata skill uninstall [--agent all] [--scope <personal|workspace>] [--force]
```
#### `skill-uninstall-agent` — Remove from one named agent; only this shape accepts --skills-dir
```
afdata skill uninstall --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <PATH>] [--force]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--agent` | Target agent |
| `--scope` | Skill scope |
| `--skills-dir` | Explicit directory; only valid with one concrete agent |
| `--force` | Overwrite or remove an unmanaged skill |
### `afdata skill validate`
Validate an Agent Skill
```
afdata skill validate <INPUT>
```
| Argument | Meaning |
|---|---|
| `INPUT` | SKILL.md file, directory, or - for stdin |
### `afdata unset`
Remove one document entry
```
afdata unset <FILE> <KEY> [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>]
```
| Argument | Meaning |
|---|---|
| `FILE` | Document file to mutate |
| `KEY` | Dot-path to remove |
| `--input-format` | Document format override |
### `afdata validate`
Validate protocol-v1 events or a finite event stream
```
afdata validate <INPUT> [--strict] [--per-event]
```
| Argument | Meaning |
|---|---|
| `INPUT` | Input file, or - for stdin |
| `--strict` | Enforce the strict protocol profile |
| `--per-event` | Validate values independently without stream lifecycle rules |
### `afdata value`
Read one scalar as raw stdout bytes
```
afdata value <FILE> <KEY> [--reveal-secret] [--default <VALUE>] [--input-format <json|toml|yaml|yml|dotenv|env|ini|toml-frontmatter|yaml-frontmatter>] [--secret-name <FIELD>...]
```
Output: raw bytes on success; rejects `--output` and `--output-to`; redirect with `--stdout-file` or `--stderr-file`. Failures are still strict JSON on stderr.
| Argument | Meaning |
|---|---|
| `FILE` | Document file, or - for stdin |
| `KEY` | Dot-path to one scalar |
| `--reveal-secret` | Allow a secret-named leaf |
| `--default` | Fallback for missing or null |
| `--input-format` | Document format override |
| `--secret-name` | Extra exact field name to redact |
## Exit codes
| Code | Meaning |
|---|---|
| 0 | The command ran and succeeded. |
| 1 | The command ran and failed. The event carries a domain `error.code`. |
| 2 | The invocation was rejected before anything ran. `error.code` is one of the `cli_*` codes below. |
The split is the useful one for a caller: exit 2 means the call was never made, so retrying it unchanged cannot help, while exit 1 means it was.
## CLI errors
Every structural failure emits one strict JSON `kind:"error"` event on stderr, leaves stdout empty, and exits 2. The `code` names the failure — `cli_unknown_argument` for an unknown spelling, `cli_unregistered_combination` for registered arguments in a mixture that is not, and one each for `cli_unknown_command`, `cli_missing_argument_value`, `cli_invalid_argument_value`, `cli_duplicate_argument`, `cli_unexpected_positional`, and `cli_invalid_utf8`. `message` names the offending argument and `hint` gives the command to run next; neither ever quotes a raw value, including secrets. These are decided before any config, secret source, filesystem, network, or domain I/O.
Domain failures (exit 1) carry their own stable `error.code` instead, drawn from whatever this tool defines rather than from the `cli_*` set. No error message quotes a raw value it was given — an error event is routinely logged, and the input may hold secrets.