JSON output
--json makes a command print one JSON document on standard output instead
of text, for scripts, other tools and the graphical interface to come. It
works with the commands that read (system, list, search, info,
status, plan, history, updates, doctor, backups, drift check,
drift list, reliability, trust, hardware, setup, desktop,
bundle verify, bundle create --dry-run, profile list)
and with --dry-run plans (run, remove, update, updates --apply,
restore, doctor --repair). Anything that would change the machine is
refused with --json unless it is a dry run: a script cannot start a run by
asking for JSON. The menu, docgen, and the profile commands that write
files refuse it too.
Errors go to standard error as text, with exit status 1 and nothing on standard output.
helix-toolbox status --json | jq -r '.data.entries[] | select(.status.state == "update") | .id'helix-toolbox updates --online --json | jq '.data.channels[] | {id, count}'helix-toolbox run git ripgrep --dry-run --json | jq '.data.runnable'The envelope
Section titled “The envelope”{ "schema": 1, "helixforge": "1.7.0", "helix_toolbox": "1.7.0", "command": "status", "data": { }}helix_toolbox is the program’s version, from 1.7. helixforge is the
same version under the program’s name before 1.7, kept so schema 1 readers
still find it. The Updates channel for the program itself keeps the id
helixforge for the same reason.
schema is the version of these shapes. Within one schema version fields are
only added, never removed or changed in meaning; a field you do not know can
be ignored. command names the shape of data: run --dry-run and the
other dry runs print a plan. Text is passed on as the tools reported it;
JSON escapes control characters, so nothing in a document reaches a terminal
as a control sequence. Optional values are null rather than missing.
system
Section titled “system”| Field | |
|---|---|
distribution |
{id, name, id_like} from /etc/os-release |
package_manager |
pacman, apt, dnf, zypper, … or null |
kernel, architecture |
|
tools |
{sudo, nix, home-manager, flatpak}: whether each is on the PATH |
list, search, info
Section titled “list, search, info”An entry is {id, name, description, flags, kind}, kind being package,
script, command, nix, native or profile.
list:{tabs: [{id, name, items}]}; an item is an entry with"type": "entry", or{"type": "group", name, items}.search:{query, results}, entries best match first, each with itsscore. No match is an empty list, not an error.info: the entry withaction(for a package:binary,packagesby family,aur,flatpak,conflicts,removable; for a script:file,interactive; for a command:line; for Nix:nixand itsinstallableorflake; for native:native; for a profile:entries) andstatusas below,nullfor entries that are not packages.
status
Section titled “status”{entries: [{id, name, status}]}. status is null for an entry that is
not a package, else state and the fields for it, with the label and
detail the menu shows:
state |
Fields |
|---|---|
installed |
source, version, shadowed_by (a Nix copy found first on the PATH) |
update |
the same and latest |
managed |
by (Home Manager, NixOS, Nix), version |
elsewhere |
path |
absent |
replaces: installed packages it conflicts with |
| Field | |
|---|---|
steps |
[{index, id, name, command, fallbacks, depends_on}], in run order; depends_on lists earlier step indexes |
notes |
what needs nothing done, and why |
blocked |
entries left out |
requirements |
commands the steps need |
privileged |
whether it asks for a password |
risk |
low, medium or high |
keep_going |
whether a failure skips only what depends on it |
findings |
[{severity, message}] from the checks before a run, severity blocker or warning |
runnable |
there are steps and no blockers |
With --effects, a plan also has effects: for each step {id, name, changes}, each change {certainty, area, text, diff}. certainty is
known, expected or unknown; area is file, package, service,
boot or other; diff is null or {path, changed, rows}, each row
{before, after, tag} with tag being same, changed, removed or
added.
history
Section titled “history”{runs: [{unix_timestamp, entries, names, success, result, log}]}, newest
first; result is the exit status, interrupted or why the run could not
start, and log a saved log’s path or null.
updates
Section titled “updates”{online, channels: [{id, name, count, pending, note, commands, caveat}]}.
count and pending ([{name, from, to}]) are null where the tool
cannot say before it updates (Nix) or only says online (the AUR); 0 and []
mean nothing waits. commands are what updating runs, as argument lists.
doctor
Section titled “doctor”{checks: [{id, title, health, summary, evidence, advice, repair, entry}]},
health being good, notice or problem; repair is {label, commands} or null, run with helix-toolbox doctor --repair <id>.
backups
Section titled “backups”{snapshots, backups}: snapshots is {tool, restore} when Snapper or
Timeshift is set up, else null; each backup is {original, backup, taken, system, directory}.
helix-toolbox drift check --json prints {against, baseline, profile, matched, differences, unknown, restore}. against is baseline or
profile; baseline is {name, taken, system} (taken in Unix seconds)
or null, and profile the profile’s id or null. Each difference is
{kind, label, subject, was, now, entry, note}:
kind |
|
|---|---|
missing |
an application the baseline had, or the profile names, is not installed |
file-missing |
a configuration file or folder is gone |
not-applied |
an entry ran on the baseline machine and has no successful run here |
file-replaced |
a path is another kind of thing now, such as a file that became a link |
file-changed |
a file or folder has other contents |
setting |
the login shell, display manager, repositories, Flatpak remotes or desktop differ |
added |
installed here and not in the baseline |
version |
installed in both, at another version or from another source |
entry is the entry that installs or writes it, or null. matched counts
what is the same, unknown lists ids this catalog does not have, and
restore the entries that would put back what is missing and can run on this
machine, in order, for helix-toolbox run.
baselines
Section titled “baselines”helix-toolbox drift list --json: {baselines: [{id, name, taken, system, entries, files, settings, applied}]}, newest first; the last four are
counts, id the name drift check takes.
reliability
Section titled “reliability”{record, entries: [{id, name, assessment}]}. record is {run, url, commit, finished, distributions} for the Distributions run a release build
carries, or null. An assessment is {level, label, systems, verified, evidence, ran_here, critical}: level is hardware-tested, vm-tested,
container-tested, stand-in-tested or not-yet-validated; systems are
the containers or reported systems; verified the last date (YYYY-MM-DD)
or null; ran_here the last successful run on this machine in Unix
seconds, or null; critical whether failing could stop the machine
booting, logging in or showing a display, or it changes disks or the whole
system.
{id, name, kind, origin, file, sha256, installer_license, package_license, provenance, integrity, downloads, privileges, validation}.
file is the installer script, relative to the scripts folder, and
sha256 and installer_license are its checksum and license;
package_license is the license of the software it installs, as the package
manager reports it, or null. Each of
provenance, integrity and downloads is a list of {standing, label, subject, text}, standing being provenance (signed build provenance),
checked (a checksum or signature a tool checks), pinned (fixed to a
revision by its hash), unverified or unknown. validation is an
assessment as above.
hardware
Section titled “hardware”{firmware, disks, sensors, batteries, pci, usb}. firmware is
{available, devices, updates, note}: devices {id, name, vendor, version, updatable}, updates {device_id, device, from, to, summary, urgency}.
A disk is {name, model, bytes, kind, firmware, celsius} (kind NVMe,
SSD, HDD or USB); a sensor {chip, label, celsius, high, critical}; a
battery {name, status, capacity, health, cycles, model, technology}
(capacity and health in percent); a device {address, class, name, driver}. Unknown values are null.
{machine, workstations, chosen, suggestions}. machine is
{distribution, family, package_manager, tools, desktop, desktop_name, gpus, laptop}; each workstation {id, name, description, entries, when};
chosen the workstation named, or null; each suggestion {id, name, available, note}.
desktop
Section titled “desktop”{desktop, entries}. desktop is {kind, name, session, display_manager, appearance, owners, blocked}: kind is kde, gnome, xfce, cinnamon,
mate, hyprland, sway, other or null; display_manager is {name, files, theme} or null; each appearance value {key, label, value};
owners says what else sets the look; blocked why Helix Toolbox would not
change it, or null. entries are the suggestions for this desktop.
bundle
Section titled “bundle”bundle create --dry-run --json: {entries, downloads, dnf, flatpaks, complete}, each entry {id, name, offline, packages, network, flatpak}
(flatpak and network only when they apply), each download {url, file, checksum}, each Flatpak {id, reference, commit, remote, url, collection, user}. bundle verify --json: the manifest, {format, created, helix-toolbox, release, distribution, family, architecture, complete, entries, files, flatpak} (flatpak, the Flatpaks in the same form, only in format 2), each
file {path, sha256, bytes, source, assurance}.
verify
Section titled “verify”{passed, entries: [{id, name, checks}]}: passed is false when a check
failed (and the command exits 1). A check is {name, label, passed, unsure, later, detail}, label being Verified, Not verified, Not checked
(unsure: it could not be checked here) or After the reboot (later: it
holds only once the machine has started since the entry’s last run).
services
Section titled “services”services list: {units: [{name, description, enablement, active, sub, user}], session}. enablement is the unit file’s state (enabled,
disabled, static, masked, indirect…) or null for a unit without a
file of its own, active and sub how it runs or null when it is not
loaded, user whether it is the session’s; session whether the user’s
own systemd answered. services show <unit> is service: {unit, needed_by, consequence}, consequence what stopping or disabling it costs
or null.
startup
Section titled “startup”{applications: [{file, name, comment, exec, enabled, here, system, own}]}:
here whether it applies to this desktop (OnlyShowIn, NotShowIn),
system whether it comes from the system’s folder, own the user’s file
when there is one.
storage
Section titled “storage”{filesystems: [{path, free, total}], items: [{id, title, detail, size, frees, packages, not_offered}], kept: [{title, detail, size}]}, sizes in
bytes, null when unknown; frees is null when only the cleanup can
tell, not_offered why an item cannot be cleaned now, packages what
unused packages would remove.
performance
Section titled “performance”{boot, no_boot, now, previous, recorded, hints}. boot is null where
systemd did not record one, with no_boot saying why; otherwise {id, booted, kernel, phases: {firmware, loader, kernel, initrd, userspace, total}, slowest: [{name, took}], chain: [{name, at, took}]}, times in
milliseconds (firmware, loader and initrd null when unknown),
booted in seconds since 1970, chain what the login screen waited for.
now is {cpus, load, memory_total, memory_available, swaps: [{name, zram, size, used}], pressure: {cpu, memory, io}, governor, power_profile, heaviest: [{pid, name, memory}]}, bytes, and the share of the last minute
programs waited (null without the kernel’s pressure figures).
previous compares this boot with the one recorded before it, as
comparison does, or is null; hints are [{title, detail, command, unit, entry}]. performance boots is boots: {boots: [...]}, newest
first. performance compare is comparison: {before, after, phases: [{name, before, after}], units: [...], runs: [{at, names, success}]}.
recovery
Section titled “recovery”{checks, snapshots}: the checks as doctor gives them (snapshots,
snapshot-boot, second-kernel, configuration-backups, own-files,
machine-record; a check that does not apply here is left out), and the
snapshot tool set up (Snapper, Timeshift) or null.
migration
Section titled “migration”migrate show <file>: {from, family, architecture, made, same_family, counts: {install, here, unavailable, yours}, items: [{kind, id, name, standing, detail}]}. family is the package family the file was made on
(arch, debian, fedora, suse, alpine, void, solus) or null;
made is in seconds since 1970. kind is entry, flatpak or
package; standing is install, here, unavailable or yours, and
detail says where it comes from here or why it does not.
migrate-export
Section titled “migrate-export”migrate export: the migration the file would hold, {version, from, family, architecture, made, entries, flatpaks, packages}, entry ids,
Flatpak ids and package names; nothing is written.
restic
Section titled “restic”{configured, repository, origin, password, paths, excludes, problem, snapshots, snapshots_problem, timer}. origin is settings,
environment or command-center; password says where restic gets it
(never the password); problem why the settings cannot be used, or
null. snapshots are [{id, short_id, time, hostname, paths, tags}],
newest first, with snapshots_problem what restic said when it could not
read them; timer is day, week or null.
restic-files, restic-history, restic-baselines
Section titled “restic-files, restic-history, restic-baselines”restic files: {snapshot, folder, nodes: [{name, type, path, size, mtime}]}, folders first. restic history: {pattern, files: [{path, versions: [{snapshot, short_id, time, hostname, size, mtime, change}], missing_from}]}, change first, changed or same, newest version
first. restic baseline: {baselines: [{id, path, sha256, recorded}]},
newest first; recording one prints it as restic-baseline.
repositories
Section titled “repositories”repos: {roots, depth, origin, repositories: [{name, path, branch, changed, upstream, ahead, behind, last, last_at, origin, problem, favorite, group}]}. origin at the top says where the roots come from
(settings, Command Center, default); in a repository it is
origin’s address without credentials. branch is null when HEAD is
detached; upstream, ahead and behind are null without an upstream;
problem says why a repository could not be read, and is null otherwise.
last_at is in seconds since 1970.
repository
Section titled “repository”repos show <repo>: {summary, files: [{path, original, staged, unstaged, conflict}], branches, remotes, stashes: [{id, name, subject}], log: [{hash, subject, at}], head, branch_ref, index_tree, busy, push_to, staged_stat, tasks: [{id, name, command, shell, detected}]}. staged and
unstaged are git’s status letters ( , M, A, D, R, C, U,
?); busy names a merge, rebase, cherry-pick or revert under way;
push_to is [remote, ref] or null; shell is direct, fish or
bash, and detected is true for a task found in a manifest. repos tasks is tasks: {repository, tasks}.
repos diff <repo> [file]: {text, truncated}, the patch as git prints
it (an untracked file as its lines), truncated when it was cut short.
config
Section titled “config”config <ghostty | fastfetch>: {kind, problem, path, live, origin, managed, flake, exists, revision, checked, values, backups}. problem
says why the file cannot be edited (then the rest is null or empty);
path is the file edited, live where the program reads it, origin
settings, command-center, dotfiles or live, managed whether the
live file is a Home Manager link, flake the Home Manager flake it is part
of or null. revision is the file’s SHA-256, or absent. checked is
{state, message}, state valid, unchecked or invalid and message
there unless it is valid. values are [{key, label, hint, value}]
(value null when not set); backups are [{backup, taken}], newest
first. config <program> history is config-history: {kind, path, backups}; config <program> validate is config-validate: {kind, checked}.
home-manager
Section titled “home-manager”home-manager: {installed, version, config, problem, generations, repository, links}. config is {folder, flake, profile, origin, reference} or null, origin settings, command-center or default
and reference the --flake argument (null for home.nix); problem
says why a named configuration cannot be used. generations are [{id, built, path, current}], newest first, built as Home Manager prints it;
repository is the configuration’s repository as repos lists one, or
null; links are [{name, path, target, managed}], managed when the
file links into the Nix store. home-manager generations is
home-manager-generations: {generations}.
hardware_report
Section titled “hardware_report”report --worked <entry>: {entries: [{id, name}], machine, system, version, date, records, toml, issue}. machine is {distribution, desktop, model, graphics, kernel, architecture, virtualized} (graphics a
list of cards with their drivers; unknown values null), and system the
line made from it. records are the [[hardware]] records it asks for,
{entry, system, version, date, note} (note left out when empty), and
toml the same as TOML; issue is the link to the new issue, filled in.
profile list
Section titled “profile list”{profiles: [{id, name, description, entries}]}, id being what run
takes (profile-dev-box).

