- hermes_cli/plugins_cmd_catalog.py: new sibling owning resolution, the
.hermes-catalog.json provenance sidecar, search/info/validate, re-pin on
update, and the dashboard/TUI payload builders. plugins_cmd.py only
gains the hooks (cmd_install catalog branch, cmd_update / dashboard
update re-pin, dashboard_install_plugin catalog_name + kill list,
dispatch entries); the community index (plugin_index.py) is gone.
- hermes_cli/plugin_catalog.py: catalog_dir parameter replaces the
test-only HERMES_PLUGIN_CATALOG_DIR env var; live refresh reads ONE
published document (/docs/api/plugin-catalog.json, 6h cache, in-tree
fallback) instead of the unauthenticated GitHub contents API (60 req/h,
1 request per entry); in-tree and live removals are unioned so a stale
cache can never un-block.
- Catalog route lives in web_routers/dashboard_ui.py (the facade is off
limits); _plugin_runtime_status shared from web_server_dashboard.py;
hub rows carry removed_reason. TUI plugins.manage gains catalog_name
install, catalog row fields and an update action.
- plugin_validate: the probe context honours ctx.get_config defaults
(real plugins do int(ctx.get_config("timeout", 180)) in register()).
- Installed-state merge matches through the sidecar's catalog_name
first — catalog names rarely equal manifest names.
- extract-plugins.py emits plugin-catalog.json; deploy-site triggers on
plugin-catalog/** so entry merges republish it.
- Capabilities gains a 4th tab (Plugins): the scoped (connection, profile)'s
installed agent plugins with toggles, and the live docs-site plugin catalog
embedded underneath (?embed=picker) — same shape as the Skills hub.
- '+ Add to this Agent' on a catalog card opens the existing dual-target
install modal: the agent half installs at the catalog's reviewed pin into
the scoped profile (plugins.manage catalog_name= passthrough), the desktop
half installs locally; bundled agent+desktop packages offer both in one flow.
- Settings > Plugins: desktop halves of bundled packages get an
'agent half missing here' badge when the currently connected backend/profile
lacks the agent component — the one-app/N-agents drift is now visible.
- Docs /plugins page: picker embed mode (chrome hidden, pick button posts
hermes-plugin-pick), subdir carried through the extractor.
- Gateway plugins.manage install accepts catalog_name (resolved server-side
against the backend's own catalog; removed-blocklist enforced, no bypass).