import { default as React } from 'react'; import { AxStatus } from '../core/ax-fetcher'; import { AxElement, AxSnapshot } from '../core/ax-tree'; declare global { interface Window { debugRemoteControl?: boolean; } } interface RemoteControlProps { url: string; token: string; className?: string; sessionId?: string; openUrl?: string; showFrame?: boolean; autoReconnect?: boolean; /** * Enable the inspect overlay. When set, the component starts polling the * accessibility tree and draws boxes over each element on top of the * video stream. * * - `true` — Select mode. Boxes are clickable, click pins a selection * with action buttons (Tap / Copy selector / Copy id), ESC clears. * Device input is blocked while in this mode. * - `'hover-only'` — Boxes follow the cursor as a visual preview. Device * input still passes through, so you can drive the simulator while * inspecting. * - `undefined` / `false` (default) — overlay disabled, no polling. */ inspectMode?: boolean | 'hover-only'; /** * Fires whenever a fresh accessibility snapshot is delivered. * * Customers use this to drive their own side panels, agent prompts, * analytics, etc. The built-in overlay does not require this callback — * it renders from internal state regardless. * * Identical-to-previous snapshots (per `axSnapshotsEqual`) are NOT * re-emitted, so a stable UI doesn't generate callback noise. * * Invoked in a microtask so customer code doesn't run synchronously * inside React's commit phase. */ onAxSnapshotChange?: (snapshot: AxSnapshot | null) => void; /** * Fires when the user clicks an overlay element (only emitted when * `inspectMode === true`). `null` indicates a deselection (ESC, click * outside any box, or programmatic clear). * * The `snapshot` field is the snapshot active at the moment of the * click — useful for capturing context without races against the next * poll cycle. */ onInspectSelectionChange?: (selection: { element: AxElement; snapshot: AxSnapshot; } | null) => void; /** * Fires whenever the accessibility subsystem changes coarse-grained * status. Useful for rendering readiness indicators or error banners in * a customer-built side panel. * * Transitions are deduplicated; no self-loops are emitted. The `error` * argument is populated when status is `error` or `unavailable`. * * Lifecycle: `idle` → `starting` → `ready` (or `unavailable` / `error`). * Recovery from `error` / `unavailable` is automatic — the fetcher * keeps polling and transitions back to `ready` on the next success. */ onAxStatusChange?: (status: AxStatus, error?: string) => void; /** * Base interval (ms) between successful AX-tree fetches. * * The fetcher will: * - Wait `axPollIntervalMs` after a successful fetch with NEW data. * - Double the wait (up to `axMaxBackoffMs`) when consecutive snapshots * are byte-identical (e.g. static screen). * - Wait 5 s when the server reports AX is unavailable. * * In addition, after user input (taps, scrolls, keypresses, openUrl, * terminateApp, orientation flips), the fetcher enters a short * "activity boost" window (~1.2 s) during which fetches happen at * ~250 ms regardless of this setting. This captures mid-animation UI * changes without you having to manually call `refreshAxTree`. * * @default 500 */ axPollIntervalMs?: number; /** * Maximum backoff (ms) for the AX-tree polling loop when consecutive * snapshots are unchanged. * * @default 2000 */ axMaxBackoffMs?: number; } interface ScreenshotData { dataUri: string; } export interface ImperativeKeyboardEvent { type: 'keydown' | 'keyup'; code: string; shiftKey?: boolean; altKey?: boolean; ctrlKey?: boolean; metaKey?: boolean; } export interface RemoteControlHandle { openUrl: (url: string) => void; sendKeyEvent: (event: ImperativeKeyboardEvent) => void; screenshot: () => Promise; terminateApp: (bundleId: string) => Promise; reconnect: () => void; refreshAxTree: () => Promise; getAxSnapshot: () => AxSnapshot | null; setInspectHighlight: (element: AxElement | null) => void; setInspectSelection: (element: AxElement | null) => void; getAxStatus: () => AxStatus; } export declare const RemoteControl: React.ForwardRefExoticComponent>; export {};