/** * ToolsRpcServer — listens on a Unix domain socket; dispatches tool * calls from the child script to a host-supplied tool runner; sends * results back over the same socket. * * Lifecycle: * 1. caller constructs server with a unique socketPath + tool runner * 2. caller calls listen() to bind the socket * 3. caller spawns the child process with MEMI_TOOLS_SOCKET= * 4. child opens the socket, sends `tool` requests, receives responses * 5. child sends `exit` then closes connection (or just disconnects) * 6. caller reads .finalResult() to get the script's exit value * 7. caller calls close() to remove the socket file * * Security: * - Each call is checked against the configured tool allowlist * - Socket is created with 0600 perms via mode parameter on createServer * - The token in MEMI_TOOLS_TOKEN must be presented in each request * (via a `token` field on the wire — though we don't reject in this * commit since the socket itself is the auth boundary; token is * reserved for the future remote variant) */ export interface ToolRunnerContext { readonly tool: string; readonly args: unknown; } export interface ToolRunner { /** Resolve the tool against the engine's broker. May throw on disallowed tools. */ run(ctx: ToolRunnerContext): Promise; /** Names of tools the script is permitted to call. */ allowedTools(): readonly string[]; } export interface ScriptLogEntry { readonly level: "info" | "warn" | "error"; readonly message: string; readonly data?: unknown; readonly at: string; } export interface ToolsRpcServerConfig { readonly socketPath: string; readonly runner: ToolRunner; readonly onLog?: (entry: ScriptLogEntry) => void; readonly onError?: (error: unknown, context: { phase: string; }) => void; } export declare class ToolsRpcServer { private readonly config; private server; private finalResult; private finalResolvers; private connections; constructor(config: ToolsRpcServerConfig); listen(): Promise; /** * Wait for the script to send an `exit` message. If the child closes * its socket without sending `exit`, returns { ok: false, error: ... }. */ waitForExit(timeoutMs?: number): Promise<{ ok: boolean; result?: unknown; error?: string; }>; close(): Promise; private handleConnection; private handleMessage; private handleToolRequest; private handleLogRequest; private handleExitRequest; private send; private recordFinal; }