153 lines
5.7 KiB
Markdown
153 lines
5.7 KiB
Markdown
# Plugin CLI Reference
|
|
|
|
`hivegrid-cli plugins ...` — the author + operator command surface
|
|
for the plugin pipeline. Operator subcommands manage installed-plugin
|
|
rows; author subcommands scaffold / build / sign / lint / publish.
|
|
|
|
```bash
|
|
hivegrid-cli plugins --help
|
|
```
|
|
|
|
## Author subcommands
|
|
|
|
### `scaffold`
|
|
|
|
```bash
|
|
hivegrid-cli plugins scaffold \
|
|
--name slack-notifier \
|
|
--publisher de.acme \
|
|
--description "Send tenant events to Slack" \
|
|
[--target-dir ./my-plugins] [--dry-run]
|
|
```
|
|
|
|
Generates a new plugin skeleton under `<targetDir>/<name>/`:
|
|
|
|
```
|
|
slack-notifier/
|
|
├── plugin.toml # manifest seed (placeholder sig/hash)
|
|
├── src/index.ts # HookHandler example
|
|
├── package.json # @hivegrid/plugin-sdk devDependency
|
|
├── tsconfig.json # ES2022 strict
|
|
└── README.md # next-step checklist
|
|
```
|
|
|
|
`--dry-run` prints the file list without writing anything.
|
|
|
|
### `build`
|
|
|
|
```bash
|
|
hivegrid-cli plugins build [--cwd ./slack-notifier] [--output plugin.wasm]
|
|
```
|
|
|
|
Detects the project's wasm toolchain (AssemblyScript via `asconfig.json`,
|
|
TinyGo via `go.mod`, Rust via `Cargo.toml`) and prints the canonical
|
|
build command. Does NOT auto-execute — pipe the command into your CI or
|
|
run it yourself. Exits non-zero when no toolchain marker is found.
|
|
|
|
### `sign`
|
|
|
|
```bash
|
|
hivegrid-cli plugins sign \
|
|
--wasm plugin.wasm \
|
|
--manifest plugin.json \
|
|
--key ./keys/publisher.priv \
|
|
[--key-id staging-2026-05] \
|
|
[--out-sig plugin.wasm.sig]
|
|
```
|
|
|
|
1. SHA-256-hashes the wasm.
|
|
2. Builds the same canonical manifest projection used by the runtime verifier
|
|
(sorted-keys JSON minus `signature`/`signedBy`/`wasmSha256`).
|
|
3. Signs `<canonical>:<wasmSha256>` with the ed25519 private key.
|
|
4. Writes the raw signature hex to `<wasm>.sig` (or `--out-sig`).
|
|
5. Prints the `wasmSha256` / `signature` / `signedBy` lines to splice
|
|
back into the manifest.
|
|
|
|
The private key is read from disk and never echoed. `--key-id` is
|
|
logged only — useful for operators to track which signing key produced
|
|
which artifact.
|
|
|
|
### `lint`
|
|
|
|
```bash
|
|
hivegrid-cli plugins lint --manifest plugin.json
|
|
```
|
|
|
|
Runs the host Zod schema, then layers author checks on top:
|
|
|
|
- `manifest_invalid` (error) — Zod rejected the manifest.
|
|
- `unknown_capability` (error) — capability not in the host registry.
|
|
- `invalid_host` (error) — `allowedHosts` entry is not a hostname.
|
|
- `unsigned_placeholder` (warn) — signature/signedBy still zeros.
|
|
- `unsigned_wasm` (warn) — wasmSha256 still zeros.
|
|
- `http_outbound_unrestricted` (warn) — `http.outbound` declared but
|
|
`allowedHosts` is empty.
|
|
- `high_risk_capability` (warn) — `db.write` declared.
|
|
|
|
Exit codes:
|
|
|
|
| Code | Meaning |
|
|
| ---- | -------------------- |
|
|
| 0 | Clean |
|
|
| 1 | At least one error |
|
|
| 2 | Warnings only |
|
|
|
|
### `publish`
|
|
|
|
```bash
|
|
hivegrid-cli plugins publish \
|
|
--wasm plugin.wasm \
|
|
--manifest plugin.json \
|
|
[--signature plugin.wasm.sig] \
|
|
[--out ./dist]
|
|
```
|
|
|
|
Packs `plugin.wasm` + `plugin.json` (+ `plugin.wasm.sig` if present)
|
|
into `<pluginId>-<version>.tar.gz` ready for operator upload.
|
|
**Local-only — no HTTP push.** Operators must inspect what they
|
|
upload; auto-uploading would hide bad signatures from review.
|
|
|
|
## Operator subcommands
|
|
|
|
| Command | Action |
|
|
| ---------------------------- | -------------------------------------------------------------- |
|
|
| `plugins list --tenantId <id>` | List installed plugin rows for one tenant (optional enabled-state filter) |
|
|
| `plugins enable <tenantId> <pluginId>` | Enable an installed plugin |
|
|
| `plugins disable <tenantId> <pluginId>` | Disable an installed plugin |
|
|
| `plugins uninstall <tenantId> <pluginId>` | Operator-only deletion of the tenant Plugin row (cascades user configs) |
|
|
| `plugins verify-audit-chain <tenantId> [--pluginId <pluginId>] [--from <iso>] [--to <iso>] [--json]` | Verify the tenant-wide PluginCapabilityUse hash chain; `--pluginId` reports matching rows without slicing the chain |
|
|
|
|
These operate against the host database directly; they are intended
|
|
for incident-response and don't substitute the tenant-admin UI. Uninstall is
|
|
deliberately available only through this operator CLI path until plugin-owned
|
|
data cleanup/down-migration semantics are reviewed.
|
|
|
|
Operator lifecycle commands use the same production gates as the service path:
|
|
production enables require `PLUGIN_RUNTIME_PRODUCTION_ENABLED=true`, reject
|
|
`PLUGIN_REQUIRE_CAPABILITY_CONSENT=false`, reject capabilities whose host
|
|
bindings are not production-reviewed, check current grants before enabling, and
|
|
write lifecycle audit events transactionally with the mutation. Disable remains
|
|
available as the emergency containment path.
|
|
|
|
Permission split: tenant routes and UI use `app.plugins.use` for installed
|
|
plugin reads, per-user non-secret settings, and settings/audit surfaces.
|
|
`app.plugins.manage` is still required for tenant API/UI install,
|
|
grant/revoke, enable/disable, and future update flows. CLI commands are operator
|
|
escape hatches against the host database and do not replace the tenant
|
|
permission model; CLI uninstall is not exposed as a tenant permissioned
|
|
API/UI flow.
|
|
|
|
## Round-trip smoke
|
|
|
|
```bash
|
|
hivegrid-cli plugins scaffold --name smoke --publisher de.smoke --dry-run
|
|
hivegrid-cli plugins build --cwd ./smoke
|
|
# (run the printed build command in your wasm toolchain)
|
|
hivegrid-cli plugins lint --manifest ./smoke/plugin.json
|
|
hivegrid-cli plugins sign --wasm ./smoke/plugin.wasm --manifest ./smoke/plugin.json --key ./keys/dev.priv
|
|
hivegrid-cli plugins publish --wasm ./smoke/plugin.wasm --manifest ./smoke/plugin.json
|
|
```
|
|
|
|
The output is the file you upload through the tenant-admin plugins
|
|
settings page.
|