Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
@@ -0,0 +1,152 @@
|
||||
# Plugin CLI Reference
|
||||
|
||||
`toolctrl-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
|
||||
toolctrl-cli plugins --help
|
||||
```
|
||||
|
||||
## Author subcommands
|
||||
|
||||
### `scaffold`
|
||||
|
||||
```bash
|
||||
toolctrl-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 # @toolctrl/plugin-sdk devDependency
|
||||
├── tsconfig.json # ES2022 strict
|
||||
└── README.md # next-step checklist
|
||||
```
|
||||
|
||||
`--dry-run` prints the file list without writing anything.
|
||||
|
||||
### `build`
|
||||
|
||||
```bash
|
||||
toolctrl-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
|
||||
toolctrl-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
|
||||
toolctrl-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
|
||||
toolctrl-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` | List installed plugin rows (filter by tenantId + enabled state) |
|
||||
| `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
|
||||
toolctrl-cli plugins scaffold --name smoke --publisher de.smoke --dry-run
|
||||
toolctrl-cli plugins build --cwd ./smoke
|
||||
# (run the printed build command in your wasm toolchain)
|
||||
toolctrl-cli plugins lint --manifest ./smoke/plugin.json
|
||||
toolctrl-cli plugins sign --wasm ./smoke/plugin.wasm --manifest ./smoke/plugin.json --key ./keys/dev.priv
|
||||
toolctrl-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.
|
||||
Reference in new issue
Block a user