import type { HubClientMessage, HubRequest, HubResponse, InitMessage } from './protocol.ts';
/**
 * Return `url` with `sessionId=<sessionId>` set as a query param.
 *
 * Used to update the cached reconnect URL once the Hub assigns a sessionId
 * via the init message. Without this, a local-lead TUI reconnects with the
 * original URL (no sessionId), and the Hub treats each reconnect as a brand
 * new lead — spawning a fresh session every time the WebSocket drops.
 *
 * @internal exported for tests
 */
export declare function applySessionIdToConnectUrl(url: string, sessionId: string): string;
export type ConnectionState = 'connected' | 'disconnected' | 'reconnecting' | 'closed';
export declare class HubClient {
    private ws;
    private reconnectAttempts;
    private reconnectTimer;
    private intentionallyClosed;
    private lastConnectUrl;
    private queue;
    private connectionStateListeners;
    private pending;
    connectionState: ConnectionState;
    onConnectionStateChange?: (state: ConnectionState) => void;
    onBeforeReconnect?: () => Promise<void>;
    onInitMessage?: (initMessage: InitMessage) => void;
    /** Called when an unsolicited server message arrives (broadcast, presence, hydration). */
    onServerMessage?: (message: Record<string, unknown>) => void;
    /** Hub auth token from the CLI environment. */
    apiKey: string | null;
    private setConnectionState;
    private buildWebSocketUrl;
    private enqueue;
    private sendRequestNow;
    private sendFireAndForgetNow;
    private flushQueue;
    private handleUnexpectedClose;
    private clearReconnectTimer;
    private rejectQueuedRequests;
    private startReconnectLoop;
    private connectInternal;
    connect(url: string, opts?: {
        sessionId?: string;
        role?: string;
        origin?: string;
    }): Promise<InitMessage>;
    /**
     * Update the cached reconnect URL so future reconnect attempts include
     * `sessionId=<sessionId>`.
     *
     * Call this once the Hub assigns a sessionId via the init message. Without
     * it, a local-lead TUI that connected with `?origin=tui` (no sessionId)
     * will reconnect with the same URL, and the Hub treats every reconnect as
     * a brand new lead — creating a fresh session on each WebSocket drop.
     *
     * No-op if no sessionId is provided, the client has not connected yet, or
     * the URL already targets the same sessionId.
     */
    setReconnectSessionId(sessionId: string): void;
    private waitForConnection;
    nextId(): string;
    send(request: HubRequest): Promise<HubResponse>;
    sendNoWait(message: HubClientMessage | Record<string, unknown>): void;
    waitUntilConnected(timeoutMs?: number): Promise<void>;
    close(): void;
    get connected(): boolean;
}
//# sourceMappingURL=client.d.ts.map