Interfaces
ConnectBridgeOptions
Properties
| Property | Type | Description |
|---|---|---|
dispatcher? | SandboxToolDispatcher | Custom tool dispatcher. Defaults to the built-in sandbox tool dispatcher (see ./dispatch.ts). Hosts can replace this to extend the tool surface. |
fetchImpl? | typeof fetch | Injectable fetch for the standby health poll (tests). Default: global. |
initialReconnectDelayMs? | number | Initial reconnect delay in ms (default 500). |
maxReconnectDelayMs? | number | Max reconnect delay in ms (default 30_000). |
noReconnect? | boolean | Disable the auto-reconnect loop (useful in tests where the test harness explicitly controls connection lifecycle). |
onStateChange? | (state: ConnectedBridgeState) => void | Called whenever the client transitions connection state. |
sandboxId? | string | Stable identifier for this sandbox session — surfaces in the bridge’s audit log entries. Default: a random UUID per page load. |
standbyPollMs? | number | Standby poll interval in ms (default 2_000). When the bridge closes this connection with the REPLACED code (another tab took the peer slot), the client polls the health endpoint at this cadence — plus per-poll jitter, so two standby tabs don’t stampede a freshly vacant slot — and only reconnects when sandboxConnected is false. |
toolNames? | string[] | Tool names to advertise to the bridge in the hello message. Defaults to SANDBOX_TOOL_NAMES. Override when supplying a custom dispatcher. |
url? | string | Bridge WebSocket URL. Overrides the discovery chain. Example: ws://localhost:5174/sandbox. |
workerRelay? | WorkerRelay | Generic worker relay (remote sandbox, slice 1). When supplied, the client advertises the worker-relay capability in its hello and routes worker-op / worker-sub / worker-unsub frames through it — on the worker path this forwards them into the SharedWorker port (relayWorkerOp / relayWorkerSub in serve/worker/client.ts). |
ConnectedBridge
Methods
disconnect()
disconnect(): void;
Close the bridge connection. Does NOT close the underlying sandbox.
Returns
void
state()
state(): ConnectedBridgeState;
Current connection state.
Returns
HelloFromBridge
Bridge → browser: acknowledge connection.
Properties
| Property | Type | Description |
|---|---|---|
bridgeVersion | string | Bridge version, for compatibility checks. |
protocol | 1 | - |
type | "hello-ack" | - |
HelloFromClient
Browser → bridge: “I’m here and ready to receive tool calls.”
Properties
SandboxToolDispatcher()
SandboxToolDispatcher(
sandbox: LocalSandbox,
name: string,
args: Record<string, unknown>): Promise<{
data?: unknown;
ok: boolean;
summary: string;
}>;
Dispatch a tool call. Throws if the tool isn’t recognised (the bridge advertises only what this dispatcher reports it can handle, so unknowns indicate wire-level drift).
Parameters
| Parameter | Type |
|---|---|
sandbox | LocalSandbox |
name | string |
args | Record<string, unknown> |
Returns
Promise<{
data?: unknown;
ok: boolean;
summary: string;
}>
ToolCallRequest
Bridge → browser: please dispatch this tool call into the sandbox.
Properties
ToolCallResponse
Browser → bridge: tool call result.
Properties
WorkerRelay
Host-supplied handlers that forward relay frames into the SharedWorker.
Methods
op()
op(op: WorkerOpPayload): Promise<unknown>;
Dispatch one worker op; resolves with the worker’s res.value.
Parameters
| Parameter | Type |
|---|---|
op | WorkerOpPayload |
Returns
Promise<unknown>
subscribe()
subscribe(sub: WorkerSubPayload, onValue: (value: unknown) => void): () => void;
Register a worker subscription; onValue receives every snap value
(including the { __error } establishment-failure convention).
Returns the unsubscribe function.
Parameters
| Parameter | Type |
|---|---|
sub | WorkerSubPayload |
onValue | (value: unknown) => void |
Returns
(): void;
Returns
void
Type Aliases
BridgeMessage
type BridgeMessage =
| HelloFromClient
| HelloFromBridge
| AttachFromConsumer
| AttachAckFromBridge
| ToolCallRequest
| ToolCallResponse
| WorkerOpFrame
| WorkerResFrame
| WorkerSubFrame
| WorkerUnsubFrame
| WorkerSnapFrame
| Ping
| Pong;
@pyric/cli/bridge — browser-side entry.
Resolved by the browser condition in package.json’s exports map.
Exports connectBridge, which the host app calls to register its
in-page sandbox with a running pyric bridge process. After
registration, MCP tool calls reaching the bridge are forwarded over
WebSocket and dispatched into the local sandbox.
The Node-side server entry lives in ./server.ts. Wire format
shared by both lives in ./protocol.ts.
ALSO reachable as @pyric/cli/bridge/client — an explicit, condition-free
subpath for browser apps whose TYPE resolution doesn’t apply the browser
condition (Pyric Studio’s moduleResolution: bundler tsconfig resolves the
./bridge subpath’s top-level types to the SERVER entry). Same file,
same surface.
ConnectedBridgeState
type ConnectedBridgeState =
| {
kind: "connecting";
}
| {
bridgeVersion: string;
kind: "connected";
}
| {
kind: "disconnected";
reason: string;
}
| {
attempt: number;
delayMs: number;
kind: "reconnecting";
}
| {
kind: "standby";
};
Type Declaration
{
kind: "connecting";
}
kind
kind: "connecting";
{
bridgeVersion: string;
kind: "connected";
}
bridgeVersion
bridgeVersion: string;
kind
kind: "connected";
{
kind: "disconnected";
reason: string;
}
kind
kind: "disconnected";
reason
reason: string;
{
attempt: number;
delayMs: number;
kind: "reconnecting";
}
attempt
attempt: number;
delayMs
delayMs: number;
kind
kind: "reconnecting";
{
kind: "standby";
}
kind
kind: "standby";
Another tab holds the peer slot (this connection was closed with the
REPLACED code). The client health-polls until the slot is vacant, then
reconnects. Distinct from reconnecting: the bridge is healthy and
deliberately serving a different tab.
Functions
connectBridge()
function connectBridge(sandbox: LocalSandbox, opts?: ConnectBridgeOptions): ConnectedBridge;
Parameters
| Parameter | Type |
|---|---|
sandbox | LocalSandbox |
opts? | ConnectBridgeOptions |
Returns
toPageOriginWsUrl()
function toPageOriginWsUrl(raw: string, loc: {
host: string;
href: string;
protocol: string;
}): string;
Re-anchor a bridge WebSocket URL to the page’s own origin.
pyric dev / the vite plugin bake their OWN host into the bridge URL it
sends the page (e.g. ws://localhost:5173/__pyric/sandbox). But the page may
have been loaded over a different host (Tailscale, a LAN IP) or scheme
(https via tailscale serve, which then requires wss). Connecting to the
baked localhost from a remote tab dials the WRONG machine (the client’s own
localhost), so the WS fails.
Keep only the PATH from the server’s URL and rebuild the scheme + host from the
page’s location. The bridge is always mounted on the same server that served
the page, so the page’s origin is the correct target wherever it is reached,
with no plugin configuration. This also sidesteps the localhost / 127.0.0.1 /
::1 family ambiguity, because the browser dials the exact host it loaded from.
Pure (location is injected) so it is unit-testable. Returns raw unchanged if
it cannot be parsed.
Parameters
| Parameter | Type |
|---|---|
raw | string |
loc | { host: string; href: string; protocol: string; } |
loc.host | string |
loc.href | string |
loc.protocol | string |
Returns
string
References
DEFAULT_BRIDGE_PORT
Re-exports DEFAULT_BRIDGE_PORT
DEFAULT_SANDBOX_PATH
Re-exports DEFAULT_SANDBOX_PATH