Skip to content

JSON output

--json is a global flag: it turns a command’s result into machine-readable JSON on stdout instead of prose. The schemas on this page are a supported interface — they are versioned with Rivet and will not change shape without a CHANGELOG entry. From v1.0 that guarantee is written down: see the compatibility policy, which covers what may be added to these schemas and what may not.

Terminal window
rivet --json audit --repo ~/rivet-snapshots | jq '.files.changed'
  • Output goes to stdout, one JSON document, pretty-printed. Nothing else is written there — colour and styling are already suppressed whenever stdout is not a terminal, so a pipe stays clean.
  • Errors are not JSON. On failure stdout stays empty, the diagnostic goes to stderr as prose, and the exit status is non-zero. Check the exit status; do not try to parse a failure.
  • Absent optional values are null (for example "revision": null when auditing the latest snapshot), and empty collections are [], never omitted. A consumer never has to distinguish “missing” from “empty”.
  • Enum-like strings are lowercase snake_case (copy_file, plaintext-blocked uses a hyphen only where the prose form does).
{
"machine": { "operating_system": "Arch Linux", "architecture": "x86_64",
"desktop": "KDE", "session_type": "wayland", "distro_family": "arch",
"distro_version": "rolling", "native_manager": "pacman",
"window_manager": "kwin" },
"packages": { "native_manager": "pacman", "native": ["git"], "foreign": [],
"snaps": [], "flatpaks": [], "nix": [], "logical": [] },
"checklist": [],
"warnings": []
}

checklist holds the same entries rivet checklist returns.

An array, one entry per discovered configuration group.

[
{
"id": "shell-git",
"plugin": "shell-git",
"title": "Shell and Git",
"description": "Common shell dotfiles and Git preferences; authentication state is excluded.",
"selected": true,
"paths": [".gitconfig", ".config/git"],
"warnings": []
}
]

selected reflects the repository’s policy when --repo is given, and is false for every group otherwise.

The file-drift subset of audit.

{ "changed": [], "new_files": [], "missing": [] }
{
"revision": null,
"files": { "changed": [], "new_files": [], "missing": [] },
"packages": [
{
"manager": "flatpak",
"not_installed": [],
"not_in_snapshot": ["com.google.Chrome"]
}
],
"secrets": []
}

not_installed is in the snapshot but missing from this machine; not_in_snapshot is the reverse. revision echoes --revision, or is null for the latest snapshot.

The dry-run plan. With --diff, a diff key is added alongside it.

The "This is a dry-run plan. …" warning below appears only when the run really was a dry run; under --apply --yes it is absent and an outcome key reports what was written.

{
"plan": {
"actions": [
{
"kind": "copy_file",
"summary": "stage .gitconfig",
"source": "files/.gitconfig",
"destination": ".gitconfig"
}
],
"warnings": ["This is a dry-run plan. …"]
},
"diff": [
{ "path": ".gitconfig", "status": "identical", "preview": "" }
]
}

kind is one of install_official_package, install_aur_package, install_snap, install_flatpak, install_nix_package, restore_app_image, create_directory, copy_file, replace_file, create_symlink, run_hook, unseal_secret, or warning. status is new, changed, identical, or missing. source and destination are null where the action has none.

{ "changed": false, "pushed": false, "created_remote": false, "warnings": [] }

changed is false when the capture matched the previous snapshot and no commit was made — the field to check in a scheduled job.

{
"user_dir": "/home/you/.config/rivet/plugins",
"plugins": [
{ "id": "kde-plasma", "title": "KDE Plasma and Wayland",
"source": "built-in", "present": false, "user": false,
"roots": [".config/kdeglobals"],
"export_hooks": [], "import_hooks": [] }
]
}

source is built-in, or the absolute path of the declarative TOML file that defined the plugin — the answer to “where did this group come from, and what may it run?”.

user is the same distinction as a boolean: true for a plugin you declared, false for one Rivet ships. Filter on it rather than on source != "built-in" when you want to audit the hooks that are your own trust decision — for example, every user plugin that can run a command:

Terminal window
rivet plugins --json | jq '.plugins[] | select(.user and (.export_hooks + .import_hooks | length > 0))'
[
{
"path": "~/dev/scripts",
"present": true,
"include": ["**/*.sh"],
"exclude": [],
"secrets": "plaintext-blocked",
"mode": "preserve",
"symlinks": "preserve-in-root",
"allow_excluded_names": false
}
]

present is whether the declared path exists on this machine.

Metadata only — public recipients and secret names, the same information rivet.toml already carries in the clear. No ciphertext, and never plaintext.

{
"recipients": ["age1…"],
"secrets": [{ "name": "ssh-config", "path": "~/.ssh/config", "store": "age" }]
}
  • rivet tui is interactive and refuses --json with an error rather than ignoring it.
  • rivet about prints the branded splash; --json has no meaning for it and is ignored.
  • rivet init, track, untrack, and the mutating vault subcommands report prose progress. They are actions, not queries; check the exit status.