Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.3 KiB
@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.
Documentation tree
- bridge — This module is the package's flagship factory:
createSandboxedVmPluginModule({ sandbox, manifest, registry })→ `Brid…- bridge — This module is the package's flagship factory:
createSandboxedVmPluginModule({ sandbox, manifest, registry })→ `Brid…
- bridge — This module is the package's flagship factory:
- error-codes — This module owns the stable
SAND_VM_BRIDGE.*error-code registry used by every public failure path inside the host br…- error-codes — This module owns the stable
SAND_VM_BRIDGE.*error-code registry used by every public failure path inside the host br…
- error-codes — This module owns the stable
- instruments — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr…
- instruments — This module owns the OTel instrument bundle the bridge emits. Splitting the bundle off the bridge module makes the metr…
- lifecycle — This module owns the idempotency wrapper around a
VmSandboxHandle'sstart/disposelifecycle. The host's lifecyc…- lifecycle — This module owns the idempotency wrapper around a
VmSandboxHandle'sstart/disposelifecycle. The host's lifecyc…
- lifecycle — This module owns the idempotency wrapper around a
- marshal-request — This module turns the host's per-request
RequestContextinto a plain-dataSerializedRequestvalue that the sandbox… - marshal-response — This module turns the value returned by a sandboxed handler into a host
Response. The sandbox-side handler returns a… - route-discovery — This module owns the route-discovery protocol that lets a sandboxed plugin tell the host which HTTP routes it wants to…
- route-discovery — 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 — This module ships
runVmHostBridgeConformance({ buildBridge })— a five-invariant conformance suite that every concret…- vm-host-bridge-conformance — This module ships
runVmHostBridgeConformance({ buildBridge })— a five-invariant conformance suite that every concret…
- vm-host-bridge-conformance — This module ships
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:
- Asking the sandbox (via a host-installed
bridge.registerRoutecapability) for the plugin's route registrations. - Wrapping every registered handler in a marshal closure that turns the
host
Requestinto aSerializedRequest, calls the sandbox-side handler, and turns the returnedSerializedResponseinto a hostResponse. - Delegating
start()/dispose()to the underlying sandbox handle, idempotently.
Quickstart
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.