import { type Server, type Socket } from "node:net"; import { encodeMessage, type HostTransport } from "./protocol"; /** * Socket plumbing for the pty-host (plan Phase 6b). * * A unix domain socket on POSIX, a named pipe on Windows. Both are local-only * by construction, which is the security property that matters: the host can * spawn arbitrary agent processes, so it must never be reachable over a TCP * port that something else on the network could find. */ /** * Where the host listens. * * Scoped by instance id, so two streamers configured as separate instances on * one machine do not fight over one host — the same reason DB-persisted * sessions are scoped by it. * * POSIX puts it under the config dir rather than /tmp: `THREADBASE_CONFIG_DIR` * already redirects the whole config tree in tests, and a path under a * user-owned directory cannot be pre-created by another user to hijack the * bind. Windows named pipes are not filesystem paths at all, so the config dir * has nothing to say about them. */ export declare function hostSocketPath(instanceId: string): string; /** Wrap a connected socket as the duplex line channel the runner expects. */ export declare function socketTransport(socket: Socket): HostTransport; /** Connect to a host that is already listening. Rejects if none is. */ export declare function connectToHost(socketPath: string): Promise; export type PtyHostStatusProbe = { reachable: true; protocolVersion: number; sessionCount: number; } | { reachable: false; error: string; }; /** Query host status without subscribing to events or adopting its sessions. */ export declare function probePtyHostStatus(socketPath: string, timeoutMs?: number): Promise; export interface HostServerHandlers { /** One connected streamer. Returns a disposer run when it disconnects. */ onConnection: (transport: HostTransport) => () => void; } /** * Listen for streamer connections. * * A stale socket file from a host that died without cleaning up would make * `listen` fail with EADDRINUSE forever, so an unconnectable one is removed * first — but only after a probe confirms nothing answers on it, because * deleting a live host's socket would strand every session it holds. */ export declare function listenForStreamers(socketPath: string, handlers: HostServerHandlers): Promise; /** Broadcast helper: a message to every currently-connected streamer. */ export declare function broadcast(transports: Iterable, message: Parameters[0]): void; //# sourceMappingURL=socket.d.ts.map