/** * `agent-relay view ` — read-only PTY stream client. * * Connects to a running broker's `/ws` WebSocket, filters the event stream * for `worker_stream` frames matching the requested agent name, and writes * each chunk's raw bytes to stdout (preserving ANSI escapes). * * No keystrokes are forwarded — the broker keeps doing whatever it's doing. * Ctrl+C exits the client cleanly; the agent keeps running under the broker. */ import { Command } from 'commander'; import WebSocket from 'ws'; import { captureAndRenderSnapshot, type AttachSnapshotConnection, type AttachSnapshotDeps } from '../lib/attach.js'; type ExitFn = (code: number) => never; /** Subset of the broker's `BrokerEvent` we actually care about for `view`. */ export interface ViewableWorkerStreamEvent { kind: 'worker_stream'; name: string; stream: string; chunk: string; } /** Connection metadata discovered from `connection.json` or CLI/env overrides. */ export interface ViewBrokerConnection { url: string; apiKey?: string; } export interface ViewWebSocket { on(event: 'open', listener: () => void): unknown; on(event: 'message', listener: (data: WebSocket.RawData) => void): unknown; on(event: 'close', listener: (code: number, reason: Buffer) => void): unknown; on(event: 'error', listener: (err: Error) => void): unknown; close(code?: number, reason?: string): void; } export type ViewWebSocketFactory = (url: string, headers: Record) => ViewWebSocket; export interface ViewSignalRegistrar { (signal: NodeJS.Signals, handler: () => void | Promise): void; } export interface ViewDependencies { /** Reads `/connection.json` and returns parsed JSON, or null. */ readConnectionFile: (stateDir: string) => unknown; /** Project paths helper — used to pick the default state dir. */ getDefaultStateDir: () => string; /** Environment variables (so tests can inject). */ env: NodeJS.ProcessEnv; /** Factory for the WebSocket — overridden in tests with a mock. */ createWebSocket: ViewWebSocketFactory; /** Where the PTY chunks get written. Defaults to `process.stdout.write`. */ writeChunk: (chunk: string) => void; /** Signal registration (so tests can drive SIGINT without killing the test). */ onSignal: ViewSignalRegistrar; log: (...args: unknown[]) => void; error: (...args: unknown[]) => void; exit: ExitFn; /** HTTP client used by the snapshot-on-attach call. Defaults to global `fetch`. */ fetch: typeof globalThis.fetch; /** Override for the snapshot-on-attach helper (tests substitute a stub). */ captureAndRenderSnapshot: (connection: AttachSnapshotConnection, agentName: string, deps: AttachSnapshotDeps) => ReturnType; } /** * Resolve the broker connection to use for `view`, in priority order: * * 1. `--broker-url` / `--api-key` CLI flags * 2. `RELAY_BROKER_URL` / `RELAY_BROKER_API_KEY` environment variables * 3. `/connection.json` (default `.agent-relay/connection.json`) * * Matches the resolution order used by `agent-relay-broker dump-pty` so users * don't have to learn two patterns. */ export declare function resolveViewBrokerConnection(options: { brokerUrl?: string; apiKey?: string; stateDir?: string; }, deps: ViewDependencies): ViewBrokerConnection | null; /** Convert an `http(s)://host:port` base URL to the matching `ws(s)://…/ws`. */ export declare function toWsUrl(baseUrl: string): string; /** * Inspect a single WebSocket message and, if it's a `worker_stream` event for * the requested agent, return the raw chunk string. Returns `null` for events * that don't match (other kinds, other agents, malformed JSON, etc.) so the * caller can ignore them. * * Exported for unit testing the filter in isolation from any WebSocket. */ export declare function extractMatchingChunk(rawMessage: string, agentName: string): string | null; /** * Open the read-only view stream and run until the WebSocket closes, the * caller signals SIGINT/SIGTERM, or an unrecoverable error occurs. Resolves * with the exit code the CLI should propagate. */ export declare function runViewSession(agentName: string, options: { brokerUrl?: string; apiKey?: string; stateDir?: string; }, deps: ViewDependencies): Promise; /** Register `agent-relay view ` on the supplied commander program. */ export declare function registerViewCommands(program: Command, overrides?: Partial): void; export {}; //# sourceMappingURL=view.d.ts.map