JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 252
  • Score
    100M100P100Q149337F
  • License SEE LICENSE IN LICENSE

VibeControls Plugin SDK — shared contract, lifecycle, CLI, telemetry, storage helpers for all vibe-plugin-* packages.

Package Exports

  • @vibecontrols/plugin-sdk
  • @vibecontrols/plugin-sdk/audit
  • @vibecontrols/plugin-sdk/broadcast
  • @vibecontrols/plugin-sdk/cli
  • @vibecontrols/plugin-sdk/config
  • @vibecontrols/plugin-sdk/contract
  • @vibecontrols/plugin-sdk/http
  • @vibecontrols/plugin-sdk/lifecycle
  • @vibecontrols/plugin-sdk/log
  • @vibecontrols/plugin-sdk/providers
  • @vibecontrols/plugin-sdk/routes
  • @vibecontrols/plugin-sdk/storage
  • @vibecontrols/plugin-sdk/subprocess
  • @vibecontrols/plugin-sdk/telemetry
  • @vibecontrols/plugin-sdk/testing

Readme

@vibecontrols/plugin-sdk

Shared contract, lifecycle, CLI, telemetry, storage, and HTTP helpers consumed by every @vibecontrols/vibe-plugin-* package and by the agent itself.

Install

bun add @vibecontrols/plugin-sdk
# or
npm install @vibecontrols/plugin-sdk

Modules

Granular subpath imports so plugins tree-shake aggressively. The most-used helpers are also re-exported from the root barrel @vibecontrols/plugin-sdk.

contract — types

The plugin contract v2 surface. VibePlugin, HostServices, PluginCapabilities, Prerequisite, StorageProvider, ServiceRegistry, plus FULL_TRUST_CAPS. Every host-side field is optional so plugins keep working against partial hosts.

import type { VibePluginFactory, VibePlugin } from "@vibecontrols/plugin-sdk/contract";

export const createPlugin: VibePluginFactory = (ctx) => ({
  name: "demo",
  version: "1.0.0",
  capabilities: { storage: "rw", telemetry: true },
  tags: ["backend"],
});

lifecycle — boilerplate-free init / shutdown

createLifecycleHooks collapses onServerStart / onServerStop boilerplate, emits a one-shot <plugin>.ready telemetry event, and skips on unsupported platforms.

import { createLifecycleHooks } from "@vibecontrols/plugin-sdk/lifecycle";

const { onServerStart, onServerStop } = createLifecycleHooks({
  name: "demo",
  telemetryEventName: "demo.ready",
  onInit: async (hostServices) => {
    /* ... */
  },
});

cli — multimode + redaction + command builder

runMultimode<T> selects between JSON / plain / interactive renderers from a single fetchData call. redact(value) strips secrets recursively. CliCommandBuilder registers status sub-commands with --json / --plain baked in.

import { CliCommandBuilder, redact } from "@vibecontrols/plugin-sdk/cli";

new CliCommandBuilder(program).addStatusCommand("status", {
  description: "Show plugin status",
  fetchData: () => fetchStatus(),
  redact: true,
});

routes — Elysia fluent builder

import { RoutesBuilder } from "@vibecontrols/plugin-sdk/routes";

const app = new RoutesBuilder("demo", hostServices)
  .withPrefix("/api/demo")
  .withAuth(() => process.env.AGENT_API_KEY ?? "")
  .withErrorHandler()
  .withLogging()
  .build();

app.get("/ping", () => ({ ok: true }));

telemetry — auto-tagged emitter

import { TelemetryEmitter } from "@vibecontrols/plugin-sdk/telemetry";

const tel = new TelemetryEmitter("demo", "1.0.0", hostServices);
tel.emitReady({ port: 3005 });
tel.emitError(new Error("boom"));

log — source-bound logger

import { BoundLogger } from "@vibecontrols/plugin-sdk/log";

const log = new BoundLogger(hostServices.logger, "demo");
log.info("started", { port: 3005 });

storage — typed JSON-encoded helpers

import { TypedStore, NamespaceStore } from "@vibecontrols/plugin-sdk/storage";

const ns = new NamespaceStore(hostServices.storage!, "demo");
const settings = ns.typed<{ enabled: boolean }>("settings");
await settings.set({ enabled: true });
const current = await settings.get();

config — env + host config + defaults

import { ConfigManager } from "@vibecontrols/plugin-sdk/config";

const cfg = new ConfigManager("demo", hostServices, hostServices.logger);
const port = (await cfg.getInt("port", 3005))!;
const apiKey = await cfg.getRequired("api_key"); // throws if missing

subprocess — cross-platform process helpers

import {
  gracefulKill,
  isProcessAlive,
  findAvailablePort,
  sleep,
} from "@vibecontrols/plugin-sdk/subprocess";

const port = await findAvailablePort(7000);
await gracefulKill(child.pid, 3000);

http — HttpClient with retries + timeout

import { HttpClient } from "@vibecontrols/plugin-sdk/http";

const client = new HttpClient("https://api.example.com", { timeoutMs: 5000 });
const data = await client.get<{ ok: boolean }>("/v1/status");

providers — ProviderRegistry façade

import { ProviderRegistry } from "@vibecontrols/plugin-sdk/providers";

const reg = new ProviderRegistry(hostServices);
reg.registerProvider("tunnel", "cloudflare", myCloudflareProvider);
const all = reg.listProviders("tunnel");

audit — bound source emitter

import { AuditLogger } from "@vibecontrols/plugin-sdk/audit";

const audit = new AuditLogger("demo", hostServices);
audit.emit("started", { port: 3005 });

broadcast — typed WebSocket emitter

import { BroadcastEmitter } from "@vibecontrols/plugin-sdk/broadcast";

new BroadcastEmitter(hostServices).broadcast("demo.event", { count: 1 });

testing — Bun-mock factories

Run with bun test (depends on the runtime bun:test import).

import { createMockHostServices, createMockProfileContext } from "@vibecontrols/plugin-sdk/testing";

const hs = createMockHostServices({ getAgentVersion: () => "test" });
const ctx = createMockProfileContext();

Compatibility Matrix

SDK version Agent version Plugin contract
2026.509.x >=2026.509.1 v2 (createPlugin factory)

Boilerplate

Downstream plugins can extend the shared configs in boilerplate/:

  • tsconfig.base.json — strict TS + ESM
  • eslint.config.base.js — no-any, no-eslint-disable, max-warnings 0
  • lefthook.base.yml — pre-push sanity gate
  • bunfig.toml — Verdaccio scope wiring
  • .github/workflows/release.template.yml — CalVer publish pipeline
  • package.template.json — minimal starter package.json

See templates/plugin-scaffold.md for the recommended layout.

Contributing

  1. bun install
  2. bun run sanity must be green (0 errors, 0 warnings)
  3. Trunk-based: main only. CalVer release via gh workflow run release.yml -f version=YYYY.MDD.PATCH.
  4. Spec: ~/products/vibecontrols/vibecontrols-specs/architecture/PLUGIN_SDK_EXTRACTION.md

License

Proprietary — Burdenoff Consultancy Services Pvt. Ltd. See LICENSE.