@nullplatform/plugin
v0.0.4
Published
<h2 align="center"> <a href="https://nullplatform.com" target="blank_"> <img height="100" alt="Nullplatform" src="https://nullplatform.com/favicon/android-chrome-192x192.png" /> </a> <br> <br> @nullplatform/plugin <br> </h2
Downloads
1,607
Readme
TypeScript SDK for building nullplatform plugins. Handles transport (gRPC
go-plugin and subprocess-exec), action routing, action lifecycle reporting,
--describe, and --publish.
Install
bun add @nullplatform/pluginLayers
The SDK is layered so the stable core is insulated from today's rough platform APIs:
- base — the plugin runtime, transport (gRPC + subprocess-exec), and the action-lifecycle protocol. Stable.
- compat (
src/compat/) — temporary shims for current APIs: token exchange, actionPATCHshapes. Each is deletable in isolation once the real API lands. - goal layers —
defineScopetoday;defineService,defineHooknext.
Usage
Scope plugin
import { defineScope } from "@nullplatform/plugin/scope";
defineScope({
name: "kubernetes-k3d",
version: "0.0.1",
category: "containers",
provider: "kubernetes",
schema: {
type: "object",
properties: {
memory: { type: "string", default: "2Gi" },
},
},
// Optional — how the platform routes actions to your worker. Defaults:
// selector { package: <name> }, entrypoint /app/packages/<name>/entrypoint,
// and channel sources DERIVED from your actions ("service", plus "telemetry"
// when you declare data-fetch actions like log:read). All overridable —
// sources are free-form; the notifications API is the validator.
agent: {
selector: { package: "kubernetes-k3d" },
// sources: ["service", "telemetry", "approval"],
},
actions: {
"create-scope": {
input: { type: "object" },
handler: async (notification, emit) => {
emit({ stdout: "Provisioning…" }); // live message on the action + worker logs
// provision infrastructure
return { domain: "app.k3d.local" }; // becomes the action results
},
},
},
});Actions
handler is a plain async (notification, emit) => result (or a workflow
chain). The SDK reports the action lifecycle automatically: in_progress on
start, success with your returned object, or failed on throw. emit({ stdout
}) streams a live message onto the action in the UI.
Well-known action slugs get their metadata (name, type, retryable, lifecycle)
for free — create-scope, delete-scope, update-scope, start-initial,
start-blue-green, switch-traffic, finalize-blue-green,
rollback-deployment, delete-deployment, diagnose-scope,
diagnose-deployment, kill-instances, restart-pods, pause-autoscaling,
resume-autoscaling, set-desired-instance-count. For a custom action, use
any slug and declare name/type inline:
"say-hello": { name: "Say Hello", type: "custom", input, handler },Transport
Agents run the compiled plugin directly (subprocess-exec): the action arrives in
NP_ACTION_CONTEXT, the plugin runs it, reports status, prints the result, and
exits. The gRPC go-plugin server is also supported for hosts that use it. You
write handlers; the SDK picks the transport.
Simple plugin (custom command)
import { createPlugin, registerManifest } from "@nullplatform/plugin";
registerManifest({ name: "my-plugin", version: "0.0.1", command_types: ["custom"] });
createPlugin({
async execute(req) {
return { success: true, data: { message: "done" } };
},
}).start();Subpath exports
| Import | Description |
|---|---|
| @nullplatform/plugin | Core: createPlugin, registerManifest, types |
| @nullplatform/plugin/scope | defineScope API |
| @nullplatform/plugin/schema | JSON Schema type inference |
| @nullplatform/plugin/testing | Test harness: startPluginProcess, factories |
| @nullplatform/plugin/workflow | Workflow integration (StreamingExecutionObserver) |
CLI integration
Packages are scaffolded and driven with the np package commands, which are
thin wrappers over the template's own tasks:
np package init # scaffold from a git template
np package dev # local dev UI + hot reload (→ mise/bun run dev)
np package test # run tests (→ mise/bun run test)
np package build --image # build the worker image
np package run # run the worker as a real local agent (docker)
np package publish # register on the platform (specs + channel + artifact)publish reads the manifest from --describe, so the SDK owns the manifest
shape and the CLI stays decoupled from it. See the CLI's docs/packages.md.
