import type { ServerResponse } from "node:http";
export type SseEventType = "connected" | "agent" | "deliver" | "tool-hook" | "outbound" | "ping" | "subagent";
export interface SseEvent {
    type: SseEventType;
    data: Record<string, unknown>;
}
type BacklogEntry = {
    id: number;
    event: SseEvent;
};
export declare class SseConnection {
    readonly deviceId: string;
    private readonly res;
    private closed;
    private pending;
    private flushTimer;
    private waitingDrain;
    constructor(deviceId: string, res: ServerResponse);
    send(entry: BacklogEntry | SseEvent, flushNow?: boolean): void;
    sendRaw(line: string): void;
    private scheduleFlush;
    private flush;
    close(): void;
    get isClosed(): boolean;
}
declare class SseEmitterRegistry {
    private connections;
    private runEmitter;
    private lastRunIdByDevice;
    private eventSeqByDevice;
    private backlogLimit;
    getConnectionCount(): number;
    setBacklogLimit(limit: number): void;
    getBacklogLimit(): number;
    /** Last persisted / assigned SSE id for device (for `connected.lastSeq`). */
    latestSeqForDevice(deviceId: string): number;
    addConnection(deviceId: string, res: ServerResponse): SseConnection;
    /**
     * @param expectedConn When provided, only removes if this connection is still the active one
     * (avoids stale `req.close` after a reconnect replaced the map entry).
     */
    removeConnection(deviceId: string, expectedConn?: SseConnection): void;
    getConnection(deviceId: string): SseConnection | undefined;
    private nextEntry;
    replayBacklog(deviceId: string, afterEventId: number): number;
    broadcast(event: SseEvent, deviceId?: string, flushNow?: boolean): void;
    trackDeviceForRun(deviceId: string, runId: string): void;
    untrackRun(runId: string): void;
    hasTrackedDevices(runId: string): boolean;
    getDeviceIdByRunId(runId: string): string | null;
    getSoleConnectedDeviceId(): string | null;
    getLastRunIdForDevice(deviceId: string): string | null;
    broadcastToRun(runId: string, event: SseEvent, flushNow?: boolean): void;
    broadcastToolEvent(deviceId: string, runId: string, event: SseEvent, flushNow?: boolean): void;
    /** Vitest / e2e: drop connections and in-memory seq maps (does not delete disk queue files). */
    resetForTest(): void;
}
export declare const sseEmitter: SseEmitterRegistry;
export {};
