/**
 * chat-bridge subscriber — TPS.6 patch 3 (v0.5.127).
 *
 * Long-lived UDS connection from the MCP-bridge subprocess to the
 * chat-daemon. Subscribes once on startup; thereafter, daemon-side
 * `inbound_message` notifications populate a per-process LRU buffer
 * that the `chat_poll_inbox` tool drains. The filesystem JSONL inbox
 * remains the durable record + the cold-start catch-up path; the
 * buffer is the hot-path cache that avoids per-poll fs reads.
 *
 * Wire shape (per `src/channels/daemon/protocol.ts`):
 *   → {"jsonrpc":"2.0","id":1,"method":"subscribe","params":{...}}
 *   ← {"jsonrpc":"2.0","id":1,"result":{"ok":true}}
 *   ← {"jsonrpc":"2.0","method":"inbound_message","params":{...}}  (push, no id)
 *   ← {"jsonrpc":"2.0","method":"daemon_shutdown","params":{...}}  (push)
 *
 * Reconnect: exponential backoff 1s → 60s cap. Triggered on socket
 * 'close' / 'error' / refused-connect. On `daemon_shutdown` we
 * lengthen the first delay to 5s (the daemon is restarting, not just
 * a transient disconnect) to avoid hammering. session_id is stable
 * across reconnects so the daemon can re-attach the slot.
 *
 * Buffer: LRU cap 1000 messages, 24h TTL. Past either bound, entries
 * are silently evicted — `chat_poll_inbox` falls back to fs.readFile
 * for the JSONL replay path.
 *
 * Why a separate module from `chat-bridge-server.ts`: the subscriber
 * has its own lifecycle (connect / reconnect / timer) that's
 * orthogonal to the MCP request/response surface. Keeping it
 * isolated also lets `chat-bridge-server.test.ts` mock the subscriber
 * cleanly via DI.
 *
 * No exported singleton — `main()` in chat-bridge-server.ts owns the
 * single instance and passes it to handlers via closure. Tests
 * construct their own.
 */
import { type Socket } from 'node:net';
export interface InboundMessage {
    delivery_id: string;
    message_id: string;
    platform: 'telegram' | 'discord' | 'slack';
    channel: string;
    thread_id?: string;
    sender: string;
    sender_id: string;
    text: string;
    received_at: string;
    mentions_bot: boolean;
}
export interface SubscriberOptions {
    socketPath: string;
    sessionId: string;
    workspaceUuid: string;
    workspacePath: string;
    /** Empty = wildcard subscription. */
    chatIds: string[];
    /** Test injection — defaults to LRU 1000/24h. */
    bufferMax?: number;
    bufferTtlMs?: number;
    /** Test injection — defaults to setTimeout. */
    setTimeoutFn?: (cb: () => void, ms: number) => unknown;
    /** Test injection — defaults to (host) net.connect. */
    connectFn?: (path: string) => Socket;
}
export declare const RECONNECT_BASE_MS = 1000;
export declare const RECONNECT_MAX_MS = 60000;
export declare const SHUTDOWN_BACKOFF_MS = 5000;
export declare class ChatBridgeSubscriber {
    private readonly opts;
    private socket;
    private buf;
    private reconnectMs;
    private closed;
    private subscribeId;
    private readonly buffer;
    private readonly setTimeoutFn;
    private readonly connectFn;
    constructor(opts: SubscriberOptions);
    /** Open the socket + send subscribe. Subsequent reconnects happen automatically. */
    start(): void;
    /** Stop reconnecting + close the socket. Buffer is preserved for late polls. */
    stop(): void;
    /**
     * Return all buffered messages with `enqueued_at` (== received_at)
     * strictly greater than `since` (or every buffered message if
     * since is omitted). Ordering: ascending by received_at. Caller
     * applies a per-call limit.
     */
    drainBuffer(since?: string): InboundMessage[];
    /** Diagnostic — current buffer size (test use). */
    bufferSize(): number;
    /** Diagnostic — true iff the socket is currently writable. */
    isConnected(): boolean;
    private connectAndSubscribe;
    private sendSubscribe;
    private onData;
    private dispatchLine;
    private scheduleReconnect;
}
export declare function generateSessionId(): string;
//# sourceMappingURL=chat_bridge_subscriber.d.ts.map