export { S as SessionDescriptor, b as buildShareConfig, a as buildShareUrl, e as constantTimeEqual, c as createSessionDescriptor, d as describeSession, r as readSessionFromUrl } from '../token-BZ8doMam.cjs'; import { d as JsonRpcMessage } from '../types-ITRQFAir.cjs'; import { T as Transport, M as MicroMcpServer } from '../server-DJJygNo1.cjs'; import { AutoActivityEvent } from '@particle-academy/fancy-auto-common'; import '../tool-host-BBSaU7IJ.cjs'; /** * SseRelayTransport — bridges the in-page MicroMcpServer to a host-app * relay broker over Server-Sent Events (inbound) + POST (outbound). * * Wire model: * - Browser opens an EventSource at `${baseUrl}/${sessionId}/events?token=…`. * Each `event: mcp` carries one JSON-RPC frame from a remote client. * - Browser POSTs JSON-RPC frames to `${baseUrl}/${sessionId}/outbox?token=…` * when the local server has a response/notification to send. * * The host provides the relay endpoint (any HTTP server). See the demo * `WhiteboardShareController` for the reference implementation. * * Token authentication is the host's job — this transport just carries the * token in the query string. For lower-trust deployments, layer signing on * top by wrapping `send` / `deliverFromRemote`. */ type SseRelayOptions = { /** * Which in-process activity events this relay forwards to ITS agent. * * The activity bus is global to the page, so with two concurrent sessions — * site co-browse and the agent playground — each relay forwarded the other's * traffic and every agent saw every other agent's navigations. Returning * `false` drops the event for this relay only. * * Omitted means forward everything, which is the historical behaviour and * correct for the common single-session case. A throwing predicate drops that * one event and keeps the subscription: a host predicate is host code, and * one bad event must not silently end forwarding for the session — that looks * exactly like the agent going quiet. */ activityFilter?: (event: AutoActivityEvent) => boolean; /** * Identity stamped on the relay's own connect/disconnect activity. * * These were emitted with a literal `agentId: "agent"`, which made two * sessions' connect events indistinguishable — and unfilterable, since there * was nothing to tell them apart by. */ agent?: { id: string; name?: string; color?: string; }; baseUrl: string; sessionId: string; token: string; /** Override fetch (testing / non-browser). Defaults to global fetch. */ fetch?: typeof fetch; }; declare class SseRelayTransport implements Transport { private server?; private es?; private channel?; private disposed; private opts; private sendQueue; private connected; private listeners; private state; private expectedToken; private peers; private peerListeners; constructor(options: SseRelayOptions); bindServer(server: MicroMcpServer): void; /** Open the receive channel. Idempotent. */ start(): void; /** Fallback receive leg: a plain EventSource (no fancy-cf-relay installed). */ private startSse; /** Mark the channel live + flush any queued outbound frames. */ private markOpen; send(message: JsonRpcMessage): void; close(): void; onStateChange(listener: (state: RelayState) => void): () => void; /** How many remote peers (agents) are currently attached to this session. */ peerCount(): number; /** * Subscribe to peer arrivals/departures. Fires immediately with the current * count. * * This is the ONLY honest answer to "is an agent actually here?". * `onStateChange` reports the BROWSER's own channel to the relay, which opens * the instant sharing starts — so a UI keyed on it announces "Agent is * driving" to a human who has not yet handed the link to anybody, and can * never tell them when one really arrives. */ onPeersChange(listener: (count: number) => void): () => void; private notifyPeers; /** * For relays that wrap each frame with auth metadata: hosts can call this * directly when a frame arrives via a non-SSE path. The transport will * dispatch it to the bound server. */ deliverFromRemote(payload: JsonRpcMessage | string, token?: string): Promise; private postOut; private handleInbound; private setState; } type RelayState = "idle" | "connecting" | "open" | "closed" | "error"; declare function attachSseRelay(server: MicroMcpServer, options: SseRelayOptions): SseRelayTransport; export { type RelayState, type SseRelayOptions, SseRelayTransport, attachSseRelay };