/** * PTYMeshBridge — wires truffle peer events to `MeshPTYTransport` instances. * * The bridge's single responsibility is transport lifecycle management: * * - On init: create a `MeshPTYTransport` for every **online** peer and * register it with `PTYSessionManager`. * - On `joined` / `identity` / `updated` / `ws_connected`: ensure a * transport exists for the peer (and re-index durable ULID). * - On `left`: tear down the transport and clean up proxy sessions. * * RFC 022 (truffle ≥ 0.6): * - Transports are keyed by `peer.ref` (process-local generation token). * - **Do not gate** transport creation on `wsConnected`. Eager identity * often learns a durable ULID then idle-reaps the hello WebSocket, so * peers can be online + identified with `wsConnected === false`. * `Peer.send` dials on demand — the envelope-bus WS is not a hard * prerequisite for owning a transport. * - `ws_disconnected` is a soft signal (do not dispose the transport). * - Secondary index `deviceId → peerRef` supports SyncedStore reconciliation. * * Higher-level concerns (session discovery, relay sessions, focus) live in * `RemoteSessionService`. */ import { EventEmitter } from 'events'; import type { MeshNode, Peer } from '@vibecook/truffle'; import type { PTYSessionManager } from '#core'; import { MeshPTYTransport } from './mesh-pty-transport.js'; export interface PTYMeshBridgeOptions { node: MeshNode; sessionManager: PTYSessionManager; } export interface PTYMeshBridgeEvents { /** A transport was created for a peer (`peerRef`). */ transportCreated: (peerRef: string, transport: MeshPTYTransport) => void; /** A transport was removed (peer left or bridge disposing). */ transportRemoved: (peerRef: string, reason: string) => void; } export interface IPTYMeshBridge extends EventEmitter { initialize(): Promise; isInitialized(): boolean; getTransportCount(): number; /** Lookup by process-local peer ref (primary key). */ getTransport(peerRef: string): MeshPTYTransport | null; /** Lookup by durable ULID once identity is known (SyncedStore path). */ getTransportByDeviceId(deviceId: string): MeshPTYTransport | null; /** Lookup by interned Peer handle. */ getTransportForPeer(peer: Peer): MeshPTYTransport | null; getTransports(): Map; getConnectedPeers(): string[]; dispose(): void; on(event: K, listener: PTYMeshBridgeEvents[K]): this; off(event: K, listener: PTYMeshBridgeEvents[K]): this; emit(event: K, ...args: Parameters): boolean; } export declare class PTYMeshBridge extends EventEmitter implements IPTYMeshBridge { private readonly node; private readonly sessionManager; /** Primary index: peer.ref → transport. */ private readonly transports; /** Secondary index: durable deviceId (ULID) → peer.ref. */ private readonly byDeviceId; /** Secondary index: tailscaleId → peer.ref (for string msg.from fallback). */ private readonly byTailscaleId; private initialized; constructor(options: PTYMeshBridgeOptions); initialize(): Promise; isInitialized(): boolean; dispose(): void; getTransportCount(): number; getTransport(peerRef: string): MeshPTYTransport | null; getTransportByDeviceId(deviceId: string): MeshPTYTransport | null; getTransportForPeer(peer: Peer): MeshPTYTransport | null; getTransports(): Map; getConnectedPeers(): string[]; private handlePeerChange; private resolveTransport; private indexPeer; private unindexPeer; private createTransportForPeer; private removeTransportForPeer; } export declare function createPTYMeshBridge(options: PTYMeshBridgeOptions): PTYMeshBridge; //# sourceMappingURL=pty-mesh-bridge.d.ts.map