Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
# @suaveplan/api-sandbox-vm-host-bridge - Host-integration bridge that wraps a @suaveplan/api-sandbox-vm VmSandboxHandle as a PluginModule + PipelineRoute[] bundle for @suaveplan/api-host.installPlugin. Marshals host Request → SerializedRequest into the vm.Context, unmarshals SerializedResponse → host Response, delegates start/dispose lifecycle to the sandbox handle, and surfaces sandbox faults via the SAND_VM_BRIDGE.* code registry.
Host-integration bridge that lets a `VmSandboxHandle` from
`@suaveplan/api-sandbox-vm` install into `@suaveplan/api-host` as a
first-class plugin.
<!-- begin:auto-docs -->
## Documentation tree
- [bridge](./src/bridge/bridge.md) — This module is the package's flagship factory: `createSandboxedVmPluginModule({ sandbox, manifest, registry })` → `Brid…
- [bridge](./src/bridge/bridge.md) — This module is the package's flagship factory: `createSandboxedVmPluginModule({ sandbox, manifest, registry })` → `Brid…
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable `SAND_VM_BRIDGE.*` error-code registry used by every public failure path inside the host br…
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable `SAND_VM_BRIDGE.*` error-code registry used by every public failure path inside the host br…
- [instruments](./src/instruments/instruments.md) — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr…
- [instruments](./src/instruments/instruments.md) — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr…
- [lifecycle](./src/lifecycle/lifecycle.md) — This module owns the idempotency wrapper around a `VmSandboxHandle`'s `start` / `dispose` lifecycle. The host's lifecyc…
- [lifecycle](./src/lifecycle/lifecycle.md) — This module owns the idempotency wrapper around a `VmSandboxHandle`'s `start` / `dispose` lifecycle. The host's lifecyc…
- [marshal-request](./src/marshal/marshal-request.md) — This module turns the host's per-request `RequestContext` into a plain-data `SerializedRequest` value that the sandbox…
- [marshal-response](./src/marshal/marshal-response.md) — This module turns the value returned by a sandboxed handler into a host `Response`. The sandbox-side handler returns a…
- [route-discovery](./src/route-discovery/route-discovery.md) — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to…
- [route-discovery](./src/route-discovery/route-discovery.md) — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to…
- [vm-host-bridge-conformance](./src/testing/vm-host-bridge-conformance/vm-host-bridge-conformance.md) — This module ships `runVmHostBridgeConformance({ buildBridge })` — a five-invariant conformance suite that every concret…
- [vm-host-bridge-conformance](./src/testing/vm-host-bridge-conformance/vm-host-bridge-conformance.md) — This module ships `runVmHostBridgeConformance({ buildBridge })` — a five-invariant conformance suite that every concret…
<!-- end:auto-docs -->
## What it does
A `VmSandboxHandle` is a frozen `vm.Context` running a `SourceTextModule`
with permission-gated `__suaveplan` capabilities — but it is NOT a
`PluginModule`. The host's `installPlugin({ module, manifest, routes })`
takes a plain TS object with `start/stop/dispose/health` hooks plus a
`PipelineRoute[]` registration list. This package builds that
`PluginModule + routes` bundle by:
1. Asking the sandbox (via a host-installed `bridge.registerRoute`
capability) for the plugin's route registrations.
2. Wrapping every registered handler in a marshal closure that turns the
host `Request` into a `SerializedRequest`, calls the sandbox-side
handler, and turns the returned `SerializedResponse` into a host
`Response`.
3. Delegating `start()` / `dispose()` to the underlying sandbox handle,
idempotently.
## Quickstart
```ts
import {
createSandboxedVmPluginModule,
createBridgeRouteRegistry,
} from "@suaveplan/api-sandbox-vm-host-bridge";
import { createVmSandbox } from "@suaveplan/api-sandbox-vm";
const registry = createBridgeRouteRegistry();
const sandbox = createVmSandbox({
pluginId: "demo",
pluginModule: { kind: "source", identifier: "demo.mjs", source },
checker, // PermissionChecker
proxies: {
fs,
fetch,
capabilities: { bridge: registry.capability },
},
logger,
});
const bridged = await createSandboxedVmPluginModule({
sandbox,
manifest,
registry,
});
await host.installPlugin({
module: bridged.module,
manifest,
manifestHash,
specifier,
routes: bridged.routes,
});
```
## Error codes
`SAND_VM_BRIDGE.*` — five stable codes covering plugin-surface
discovery (`INVALID_PLUGIN_SURFACE`), wire marshalling (`MARSHAL_FAILED`
/ `UNMARSHAL_FAILED`), handler throws (`HANDLER_REJECTED`), and
lifecycle delegation (`LIFECYCLE_FAILED`).
## Conformance
`@suaveplan/api-sandbox-vm-host-bridge/testing` ships
`runVmHostBridgeConformance({ buildBridge })` with the five invariants
the spec mandates: route registration, request round-trip, idempotent
lifecycle, error propagation with `cause` chain, and capability
passthrough including denied capability surfacing `SAND_PERM.DENIED`.