diff --git a/packages/plugin-sdk/README.md b/packages/plugin-sdk/README.md new file mode 100644 index 0000000..4cc82ae --- /dev/null +++ b/packages/plugin-sdk/README.md @@ -0,0 +1,150 @@ +# @dorfteich/plugin-sdk + +The contract between the Dorfteich host app and a plugin bundle: the +**manifest schema**, the **capability names**, and the typed **postMessage RPC +protocol**. It is the one package a plugin author needs — it builds standalone +and pulls in only `zod`. + +Read [ADR 0008](../../docs/architecture/adr/0008-plugin-sandbox.md) and +[plugin-architecture.md](../../docs/architecture/plugin-architecture.md) first; +the manifest example there is normative and mirrored by the fixtures under +[`fixtures/manifests/`](./fixtures/manifests). + +## What's in here + +| Module | Purpose | +| ----------------- | ----------------------------------------------------------------------------------- | +| `manifest.ts` | Zod schema for `manifest.json` + `validateManifest` / `parseManifest`. | +| `api-version.ts` | `checkApiVersion` — is a plugin's `apiVersion` within the host's supported range? | +| `capabilities.ts` | Capability names and the method → capability map that gates RPC calls. | +| `rpc.ts` | Transport-agnostic RPC engine (`createRpcEndpoint`) + a `windowTransport` adapter. | +| `host.ts` | `createHostBridge` — host end: routes plugin calls through the permission gate. | +| `plugin.ts` | `createPlugin` — plugin end: answers lifecycle calls, exposes a typed `host` proxy. | + +## Manifest + +```ts +import { validateManifest } from '@dorfteich/plugin-sdk'; + +const result = validateManifest(JSON.parse(raw)); +if (!result.success) { + // result.issues: [{ path: 'extensionPoints.0.type', message: '…' }, …] +} +``` + +`validateManifest` never throws — it returns a flat list of `{ path, message }` +issues so the install path (#71) can show a Site Admin every problem at once. +`parseManifest` is the throwing variant. Cross-field rules enforced beyond the +field shapes: + +- extension point types must match the plugin `kind` + (`section_style` → `sectionStyle` only; `code` → `block`/`pageTool`); +- extension point `id`s are unique within the manifest; +- `section_style` plugins run no JavaScript and must not declare `permissions`. + +## RPC protocol + +Every code-plugin surface runs in a sandboxed `