Skip to main content

Module plugin_cli

Module plugin_cli 

Source
Expand description

The bamboo plugin install|list|remove|update CLI: a thin HTTP client over a running bamboo serve instance’s /api/v1/plugins routes. The bamboo plugin install|list|remove|update CLI — a thin HTTP client over a running bamboo serve instance’s /api/v1/plugins routes.

Mirrors the bamboo mcp ... verb pattern in crate::admin_cli: this module only builds request bodies, resolves the base URL (via the shared [ConnArgs]) and pretty-prints responses. The server (built in parallel against the same frozen contract) is the single source of truth for whether an install/update/remove actually succeeds.

Wire contract (frozen — see PLUGIN_PLAN.md §“2. CLI agent” / §“3. HTTP agent”):

  • GET /api/v1/plugins -> { "plugins": [ { id, name?, version, source, status, registered: { mcp_server_ids, preset_ids, skill_dirs, workflow_filenames } } ] }
  • POST /api/v1/plugins/install -> body { "source": <SourceSpec> } (InstallDisposition::FailIfInstalled); SourceSpec is one of {"type":"local_dir","path":"..."} / {"type":"local_archive","path":"..."} / {"type":"url","url":"...","sha256":"..."?,"allow_unverified":bool?, "allow_untrusted_host":bool?,"allow_unsigned":bool?,"insecure":bool?} — the same tagged shape as bamboo_plugin::registry::PluginSource’s #[serde(tag = "type")] wire form, reproduced here by hand (this crate does not depend on bamboo-plugin, to stay decoupled from the parallel installer-core branch).
  • POST /api/v1/plugins/{id}/update -> same body shape (Upgrade).
  • DELETE /api/v1/plugins/{id} -> uninstall.
  • Errors: 409 (Conflict / AlreadyInstalled), 422 (UnsupportedPlatform), 404 (NotFound), 403 (url source: untrusted host / unsigned-or-untrusted signature), 400 (bad manifest/artifact/bundle checksum, or a url install missing both sha256 and allow_unverified); body {"error": "..."}.

§URL installs: three trust layers, secure by default

A url source is checked against three independent, stacked layers (see bamboo-server’s plugin_source.rs module docs for the full precedence):

  1. Host allowlist — the URL’s host+path must match an operator-trusted prefix (plugin_trust.trusted_hosts in config.json; the default trusts github.com/bigduu/) unless --allow-untrusted-host is passed.
  2. Signature — the bundle’s <url>.sig must verify against an operator-trusted ed25519 key (plugin_trust.trusted_keys; the default trusts nova’s official signing key) unless --allow-unsigned is passed.
  3. Checksumsha256 pins the downloaded BUNDLE (the plugin.json, or the archive containing it) — NOT merely the per-platform binary artifact declared inside the manifest (that is separately, and always, sha256-verified against the manifest’s own declaration). A url install with neither sha256 nor allow_unverified: true is refused UNLESS layer 2 already verified a signature (a verified signature is a stronger integrity+authenticity guarantee than a pasted checksum, so it satisfies this layer on its own).

Net effect: installing the OFFICIAL nova plugin from its GitHub release needs NO flags at all once nova’s release CI signs the bundle (trusted host + verified signature). An install from an untrusted host or an unsigned/untrusted-signature bundle needs the matching explicit opt-out flag(s) — bamboo plugin install <url> alone no longer just downloads and trusts any tar.gz from any host.

§--insecure: skip ALL three layers at once

--insecure (install/update) is a convenience AGGREGATE over the three flags above — equivalent to passing --allow-untrusted-host --allow-unsigned --allow-unverified together, for the one install it’s given on. It only turns default-required checks OFF: a --sha256 passed alongside --insecure is still verified (a mismatch still refuses the install) — the flag never downgrades a check the caller explicitly opted into. There’s also a persistent, config-level form for a private/dev bamboo instance that never wants to pass flags at all: bamboo config set plugin_trust.enforcement off makes EVERY url install/update behave this way with no per-install flag needed (plugin_trust.enforcement defaults to "strict", so this is always an explicit opt-in relaxation). Use either only for sources you fully trust (dev/self-hosted/custom setups) — the server logs a prominent warning for every insecure install (plus its own startup warning when plugin_trust.enforcement is off) and records the aggregate in provenance, visible via bamboo plugin list --json.

Functions§

install
bamboo plugin install <path-or-url> [--sha256 <hex>] [--allow-unverified] [--allow-untrusted-host] [--allow-unsigned] [--insecure]POST /api/v1/plugins/install. On a 409 (already installed) prints a pointer to bamboo plugin update and returns an error (non-zero exit). A URL source with neither --sha256 nor --allow-unverified gets a 400 from the server (secure by default — see the module docs); a URL from a host outside plugin_trust.trusted_hosts or an unsigned/untrusted-signature bundle gets a 403 (unless the matching opt-out flag, or --insecure, was passed). Every one of those error bodies is already the actionable “pass –X” guidance, surfaced as-is through the branches below.
list
bamboo plugin list [--json]GET /api/v1/plugins.
remove
bamboo plugin remove <id> [--yes]DELETE /api/v1/plugins/{id}. Destructive (stops/removes its registered MCP servers, prompt presets and workflow files, then deletes the plugin directory), so it confirms like mcp remove / session delete unless --yes.
update
bamboo plugin update <id> <path-or-url> [--sha256] [--allow-unverified] [--allow-untrusted-host] [--allow-unsigned] [--insecure]POST /api/v1/plugins/{id}/update (InstallDisposition::Upgrade). Same three-layer source-trust policy (plus the --insecure aggregate) as install (see the module docs).