/**
 * LocalIpcServer — generic HTTP + WebSocket IPC endpoint for daemon processes.
 *
 * Both daemon-cloud and daemon-standalone need a local IPC surface so
 * external tools — the `adhdev mcp --mode ipc` MCP server and anything
 * else that wants to issue commands without going through the cloud
 * Worker — can connect over `ws://127.0.0.1:<port>/ipc`.
 *
 * Until now the implementation lived only in daemon-cloud. Standalone
 * sessions therefore couldn't host MCP mesh tools — codex/claude config
 * pointing at `--mode ipc` got `Cannot reach ipc daemon`. This module
 * moves the transport into daemon-core so both daemons can mount it.
 *
 * The transport itself is daemon-agnostic. Cloud-specific behaviors
 * (mesh relay, mandatory update gates) are injected via the caller's
 * `handleCommand` hook; the IPC layer just frames/unframes JSON and
 * routes messages.
 */
import { WebSocket } from 'ws';
/** Parameters passed to `handleCommand` for each incoming ext:command frame. */
export interface IpcCommandContext {
    /** The raw `command` field from the message — caller decides routing. */
    command: string;
    /** Args provided by the client; may have been normalized by the caller. */
    args: Record<string, unknown>;
    /** Stable id correlating the request and the eventual ext:command_result. */
    requestId: string;
    /** The connected WebSocket — only needed if the caller wants to send extra events. */
    ws: WebSocket;
}
/** Result reported back to the client. `result` is optional context for success. */
export interface IpcCommandResult {
    success: boolean;
    result?: unknown;
    error?: string;
    /**
     * Additional fields the caller wants merged into the response payload
     * (e.g. the cloud daemon's mandatory-update-block fields). Reserved.
     */
    extra?: Record<string, unknown>;
}
/** Status payload returned from GET / on the IPC HTTP port. */
export interface IpcStatusPayload {
    ok: true;
    pid: number;
    wsPath: string;
    port: number;
    /** Arbitrary daemon-specific summary. Cloud daemon includes mesh state, etc. */
    status: Record<string, unknown> | null;
}
export interface LocalIpcServerOptions {
    /** TCP port to listen on. 19222 is the conventional default. */
    port: number;
    /** Build the GET / status payload. Called on every health probe. */
    buildStatusPayload: () => Record<string, unknown> | null;
    /** Build the welcome message sent to a freshly-connected client. */
    buildWelcomePayload: () => Record<string, unknown>;
    /** Handle a single ext:command frame. Caller decides routing and returns the result. */
    handleCommand: (ctx: IpcCommandContext) => Promise<IpcCommandResult>;
    /** Optional notification when a new client connects (lets daemon track them for broadcasts). */
    onClientConnected?: (ws: WebSocket) => void;
    /** Optional notification when a client disconnects. */
    onClientDisconnected?: (ws: WebSocket) => void;
    /** Optional logger label (defaults to "IPC"). */
    logCategory?: string;
}
/**
 * Returned controller for stopping the server and broadcasting to clients.
 * Stored by the daemon and torn down at shutdown.
 */
export interface LocalIpcServerHandle {
    /** True once `listen()` succeeded. */
    isListening(): boolean;
    /** Push a message to every connected client. */
    broadcast(type: string, payload: unknown): void;
    /** Close all client sockets + the HTTP server. */
    close(): Promise<void>;
}
/**
 * Build a JSON HTTP response describing the IPC endpoint. Exposed so caller
 * code (and tests) can build the same shape without spinning a real server.
 */
export declare function buildIpcStatusHttpResponse(method: string | undefined, url: string | undefined, payload: IpcStatusPayload): {
    statusCode: number;
    body: Record<string, unknown>;
};
/**
 * Start the local IPC server. Returns a handle the caller can use to broadcast
 * events and tear down at shutdown.
 */
export declare function startLocalIpcServer(opts: LocalIpcServerOptions): Promise<LocalIpcServerHandle>;
