/**
 * Browser Relay Adapter Service
 *
 * Bridges BrowserBridgeService with CloudSyncService to enable browser
 * commands to flow through the Cloud relay queue when the Chrome Extension
 * is not directly connected via WebSocket.
 *
 * Flow:
 *   Agent → BrowserBridgeService → BrowserRelayAdapter → CloudSyncService
 *   → Cloud relay queue → Extension polls → executes → sends response
 *   → Cloud relay queue → Droplet polls → BrowserRelayAdapter resolves
 *
 * The Extension never sees the droplet IP — all traffic goes through
 * the Cloud relay URL (crewlyai.com).
 *
 * @module services/browser/browser-relay-adapter.service
 */
import type { BrowserCommandResponse } from './browser-bridge.service.js';
/**
 * Adapter that routes browser commands through the Cloud relay queue
 * when no direct WebSocket connection exists to the Chrome Extension.
 *
 * Usage:
 * 1. Create adapter with target Extension device ID
 * 2. Register with BrowserBridgeService as relay fallback
 * 3. Handle incoming `browser_response` messages from CloudSyncService
 *
 * @example
 * ```typescript
 * const adapter = BrowserRelayAdapter.getInstance();
 * adapter.setExtensionDeviceId('ext-device-abc');
 *
 * // Send command via relay
 * const response = await adapter.sendViaRelay('navigate', { url: 'https://example.com' });
 *
 * // Handle incoming responses (called by CloudSyncService message handler)
 * adapter.handleRelayResponse({ id: 'cmd-1', success: true, result: {...} });
 * ```
 */
export declare class BrowserRelayAdapter {
    private static instance;
    private readonly logger;
    private pendingCommands;
    private commandCounter;
    /** Device ID of the connected Chrome Extension (from Cloud device list) */
    private extensionDeviceId;
    /** Whether auto-discovery is currently active */
    private discoveryActive;
    /** Bound handler references for cleanup */
    private boundDeviceOnlineHandler;
    private boundDeviceOfflineHandler;
    private boundDevicesUpdatedHandler;
    /**
     * Bound handlers for the BrowserProxy event channel — the primary
     * signal source after 2026-05-23. The Sync handlers above remain wired
     * as a belt-and-suspenders fallback for legacy code paths that still
     * push browser devices through Sync, but in current production those
     * events never fire (CloudSyncService only tracks orchestrator-role
     * devices). The proxy listens directly to the Cloud relay's browser_list
     * / browser_event channel, which is the canonical source of truth for
     * extension presence.
     */
    private boundProxyConnectedHandler;
    private boundProxyDisconnectedHandler;
    private constructor();
    /**
     * Get the singleton instance.
     *
     * @returns BrowserRelayAdapter instance
     */
    static getInstance(): BrowserRelayAdapter;
    /**
     * Reset singleton instance (for testing).
     */
    static resetInstance(): void;
    /**
     * Set the target Chrome Extension device ID for relay routing.
     * This device ID comes from CloudSyncService device discovery.
     *
     * @param deviceId - Cloud device ID of the Extension
     */
    setExtensionDeviceId(deviceId: string): void;
    /**
     * Get the current Extension device ID.
     *
     * @returns Device ID or null if not set
     */
    getExtensionDeviceId(): string | null;
    /**
     * Whether the relay adapter has a known extension target via the
     * BrowserProxy event channel.
     *
     * Single liveness definition (2026-05-28 browser-relay fix): availability is
     * derived from the BrowserProxy — the canonical source of truth for browser
     * presence on the Cloud relay — NOT from the CloudSyncService state. The
     * former CloudSync `getState() === 'syncing'` gate was dead in production
     * (Sync only tracks orchestrator-role devices, never browser-role), so it
     * reported a liveness that disagreed with `proxy.isAvailable()`. Collapsing
     * to the proxy removes that disagreement (REGISTRY-TRUTH invariant).
     *
     * @returns True if the proxy reports a drivable browser and we have a target
     */
    isAvailable(): boolean;
    /**
     * Send a browser command to the Chrome Extension via the Cloud relay queue.
     *
     * @param tool - Tool name to execute (e.g., 'navigate', 'screenshot')
     * @param params - Tool parameters
     * @param timeoutMs - Command timeout in milliseconds
     * @param agentName - Optional agent name for display in Extension
     * @returns Response from the Chrome Extension
     * @throws Error if relay is not available or command times out
     */
    sendViaRelay(tool: string, params?: Record<string, unknown>, timeoutMs?: number, agentName?: string): Promise<BrowserCommandResponse>;
    /**
     * Handle an incoming browser_response message from the Cloud relay queue.
     * Called by CloudSyncService message handler when a browser_response arrives.
     *
     * @param response - The browser command response from the Extension
     */
    handleRelayResponse(response: BrowserCommandResponse): void;
    /**
     * Get the number of pending relay commands.
     *
     * @returns Number of commands awaiting response
     */
    getPendingCount(): number;
    /**
     * Start listening for CloudSync device events to auto-discover Chrome
     * Extension devices. When a device with role 'browser' or 'chrome-extension'
     * comes online, automatically sets it as the relay target.
     *
     * Also scans the current device list on startup for already-online extensions.
     */
    startAutoDiscovery(): void;
    /**
     * Handle `instance_connected` from BrowserProxy — adopt as the relay
     * target if we don't already have one (or if the existing one is gone).
     *
     * @param evt - Connected instance info
     */
    private onProxyInstanceConnected;
    /**
     * Handle `instance_disconnected` from BrowserProxy — clear the relay
     * target only if it matches the disconnecting instance.
     *
     * @param evt - Disconnected instance info
     */
    private onProxyInstanceDisconnected;
    /**
     * Stop listening for device events.
     */
    stopAutoDiscovery(): void;
    /**
     * Whether auto-discovery is active.
     *
     * @returns True if listening for device events
     */
    isDiscoveryActive(): boolean;
    /**
     * Check if a SyncDevice represents a Chrome Extension (browser role).
     *
     * @param device - Device to check
     * @returns True if the device has a browser/chrome-extension role
     */
    private isBrowserDevice;
    /**
     * Handle a device coming online — if it's a browser extension, set it as relay target.
     *
     * @param device - The device that came online
     */
    private onDeviceOnline;
    /**
     * Handle a device going offline — if it's our current extension, clear the target.
     *
     * @param device - The device that went offline
     */
    private onDeviceOffline;
    /**
     * Handle devices_updated — scan for browser extensions in the full list.
     *
     * @param devices - Current device list
     */
    private onDevicesUpdated;
    /**
     * Scan a device list for browser extensions and set the first online one as relay target.
     *
     * @param devices - Device list to scan
     */
    private scanForBrowserDevice;
    /**
     * Clean up pending commands and timers.
     */
    cleanup(): void;
}
//# sourceMappingURL=browser-relay-adapter.service.d.ts.map