# @ethisyscore/extension-runtime

Host + plugin runtime for EthisysCore extension contracts:

- **Contract A** — host-rendered SDUI extensions. Plugins return a closed-vocabulary `SduiNode` tree from a `ResourceHandler`; the host's declarative interpreter mounts it directly.
- **Contract B** — worker remote-runtime extensions. Plugin code runs in a sandboxed Web Worker; UI mutations flow via Remote DOM into the host's semantic primitive registry. The capability token never crosses the worker boundary.

Built on top of `@ethisyscore/protocol` (canonical bridge / manifest / SDUI / capability / theme types).

## Subpath exports

| Entry | Use | Surface |
| ----- | --- | ------- |
| `@ethisyscore/extension-runtime` | Root re-exports | Stable consumer-facing types and helpers. |
| `@ethisyscore/extension-runtime/host` | Host integration | `WorkerRemoteDomTransport`, declarative interpreter, semantic component registry, offscreen-canvas helpers. |
| `@ethisyscore/extension-runtime/plugin` | Plugin side | `ExtensionRuntimeProvider`, `useMcpResource`, `useMcpTool`, transport abstraction. |
| `@ethisyscore/extension-runtime/mock-host` | Local dev | `DeclarativeMockHost` and the `mock-host` CLI entry. |

The `mock-host` bin (`npx mock-host <dir>`) is shipped — boots a Vite dev page that mounts the declarative interpreter against a directory of SDUI JSON resources. Run `--render-mode remote-runtime <bundle>` for the Contract B variant.

## Local development

This package consumes `@ethisyscore/protocol` via `npm link`. The protocol package is registered globally in E1.S8:

```powershell
cd <repo>/sdk/extension-runtime
npm install
npm link @ethisyscore/protocol
```

## Scripts

| Script           | Purpose                            |
| ---------------- | ---------------------------------- |
| `npm run build`  | Build ESM + CJS + `.d.ts` via tsup |
| `npm test`       | Run unit tests (Vitest, jsdom)     |
| `npm run lint`   | Type-check only (`tsc --noEmit`)   |

## Targets

- Node.js >= 20
- React >= 18 (peer dep, required by `./host` and `./plugin` subpaths in later tasks)
