- Events: pushed from the host, no response expected
(
config.changed,theme.changed,telemetry.<topic>). - Responses: returned by the host in reply to a plugin request.
Events the host pushes
| Method | Capability | Args | When |
|---|---|---|---|
theme.changed | theme.useTheme | Record<string, string> of CSS variables | Initial mount; whenever the host theme changes. |
config.changed | none | the plugin’s full config object | Operator saves a new config under Settings -> Plugins. |
telemetry.<topic> | telemetry.subscribe.<topic> | topic-specific payload | After the plugin called telemetry.subscribe. |
lifecycle.tick | none | { uptimeMs } | Once a minute while the plugin is running. |
recording.started | none | { recordingId, startedAtMs } | Operator starts a recording. |
recording.stopped | none | { recordingId, durationMs } | Operator stops a recording. |
ctx.client.on("config.changed", handler) or via the
typed wrappers on ctx.config.onChange, ctx.theme.onChange, etc.
Requests the plugin can send
Every RPC carries{ method, capability, args }. The host
re-resolves the required capability from method and args and
checks the granted set. The plugin never has to compute the
capability id itself.
| Method | Capability | Args | Returns |
|---|---|---|---|
telemetry.subscribe | telemetry.subscribe.<topic> | { topic } | { ok } |
telemetry.unsubscribe | derived | { topic } | { ok } |
command.send | command.send | { command, args } | host-defined |
mission.read | mission.read | { missionId } | mission body |
mission.write | mission.write | { missionId, payload } | { ok, version } |
notification.publish | ui.slot.notification | { channelId, severity, title, body, meta } | { ok } |
recording.mark | recording.write | { label, meta } | { ok } |
event.publish | event.publish | { topic, payload } | { ok } |
event.subscribe | event.subscribe | { topic } | { ok } |
Wire shape
PluginClient
generates the id, attaches the protocol version, and waits for the
correlated response.
Error envelopes
When the host rejects a request it returns a response witherror: { code, message }. The SDK throws a HostError whose code
field carries the machine-readable error code:
| Code | Meaning |
|---|---|
permission_denied | The required capability is not in the granted set. |
method_unknown | The method is not in the host’s registry. |
schema_invalid | Args failed schema validation. |
handler_unset | The host knows the method but no handler is wired. |
handler_error | The host’s handler threw. The message is the thrown error’s message. |
code, not on message. Messages are for
log lines.
Theming
theme.changed arrives once on mount and again on every theme
toggle. The payload is a Record<string, string> of CSS variables.
Apply them by walking the entries:
i18n
Plugin authors ship a locale bundle in their archive; the host streams the active bundle to the plugin on mount. The SDK formats keys withctx.i18n.t(key, params):
{name} placeholder so it is visible in QA.