@cwe-platform/plugin-sdk
v0.1.3
Published
CasinoWebEngine plugin SDK — the complete, contract-only surface for building CWE plugins (manifest, PluginContext, routes, datasets, jobs, migrations) plus an in-memory test harness under ./testing.
Maintainers
Readme
@cwe-platform/plugin-sdk
The official SDK for building CasinoWebEngine (CWE) plugins — the complete, contract-only
surface a plugin may touch, plus a full in-memory test harness under ./testing. You never see
(or need) the platform's core: no database, no message bus, no wallet internals.
pnpm add @cwe-platform/plugin-sdk zodzod is a peer dependency — your plugin and the host share one instance.
Quickstart
import { definePlugin, settingsField, type PluginManifest } from "@cwe-platform/plugin-sdk";
import { z } from "zod";
const manifest: PluginManifest = {
key: "my-plugin",
name: "My Plugin",
author: "me",
version: "0.1.0",
kind: "integration",
runtimeCompat: ">=0.1.0 <0.2.0",
permissions: {
commands: [], // command allowlist (fail-closed)
events: { subscribe: [], emit: ["plugin.my-plugin.something_happened"] },
},
settings: { fields: { greeting: settingsField.string({ label: "Greeting" }) } },
datasets: {
notes: { schema: z.object({ noteKey: z.string(), text: z.string() }), keyField: "noteKey" },
},
routes: [{ method: "GET", path: "/notes", surface: "player", handler: "list-notes" }],
};
export default definePlugin({
manifest,
handlers: {
routes: {
"list-notes": async (req, ctx) => {
const notes = ctx.datasets.collection("notes");
const page = await notes.query({ limit: 50 });
return { body: { notes: page.records, player: req.player!.id } };
},
},
},
});Everything a plugin can do flows through the PluginContext (ctx):
| Capability | Surface | Gate |
|---|---|---|
| change core state | ctx.commands.execute | manifest command allowlist |
| read core data | ctx.data.query | manifest dataScopes (PII is a separate grant) |
| own data | ctx.datasets | declared datasets; schema-validated, quota-capped |
| events out | ctx.events.emit | namespaced plugin.<key>.*, declared |
| events in | ctx.events.on | declared subscriptions |
| call external APIs | ctx.http.fetch | network.allowedHosts, HTTPS only, secrets injected host-side |
| background work | ctx.tasks.start | task handlers, checkpoint-resumable |
| config / credentials | ctx.settings / ctx.secrets | typed schema; secrets write-only, never logged |
Everything not declared in the manifest is denied — at runtime and in your tests.
Testing (/testing)
import { createTestContext, validateManifest } from "@cwe-platform/plugin-sdk/testing";
import plugin from "./src/index.js";
const { ctx, harness } = createTestContext({
definition: plugin,
settings: { greeting: "hi" },
secrets: { apiKey: "test-key" },
commandResults: { "wallet.bet.place": { transactionId: "t1", legs: [] } },
httpMock: () => ({ status: 200, json: { ok: true } }),
});
await harness.invokeRoute("POST /notes", { player: { id: "p1" }, body: { text: "gg" } });
harness.commands; // every command the plugin dispatched
harness.events; // every event it emitted
harness.httpExchanges; // outbound calls — secret headers shown as <redacted:name>
await harness.runJob("cleanup");
await harness.runMigration("0.2.0");
validateManifest(plugin); // doctor-lite: handler refs, cron, datasets, surfacesThe mock enforces exactly what the real host enforces (same error names/codes); the platform runs a conformance suite against both on every change.
Versioning — the runtime contract
The SDK's major.minor is the platform's RUNTIME_API_VERSION (patch releases are free). Your
manifest's runtimeCompat range must include the SDK minor you compiled against:
SDK 0.1.x → runtimeCompat: ">=0.1.0 <0.2.0"npm dist-tags mirror the platform's release channels: latest = stable, next = beta,
dev = dev.
Dev loop
Start from the plugin template (a working player-favorites example with tests), then:
docker compose -f docker-compose.plugindev.yml up # local CWE runtime (from the platform repo)
npx @cwe-platform/plugin-cli dev # watch → build → hot-reload sideload
npx @cwe-platform/plugin-cli validate # full plugin doctor on the runtimeMIT © CasinoWebEngine
