@altnautica/plugin-sdk (v1.3.0, GPL-3.0-or-later) is the GCS-half
SDK: the package a plugin’s Mission Control side imports. A plugin’s GCS
half always uses it; its agent half uses the
Python SDK or the
Rust SDK.
The SDK hides the postMessage envelope and gives you a typed
PluginContext.
Install
The package is not published to npm. Develop your plugin inside thealtnautica/ADOSExtensions
monorepo as a pnpm workspace member; the scaffolder pins the SDK to
workspace:^ against the in-tree
packages/plugin-sdk.
Your first plugin walks through the
clone and scaffold flow.
The package ships ESM only, with no runtime dependencies, and four entry
points:
definePlugin
The single entry point:
mount is called once the bundle loads. A throw is not reported to the
host, so catch errors and render your own error state. info is
{ id, version } from your definePlugin call. Before Mission Control
destroys the frame it asks the plugin to unmount and waits up to 500 ms;
keep unmount short and do not rely on it to persist state. See
Lifecycle.
definePlugin returns a PluginInstance with info, ctx and an
unmount() you can call for your own teardown.
PluginContext
The argument the SDK hands to mount:
command.send and mission.write wait for the operator’s decision
rather than a fixed deadline. A denial, a command the host does not
allow, or a rate limit rejects with a HostError whose code is
refused.
events.subscribe reads one-way host pushes (video-overlay host props,
an agent plugin’s state read-back) and needs no grant. events.listen
and events.publish use the GCS plugin bus between installed plugin
panels and need event.subscribe and event.publish.
records reads and writes the plugin’s own cloud collection:
list(opts), get(collection, key), put(collection, key, data) and
remove(collection, key).
definePlugin builds the context for you. To build one by hand (in a
test, for example), use createPluginContext:
Wrappers and the bridge methods they call
Each wrapper delegates to onePluginClient call. The wire methods and
their capabilities are on GCS bridge methods.
For any other method, call
ctx.client.request(method, capability, args).
PluginClient
The lower-level RPC client:
request(method, capability, args, options?): send a request and await the response. Default timeout 5 s.on(method, handler): subscribe to host-pushed events.subscribeTelemetry(topic, handler): does both the subscribe request and thetelemetry.<topic>listener.dispose(): tear down listeners and reject in-flight requests.
capability.token event (CAPABILITY_TOKEN_EVENT), so token rotation
needs no plugin code. A request the host refuses with
capability_denied:token_missing is held and sent again once the first
token arrives. The capability argument is typed with the
CapabilityId union of every known id.
HostError
Thrown when the host returns an error envelope:
code; the message is for humans. The codes are listed on
GCS bridge methods.
Other exports
contributesModel: an identity helper that types acontributesliteral (editor autocomplete and a compile-time shape check) and returns it unchanged, for manifest fixtures and codegen.validateValue,clampValue,inferWidget,resolveBinding,defaultFor,PARAMETER_WIDGETS,PARAMETER_BINDINGS: the parameter schema helpers. See Parameter schema.createWindowTransport,MemoryTransport: the transports underPluginClient.PROTOCOL_VERSION,TELEMETRY_TOPICSand the envelope, telemetry, perception, records and contribution types.
Test harness
- mounts the plugin against an in-memory transport (no real iframe);
- records every request in
harness.calls, withharness.notificationsandharness.recordingMarksas shortcuts; - pushes host traffic with
pushTelemetry,pushEvent,pushConfig,pushThemeandpushPerceptionDetection, and stubs reads withstubPerceptionTierandstubPerceptionHealth; - simulates host failures with
failNext(method, code, message); - gates calls by capability like the bridge: a telemetry subscription
needs its topic grant (
telemetry.subscribe.<topic>), and aui.slot.*RPC needs that slot’s capability.
Building the bundle
The SDK has no build step of its own. Thecreate-ados-plugin templates
use esbuild:
gcs/, the output is gcs/plugin.bundle.js, the path the
manifest’s gcs.entrypoint names. The bundle is not hashed in the
manifest; the archive signature covers it.
Next steps
Your first plugin
Build, test, sign and install a GCS-only tab.
GCS bridge methods
The wire methods, pushed events and error codes.