This page covers apus plugins list, its options and discovery diagnostics, and the machine-managed plugin index that backs it.

List

apus plugins list
apus plugins list --enabled
apus plugins list --verbose
apus plugins list --json
--enabled boolean

Show only enabled plugins.

--verbose boolean

Switch from the table view to per-plugin detail lines with format/source/origin/version/activation metadata.

--json boolean

Machine-readable inventory plus registry diagnostics and package dependency install state.

plugins list reads the persisted local plugin registry first, with a manifest-only derived fallback when the registry is missing or invalid. It is useful for checking whether a plugin is installed, enabled, and visible to cold startup planning, but it is not a live runtime check of an already-running Gateway process. After editing plugin code, run plugins reload <id> against the Gateway that serves the channel before expecting new register(api) code or hooks to run. The default hybrid reload mode also applies plugin config and discovery-path changes; the admin plugins.refresh RPC explicitly refreshes the inventory when passive reload is disabled.

plugins list --json includes each plugin's dependencyStatus from package.json dependencies and optionalDependencies. Apus checks whether those package names are present along the plugin's normal Node node_modules lookup path; it does not import plugin runtime code, run a package manager, or repair missing dependencies.

If startup logs plugins.allow is empty; discovered non-bundled plugins may auto-load: ..., run apus plugins list --enabled --verbose or apus plugins inspect <id> with a listed plugin id to confirm the plugin ids and copy trusted ids into plugins.allow in apus.json. When the warning can list every discovered plugin, it prints a ready-to-paste plugins.allow snippet that already includes those ids. If a plugin loads without install/load-path provenance, inspect that plugin id, then either pin the trusted id in plugins.allow or reinstall the plugin from a trusted source so Apus records install provenance.

For bundled plugin work inside a packaged Docker image, bind-mount the plugin source directory over the matching packaged source path, such as /app/extensions/synology-chat. Apus discovers that mounted source overlay before /app/dist/extensions/synology-chat; a plain copied source directory remains inert, so normal packaged installs still use compiled dist.

For runtime hook debugging:

Plugin index

Plugin install metadata is machine-managed state, not user config. Installs and updates write it to the shared SQLite state database under the active Apus state directory. The config_machine_state value keyed by plugins.installedIndex stores durable installRecords metadata, including records for broken or missing plugin manifests, plus a manifest-derived cold registry cache used by apus plugins update, uninstall, diagnostics, and the cold plugin registry.

An unreadable index is not invalid data. Permission, lock, and other read errors stop fallback, migration, and refresh with the original error. Restore database access, then rerun apus plugins registry to inspect the state before attempting repair. Do not delete the plugins.installedIndex row unless inspection succeeds and confirms invalid install records; a failed read alone does not justify deletion.

When upgrading a legacy plugin index through state schema 13, malformed JSON or an unexpected JSON shape no longer discards the installation ledger. The migration preserves the complete original row in diagnostic_events under plugins.installedIndex.quarantine, records a warning, and continues. Valid install records remain available even when derived registry metadata is damaged. Run apus doctor --fix or apus plugins registry --refresh to rebuild that metadata. Invalid install records remain marked invalid and require recovery from the preserved row or a verified backup; they are never treated as an empty installation. Recovery records survive reopening and ordinary diagnostic retention. If preservation fails, the migration rolls back and leaves the legacy row intact.

plugins.installs is a retired authored-config surface. Runtime and update commands read only the SQLite machine-state plugin index. Run apus doctor --fix to import legacy config records into the index and remove the retired key before normal runtime use.