ados plugin subcommand tree is the operator and developer interface
to the agent’s plugin host: install, enable, inspect, sign, and lint
plugins. This page documents all 15 subcommands, their flags, and the
exit codes every command shares.
The plugin group is not listed in ados help, but it is always
available. Run ados plugin --help on the agent for the command list,
or ados plugin <command> --help for a single command. The lifecycle
commands talk to the local agent’s /api/plugins routes, so run them on
the node.
The --json flag
Every subcommand accepts --json. With it, the command prints a single
machine envelope to stdout instead of human-readable text:
code is the process exit code (see Exit codes), kind
is the stable string form of that code, data is the per-command
payload, and hint (when present) is a suggested next step. Use the
JSON form in scripts and CI; parse .ok and .code rather than the
human text, which is not stable.
Exit codes
Everyados plugin subcommand returns one of these codes. The JSON
envelope’s kind field carries the same meaning as a string.
Lifecycle commands
list
List installed plugins.
The human table prints
ID, VERSION, STATUS, and SIGNER. With
--all, a built-in that is not installed shows status available and
signer -; install one with ados plugin install <id>. Installed
built-ins show their real status.
install
Install a plugin from a local archive, an archive URL, a built-in plugin
id, or a first-party catalog id. The command drives the agent’s native
/api/plugins routes: it previews first, asks for approval, then installs
and grants the permissions you approved.
The preview verifies the signature and validates the manifest, then prints
the plugin id, its risk level, and the permissions requested, and prompts
for approval. If you decline, nothing is installed and the command exits 0.
The install itself checks compatibility, including the node profile and
the host architecture, before anything is unpacked. A URL install is pinned
to the sha256 of the archive you reviewed; a catalog install is pinned to
the catalog’s sha256.
--yes approves the listed permissions without a prompt, but it refuses
any plugin whose risk is high or critical (exit 4); re-run those
interactively. A signature failure exits 3, a bad manifest exits 2, a
compatibility mismatch exits 8.
With --json and no --yes, the plugin installs with no permissions
granted; grant them with ados plugin perms <id> --grant <cap>, or add
--yes.
After a successful install the plugin is installed but stopped.
Enable it next:
enable
Enable an installed plugin so the host starts it.
Exits 5 if no plugin with that id is installed.
disable
Disable a plugin. It stays installed, with its grants intact, but the
host stops running it.
remove
Stop, uninstall, and forget a plugin.
Inspection commands
info
Print a manifest summary and runtime state for one plugin.
The human output lists the version, status, signer, install source, and
each permission with its grant state. Exits 5 if the id is neither
installed nor a built-in.
perms
Show, grant, or revoke permissions on an installed plugin.
With neither flag, the command lists each recorded permission as
GRANTED or DENIED. Pass --grant or --revoke, not both. A revoke
confirms intent (unless -y or --json), then takes effect at once:
the host re-mints the plugin’s token without the capability, which can
interrupt a running workload. Exits 5 if the plugin is not installed.
logs
Print or follow a plugin’s stdout and stderr log.
The command asks the agent for the log path (
GET /api/plugins/<id>),
so it always reads the file the host writes:
/var/log/ados/plugins/<id with dots as hyphens>-<hash8>.log, or
...-<hash8>-<service>.log for a declared service. An unknown
--service exits 2 and lists the declared services. Exits 5 if the log
file does not exist yet (the plugin may never have started, or its log
was rotated out).
Update commands
pin
Pin a plugin to a version so auto-update skips it.
unpin
Clear the pinned version so auto-update can run again.
auto-update
Toggle auto-update on or off for one plugin.
Developer commands
These commands run on a developer workstation against a plugin directory or a packed archive, not against installed plugins.lint
Run static analysis on a packed .adosplug archive before submission.
Exits 0 when the report passes, 1 when it carries a finding at severity
error or critical, 2 when the manifest is invalid. The full rule set
is documented under Linting.
test
Run a plugin’s pytest suite under the SDK test harness.
The command validates the manifest, sets
ADOS_PLUGIN_ID,
ADOS_PLUGIN_VERSION, ADOS_PLUGIN_ROOT, and (when declared)
ADOS_PLUGIN_TEST_FIXTURES in the environment, then shells out to
pytest so your tests run against the canonical runner. Exits 0 when
pytest passes, 1 when it fails, 2 on a bad manifest, 5 when the tests
directory is missing.
sign
Pack a plugin directory into a signed .adosplug archive.
The command packs the directory, computes the canonical payload hash
(SHA-256 over the sorted entry hashes), signs that digest with the
Ed25519 key, and writes a
SIGNATURE entry into the archive plus a
.sha256 checksum file next to it. The signing details and the
monorepo-CI alternative (pack.sh and sign.sh) are covered under
Signing keys.
keygen
Generate a fresh Ed25519 keypair for plugin signing.
Writes
<signer-id>.pem (the public key, mode 0644) and
<signer-id>.priv.pem (the private key, mode 0600) under the output
directory, and prints a SHA-256 fingerprint of the public key for
cross-checking. Install the public PEM on each agent at
/etc/ados/plugin-keys/<signer-id>.pem and keep the private half
offline.
Next steps
Lifecycle
The states these commands move a plugin through.
Signing keys
Keys for
sign and keygen, and how a node trusts them.Linting
The rules
ados plugin lint applies.Troubleshooting
What to do when a command exits non-zero.