import { A as AppError, B as PlatformSelector, C as SnapshotQualityVerdict, D as centerOfRect, E as SnapshotVisibility, I as AppleOS, L as DeviceKind, N as isAgentDeviceError, O as DebugSymbolsOptions, P as normalizeAgentDeviceError, R as DeviceTarget, S as SnapshotNode, T as SnapshotUnchanged, V as PublicPlatform, _ as ResponseLevel, a as DaemonRequest, b as Point, g as NetworkIncludeMode, i as DaemonLockPolicy, j as NormalizedError, k as DebugSymbolsResult, o as DaemonResponse, p as LeaseBackend, r as DaemonInstallSource, s as DaemonResponseData, t as DaemonArtifactType, v as SessionIsolationMode, x as ScreenshotOverlayRef, y as SessionRuntimeHints } from "./sdk-contracts.js"; import { t as AppsFilter } from "./sdk-app-inventory.js"; import { t as BatchRunResult } from "./sdk-batch-runner.js"; import { r as FindLocator } from "./sdk-finders.js"; import { p as createLocalArtifactAdapter } from "./sdk-io.js"; import { a as PrepareMetroRuntimeResult, c as MetroBridgeScope, i as MetroPrepareKind, o as ReloadMetroResult, r as RemoteConnectionProfileFields, t as CloudProviderProfileFields } from "./sdk-remote-config.js"; //#region src/platforms/android/snapshot-helper-types.d.ts type AndroidSnapshotHelperTransport = 'instrumentation' | 'persistent-session'; type AndroidSnapshotCaptureMode = 'interactive-windows' | 'active-window'; type AndroidSnapshotHelperInstallReason = 'missing' | 'outdated' | 'forced' | 'current' | 'skipped'; //#endregion //#region src/platforms/android/snapshot-types.d.ts type AndroidSnapshotBackendMetadata = { backend: 'android-helper' | 'uiautomator-dump'; helperVersion?: string; helperApiVersion?: string; helperTransport?: AndroidSnapshotHelperTransport; helperSessionReused?: boolean; fallbackReason?: string; installReason?: AndroidSnapshotHelperInstallReason; waitForIdleTimeoutMs?: number; waitForIdleQuietMs?: number; timeoutMs?: number; maxDepth?: number; maxNodes?: number; rootPresent?: boolean; captureMode?: AndroidSnapshotCaptureMode; windowCount?: number; nodeCount?: number; helperTruncated?: boolean; elapsedMs?: number; }; //#endregion //#region src/snapshot-capture-annotations.d.ts type SnapshotCaptureAnalysis = { rawNodeCount: number; maxDepth: number; }; type SnapshotCaptureFreshness = { action: string; retryCount: number; staleAfterRetries: boolean; reason?: 'empty-interactive' | 'sharp-drop' | 'stuck-route'; }; type SnapshotCaptureAnnotations = { analysis?: SnapshotCaptureAnalysis; androidSnapshot?: AndroidSnapshotBackendMetadata; freshness?: SnapshotCaptureFreshness; quality?: SnapshotQualityVerdict; warnings?: string[]; }; type PublicSnapshotCaptureAnnotations = Pick & { snapshotQuality?: SnapshotQualityVerdict; }; //#endregion //#region src/snapshot-diagnostics.d.ts type SnapshotTimingStats = { count: number; p50Ms: number; p95Ms: number; maxMs: number; slowThresholdMs: number; platform?: PublicPlatform; backends?: Record; }; type SnapshotDiagnosticsSummary = { stats: SnapshotTimingStats; warning?: string; }; //#endregion //#region src/core/back-mode.d.ts declare const BACK_MODES: readonly ['in-app', 'system']; type BackMode = (typeof BACK_MODES)[number]; //#endregion //#region src/core/click-button.d.ts declare const CLICK_BUTTONS: readonly ['primary', 'secondary', 'middle']; type ClickButton = (typeof CLICK_BUTTONS)[number]; //#endregion //#region src/core/recording-export-quality.d.ts declare const RECORDING_EXPORT_QUALITIES: readonly ['medium', 'high']; type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number]; //#endregion //#region src/core/recording-scope.d.ts declare const RECORDING_SCOPE_VALUES: readonly ['app', 'device', 'system']; type RecordingScope = (typeof RECORDING_SCOPE_VALUES)[number]; //#endregion //#region src/core/device-rotation.d.ts declare const DEVICE_ROTATIONS: readonly ['portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right']; type DeviceRotation = (typeof DEVICE_ROTATIONS)[number]; //#endregion //#region src/core/tv-remote.d.ts declare const TV_REMOTE_BUTTON_DEFINITIONS: { readonly up: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_DPAD_UP'; readonly appleRemoteButton: 'up'; }; readonly down: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_DPAD_DOWN'; readonly appleRemoteButton: 'down'; }; readonly left: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_DPAD_LEFT'; readonly appleRemoteButton: 'left'; }; readonly right: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_DPAD_RIGHT'; readonly appleRemoteButton: 'right'; }; readonly select: { readonly aliases: readonly ["ok", "center", "enter"]; readonly androidKeyevent: 'KEYCODE_DPAD_CENTER'; readonly appleRemoteButton: 'select'; }; readonly menu: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_MENU'; readonly appleRemoteButton: 'menu'; }; readonly home: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_HOME'; readonly appleRemoteButton: 'home'; }; readonly back: { readonly aliases: readonly []; readonly androidKeyevent: 'KEYCODE_BACK'; readonly appleRemoteButton: 'menu'; }; }; declare const TV_REMOTE_BUTTONS: (keyof typeof TV_REMOTE_BUTTON_DEFINITIONS)[]; type TvRemoteButton = (typeof TV_REMOTE_BUTTONS)[number]; //#endregion //#region src/core/scroll-gesture.d.ts declare const SCROLL_DIRECTIONS: readonly ['up', 'down', 'left', 'right']; type ScrollDirection = (typeof SCROLL_DIRECTIONS)[number]; declare const SWIPE_PRESETS: readonly ['left', 'right', 'left-edge', 'right-edge']; type SwipePreset = (typeof SWIPE_PRESETS)[number]; declare const SWIPE_PATTERNS: readonly ['one-way', 'ping-pong']; type SwipePattern = (typeof SWIPE_PATTERNS)[number]; type TransformGestureParams = { x: number; y: number; dx: number; dy: number; scale: number; degrees: number; durationMs?: number; }; //#endregion //#region src/alert-contract.d.ts declare const ALERT_ACTIONS: readonly ['get', 'accept', 'dismiss', 'wait']; type AlertAction = (typeof ALERT_ACTIONS)[number]; //#endregion //#region src/contracts/json.d.ts type JsonPrimitive = string | number | boolean | null; type JsonValue = JsonPrimitive | JsonObject | JsonValue[]; type JsonObject = { [key: string]: JsonValue; }; //#endregion //#region src/core/session-surface.d.ts declare const SESSION_SURFACES: readonly ['app', 'frontmost-app', 'desktop', 'menubar']; type SessionSurface = (typeof SESSION_SURFACES)[number]; //#endregion //#region src/utils/screenshot-result.d.ts type ScreenshotResultData = { path?: string; width?: number; height?: number; logicalWidth?: number; logicalHeight?: number; pixelDensity?: number; overlayRefs?: ScreenshotOverlayRef[]; }; //#endregion //#region src/contracts/interaction.d.ts type ResolvedTarget = { kind: 'selector'; selector: string; } | { kind: 'ref'; ref: string; }; type ResolvedInteractionTarget = { kind: 'point'; point: Point; preActionNodes?: SnapshotNode[]; } | { kind: 'ref'; point?: Point; target: Extract; node?: SnapshotNode; selectorChain?: string[]; refLabel?: string; targetHittable?: boolean; hint?: string; preActionNodes?: SnapshotNode[]; } | { kind: 'selector'; point: Point; target: Extract; node: SnapshotNode; selectorChain: string[]; refLabel?: string; targetHittable?: boolean; hint?: string; preActionNodes?: SnapshotNode[]; }; /** * Opt-in (`--verify`) cheap post-condition evidence for mutating interaction * commands (#1047). `digest`/`nodeCount`/`interactiveNodeCount` describe a single * interactive-only capture taken right after the action; `changedFromBefore` * compares that digest against the pre-action capture the resolution path already * held, so no extra device round trip is spent beyond the one verify capture. * `changedFromBefore: false` is evidence, not failure — the command still * succeeded. */ type InteractionEvidence = { foregroundApp?: string; nodeCount: number; interactiveNodeCount: number; digest: string; changedFromBefore: boolean; }; type SettleDiffLine = { kind: 'added' | 'removed'; text: string; /** * Plain ref body (`e12`) for ADDED lines: minted from the settled tree that * became the stored session snapshot, so it is immediately actionable and * lets the MCP layer pin it at `refsGeneration`. Removed lines never carry * one — their refs name nodes of the replaced tree. */ ref?: string; }; /** * One still-present, actionable element on the settled tree, surfaced by the * unchanged-interactive tail (see `SettleObservation.tail`). */ type SettleTailEntry = { ref: string; role: string; label?: string; }; type SettleObservation = { settled: boolean; waitedMs: number; captures: number; quietMs: number; timeoutMs: number; /** * The session's snapshot generation after the settled tree became the stored * snapshot (#1076 versioned refs). Attached by the daemon response layer * when `diff` is present: added lines carry refs minted from that tree, so * the response is ref-issuing — the MCP layer merges per-ref pins from it * exactly like snapshot/find responses. */ refsGeneration?: number; /** * Digest response view only: capped added-line refs preserved without the * verbose diff line text, so MCP can still pin refs when `diff.lines` is * intentionally omitted. */ refs?: Array<{ ref: string; }>; /** Present only for `settled: true` observations that stored the settled tree. */ diff?: { summary: { additions: number; removals: number; unchanged: number; }; lines: SettleDiffLine[]; /** Present (true) when lines were capped to the response bound. */ truncated?: boolean; }; /** * Unchanged interactive refs tail: benchmarks (July 2026) showed 27% of * `--settle` actions were followed by a fallback `snapshot -i` because a * change-only diff omits refs for elements that did not change — after a * modal dismiss the diff shows only removals, and the next button to press * (already on screen, untouched) is absent from the response. `tail` lists * the settled tree's remaining uncovered interactive elements (excluding * structural application/window chrome and the keyboard window's chrome) * so the response stays actionable without that extra round trip. Attached * ONLY when `diff` carries zero added-line refs naming a NEW target (the * modal-dismiss/toast-only/fill signature) — a diff whose added refs hand * the next target already pays its way, so the tail would be pure byte * cost. Keyboard-chrome refs and self-echo refs (added lines whose node * contains the action point: the acted-on element re-describing itself, * e.g. a filled field re-labeled with its new value) do not count as new * targets. Refs already present on `diff`'s added lines are excluded. * Capped; `tailTruncated` marks when candidates exceeded the cap. */ tail?: SettleTailEntry[]; tailTruncated?: true; hint?: string; }; type PressCommandResult = ResolvedInteractionTarget & { backendResult?: Record; message?: string; warning?: string; evidence?: InteractionEvidence; settle?: SettleObservation; }; type FillCommandResult = ResolvedInteractionTarget & { text: string; warning?: string; backendResult?: Record; message?: string; evidence?: InteractionEvidence; settle?: SettleObservation; }; type LongPressCommandResult = ResolvedInteractionTarget & { durationMs?: number; backendResult?: Record; message?: string; warning?: string; settle?: SettleObservation; }; //#endregion //#region src/commands/interaction/runtime/gestures.d.ts declare const SCROLL_INPUT_DIRECTIONS: readonly ['up', 'down', 'left', 'right', 'top', 'bottom']; type ScrollInputDirection = (typeof SCROLL_INPUT_DIRECTIONS)[number]; //#endregion //#region src/contracts/logs.d.ts declare const LOG_ACTION_VALUES: readonly ['path', 'start', 'stop', 'doctor', 'mark', 'clear']; type LogAction = (typeof LOG_ACTION_VALUES)[number]; //#endregion //#region src/target-shutdown-contract.d.ts type TargetShutdownResult = { success: boolean; exitCode: number; stdout: string; stderr: string; error?: NormalizedError; }; //#endregion //#region src/contracts/perf.d.ts declare const PERF_AREA_VALUES: readonly ['metrics', 'frames', 'memory', 'cpu', 'trace']; declare const PERF_ACTION_VALUES: readonly ['sample', 'snapshot', 'start', 'stop', 'report']; declare const PERF_SUBJECT_VALUES: readonly ['profile']; declare const PERF_KIND_VALUES: readonly ['xctrace', 'simpleperf', 'perfetto', 'android-hprof', 'memgraph']; type PerfArea = (typeof PERF_AREA_VALUES)[number]; type PerfAction = (typeof PERF_ACTION_VALUES)[number]; type PerfSubject = (typeof PERF_SUBJECT_VALUES)[number]; type PerfKind = (typeof PERF_KIND_VALUES)[number]; //#endregion //#region src/contracts/device.d.ts /** * Closed result of the `boot` command. Mirrors the daemon handler's only * success return EXACTLY (src/daemon/handlers/session-state.ts) — the fixed * object literal `{ platform, target, device, id, kind, booted }` plus the * additive `appleOs` discriminant, emitted only for Apple devices. */ type BootCommandResult = { platform: PublicPlatform; target: DeviceTarget; /** Human-readable device name (`device.name`). */ device: string; /** Stable device id (`device.id`). */ id: string; kind: DeviceKind; /** Always `true` on the success path. */ booted: true; /** * Additive Apple-OS discriminant (`device.appleOs`): iPhone/iPad/tvOS/visionOS/macOS. * Present only for Apple devices; absent for non-Apple platforms. `platform` stays the * leaf (`ios`/`macos`) — this is an extra field, not a replacement. */ appleOs?: AppleOS; }; /** * Closed result of the `shutdown` command. Mirrors the daemon handler's success * return EXACTLY (src/daemon/handlers/session-state.ts) — the fixed object * literal `{ platform, target, device, id, kind, shutdown }` plus the additive * `appleOs` discriminant (Apple devices only). The `shutdown` field is the raw * {@link TargetShutdownResult} from `shutdownDeviceTarget`. */ type ShutdownCommandResult = { platform: PublicPlatform; target: DeviceTarget; /** Human-readable device name (`device.name`). */ device: string; /** Stable device id (`device.id`). */ id: string; kind: DeviceKind; shutdown: TargetShutdownResult; /** * Additive Apple-OS discriminant (`device.appleOs`): iPhone/iPad/tvOS/visionOS/macOS. * Present only for Apple devices; absent for non-Apple platforms. `platform` stays the * leaf (`ios`/`macos`) — this is an extra field, not a replacement. */ appleOs?: AppleOS; }; //#endregion //#region src/contracts/viewport.d.ts /** * Closed result of the `viewport` command. Mirrors the dispatch handler's return * EXACTLY (src/core/dispatch.ts `handleViewportCommand`) — `{ width, height }` * plus the always-present `successText` message. The generic dispatch path * returns this object unchanged (viewport has no Android dialog guard, so no * `warning` is ever appended), so the shape is intentionally closed. */ type ViewportCommandResult = { width: number; height: number; message: string; }; //#endregion //#region src/contracts/navigation.d.ts /** * Closed results of the navigation/global action commands. Each mirrors the * dispatch handler's literal return EXACTLY (src/core/dispatch.ts * `DISPATCH_HANDLERS`): a fixed `action` discriminant plus the always-present * `successText` message (the handlers always pass a non-empty message, so it is * required here). The handlers spread nothing else, so the shapes are closed — * consistent with the `viewport` contract, the generic-dispatch Android * dialog-recovery `warning` annotation is intentionally not part of the contract. */ /** `home` — `{ action: 'home', message: 'Home' }`. */ type HomeCommandResult = { action: 'home'; message: string; }; /** `back` — `{ action: 'back', mode, message: 'Back' }`; `mode` defaults to `'in-app'`. */ type BackCommandResult = { action: 'back'; mode: BackMode; message: string; }; /** `rotate` — `{ action: 'rotate', orientation, message: 'Rotated to ' }`. */ type RotateCommandResult = { action: 'rotate'; orientation: DeviceRotation; message: string; }; /** `app-switcher` — `{ action: 'app-switcher', message: 'Opened app switcher' }`. */ type AppSwitcherCommandResult = { action: 'app-switcher'; message: string; }; /** `tv-remote` — `{ action: 'tv-remote', button, durationMs?, message }`. */ type TvRemoteCommandResult = { action: 'tv-remote'; button: TvRemoteButton; durationMs?: number; message: string; }; //#endregion //#region src/contracts/clipboard.d.ts /** * Closed result of the `clipboard` command. Mirrors the dispatch handler's * literal return EXACTLY (src/core/dispatch.ts `handleClipboardCommand`): a * discriminated union on `action`. `read` returns the clipboard `text`; `write` * reports the written `textLength` plus the `successText` message. The handler * spreads nothing else, so each branch is closed. */ type ClipboardCommandResult = { action: 'read'; text: string; } | { action: 'write'; textLength: number; message: string; }; //#endregion //#region src/contracts/app-state.d.ts /** * Closed result of the `appstate` command, grounded in the daemon handler's * success returns (src/daemon/handlers/session-state.ts `handleAppStateCommand`). * A discriminated union on `platform`: * - Apple (`ios` / `macos`) session state, with iOS-only device locators that * the previous hand-written mirror omitted; and * - Android foreground `package` / `activity`. * * The handler returns one of these fixed objects (errors take the `ok: false` * path), so each branch is closed. */ type AppStateCommandResult = { platform: 'ios' | 'macos'; appName: string; appBundleId?: string; source: 'session'; surface: SessionSurface; /** iOS only — the session device's UDID. */ device_udid?: string; /** iOS only — the simulator set path, or `null` when unknown. */ ios_simulator_device_set?: string | null; } | { platform: 'android'; package: string; activity: string; }; //#endregion //#region src/contracts/keyboard.d.ts /** * Closed result of the `keyboard` command, grounded in the dispatch handlers' * literal returns (src/core/dispatch.ts `handleAndroidKeyboardCommand` / * `handleIosKeyboardCommand`). * * `platform` and `action` are always present; the remaining fields appear per * branch (Android `status`/`dismiss` carry the keyboard-state fields; `enter` * and iOS `dismiss` carry a `message`). It is kept as a flat closed shape rather * than a five-way `platform`×`action` union because the per-branch field sets * overlap heavily and the underlying Android keyboard-state types live in the * platform layer (below the public contract). The `Record` index signature of * the previous hand-written mirror is dropped, and the spurious `| null`s are * removed (the handler never returns `null` for these). */ type KeyboardCommandResult = { platform: 'android' | 'ios'; action: 'status' | 'dismiss' | 'enter'; visible?: boolean; wasVisible?: boolean; dismissed?: boolean; attempts?: number; inputType?: string; type?: 'text' | 'number' | 'email' | 'phone' | 'password' | 'datetime' | 'unknown'; inputMethodPackage?: string; focusedPackage?: string; focusedResourceId?: string; inputOwner?: 'app' | 'ime' | 'unknown'; message?: string; }; //#endregion //#region src/contracts/wait.d.ts /** * Public daemon result for `wait`. The runtime-local result carries a `kind` * discriminant, but `toDaemonWaitData` intentionally projects the normal daemon * payload to this compact shape. The direct iOS selector fast path may still * include `kind: 'selector'` additively. */ type WaitCommandResult = { waitedMs: number; kind?: 'selector'; text?: string; selector?: string; captures?: number; nodeCount?: number; hint?: string; warning?: string; }; //#endregion //#region src/contracts/prepare.d.ts type PrepareIosRunnerCacheKind = 'exact' | 'restore-key' | 'miss' | 'external'; type PrepareIosRunnerArtifactState = 'valid' | 'rebuilt'; type PrepareIosRunnerTiming = { totalMs: number; additiveParts: { buildMs?: number; connectAfterBuildMs: number; healthCheckMs: number; }; containment: { connectMs?: ['buildMs']; healthCheckMs: []; }; note: string; }; /** * Public daemon result for `prepare ios-runner`. The runner-local prepare result * is projected by `prepareIosRunnerResponseData` with device identity and timing * guidance before it reaches the client. */ type PrepareCommandResult = { action: 'ios-runner'; platform: PublicPlatform; deviceId: string; deviceName: string; kind: DeviceKind; durationMs: number; runner: JsonObject; cache?: PrepareIosRunnerCacheKind; artifact?: PrepareIosRunnerArtifactState; buildMs?: number; connectMs: number; healthCheckMs: number; xctestrunPath?: string; recoveryReason?: string; failureReason?: string; timing: PrepareIosRunnerTiming; message: string; }; //#endregion //#region src/contracts/push.d.ts type PushCommandResult = { platform: 'ios'; bundleId: string; message: string; } | { platform: 'android'; package: string; action: string; extrasCount: number; message: string; }; //#endregion //#region src/contracts/app-events.d.ts type TriggerAppEventCommandResult = { event: string; eventUrl: string; transport: 'deep-link'; message: string; }; //#endregion //#region src/core/command-descriptor/command-result.d.ts /** * The additive typed-result spine (ADR-0008, Phase 1 step 6). * * Maps a command name to the per-command result type from `src/contracts/*`. It * is SEEDED, not exhaustive: a command is listed here only once its accurate, * closed result shape lives in the contracts layer. Commands whose daemon * handler spreads dynamic/Record data (screenshot overlays, gesture * visualization, perf, logs, …) are deliberately omitted rather than given an * invented shape. * * Batches 1-2 wired `boot` / `shutdown` / `viewport` and the navigation/action * commands `home` / `back` / `rotate` / `app-switcher` alongside the seed * interaction trio. Batch 3 adds `clipboard` (a closed `read`/`write` union) and * `appstate` (a closed `platform` union — Apple session state with the iOS-only * device locators, or Android package/activity). Batch 4 adds `keyboard` (a * closed flat shape). Batch 5 adds the compact daemon projections for `wait`, * `prepare`, `push`, and `trigger-app-event`. Each entry is grounded in a * re-read of the handler's literal return; see the per-type docstrings. */ interface CommandResultMap { press: PressCommandResult; fill: FillCommandResult; longpress: LongPressCommandResult; boot: BootCommandResult; shutdown: ShutdownCommandResult; viewport: ViewportCommandResult; home: HomeCommandResult; back: BackCommandResult; rotate: RotateCommandResult; 'app-switcher': AppSwitcherCommandResult; clipboard: ClipboardCommandResult; appstate: AppStateCommandResult; keyboard: KeyboardCommandResult; 'tv-remote': TvRemoteCommandResult; wait: WaitCommandResult; prepare: PrepareCommandResult; push: PushCommandResult; 'trigger-app-event': TriggerAppEventCommandResult; } /** * The typed result for a command named `N`. Seeded commands resolve to their * contract result type from {@link CommandResultMap}; every other (unmigrated) * command falls back to the untyped `Record` bag. That default * branch is what keeps the mapping total over every command name, so consumers * can switch to `CommandResult` without first migrating every command. */ type CommandResult = N extends keyof CommandResultMap ? CommandResultMap[N] : Record; //#endregion //#region src/cloud-artifacts.d.ts declare const CLOUD_ARTIFACT_KINDS: readonly ['video', 'appium-log', 'device-log', 'automation-log', 'provider-session', 'raw']; type CloudArtifactKind = (typeof CLOUD_ARTIFACT_KINDS)[number]; type CloudArtifactAvailability = 'ready' | 'pending' | 'unavailable' | 'expired'; type CloudArtifact = { provider: string; kind: CloudArtifactKind; name: string; url?: string; providerSessionId?: string; providerArtifactId?: string; contentType?: string; extension?: string; availability?: CloudArtifactAvailability; metadata?: Record; }; type CloudArtifactsStatus = 'ready' | 'pending' | 'unavailable'; type CloudArtifactsResult = { provider: string; status: CloudArtifactsStatus; cloudArtifacts: CloudArtifact[]; providerSessionId?: string; message?: string; }; type DaemonArtifactInventoryEntry = { id: string; artifactType?: DaemonArtifactType; filename: string; mimeType: string; sizeBytes: number; createdAt: string; expiresAt: string; }; type DaemonArtifactsResult = { source: 'daemon'; status: 'ready'; artifacts: DaemonArtifactInventoryEntry[]; message?: string; }; type AgentArtifactsResult = CloudArtifactsResult | DaemonArtifactsResult; type CloudProviderSessionResult = { provider?: string; providerSessionId?: string; cloudArtifacts?: CloudArtifactsResult; } & Record; //#endregion //#region src/client/client-types.d.ts type AgentDeviceDaemonTransport = (req: Omit) => Promise; type AgentDeviceClientConfig = RemoteConnectionProfileFields & CloudProviderProfileFields & { session?: string; lockPolicy?: DaemonLockPolicy; lockPlatform?: PlatformSelector; requestId?: string; sessionIsolation?: SessionIsolationMode; leaseBackend?: LeaseBackend; leaseTtlMs?: number; runtime?: SessionRuntimeHints; cwd?: string; debug?: boolean; cost?: boolean; responseLevel?: ResponseLevel; iosXctestrunFile?: string; iosXctestDerivedDataPath?: string; iosXctestEnvDir?: string; }; type AgentDeviceRequestOverrides = Pick; type AgentDeviceIdentifiers = { session?: string; deviceId?: string; deviceName?: string; udid?: string; serial?: string; appId?: string; appBundleId?: string; package?: string; }; type AgentDeviceSelectionOptions = { platform?: PlatformSelector; target?: DeviceTarget; device?: string; udid?: string; serial?: string; iosSimulatorDeviceSet?: string; androidDeviceAllowlist?: string; }; type AgentDeviceDevice = { platform: PublicPlatform; target: DeviceTarget; kind: DeviceKind; id: string; name: string; booted?: boolean; /** * Additive Apple-OS discriminant (iPhone/iPad/tvOS/visionOS/macOS). Present only for * Apple devices; `platform` still carries the leaf (`ios`/`macos`). */ appleOs?: AppleOS; identifiers: AgentDeviceIdentifiers; ios?: { udid: string; }; android?: { serial: string; }; }; type AgentDeviceCapabilitiesResult = { device: AgentDeviceDevice; availableCommands: string[]; }; type AgentDeviceSessionDevice = { platform: PublicPlatform; target: DeviceTarget; id: string; name: string; /** * Additive Apple-OS discriminant (iPhone/iPad/tvOS/visionOS/macOS). Present only for * Apple devices; `platform` still carries the leaf (`ios`/`macos`). */ appleOs?: AppleOS; identifiers: AgentDeviceIdentifiers; ios?: { udid: string; simulatorSetPath?: string | null; }; android?: { serial: string; }; }; type AgentDeviceSession = { name: string; createdAt: number; sessionStateDir?: string; runnerLogPath?: string; device: AgentDeviceSessionDevice; identifiers: AgentDeviceIdentifiers; }; type StartupPerfSample = { durationMs: number; measuredAt: string; method: string; appTarget?: string; appBundleId?: string; }; type SessionCloseResult = { session: string; shutdown?: TargetShutdownResult; provider?: CloudProviderSessionResult; identifiers: AgentDeviceIdentifiers; }; type CloudArtifactsOptions = AgentDeviceRequestOverrides & { provider?: string; providerSessionId?: string; }; type AppInstallOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { app?: string; appPath: string; }; type AppDeployOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { app: string; appPath: string; }; type AppDeployResult = { app: string; appPath: string; platform: PublicPlatform; appId?: string; bundleId?: string; package?: string; identifiers: AgentDeviceIdentifiers; }; type AppOpenOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { app?: string; url?: string; surface?: SessionSurface; activity?: string; launchConsole?: string; launchArgs?: string[]; relaunch?: boolean; saveScript?: boolean | string; deviceHub?: boolean; noRecord?: boolean; runtime?: SessionRuntimeHints; }; type AppOpenResult = { session: string; sessionStateDir?: string; runnerLogPath?: string; requestLogPath?: string; eventLogPath?: string; appName?: string; appBundleId?: string; appId?: string; startup?: StartupPerfSample; runtime?: SessionRuntimeHints; device?: AgentDeviceSessionDevice; identifiers: AgentDeviceIdentifiers; }; type AppCloseOptions = AgentDeviceRequestOverrides & { app?: string; shutdown?: boolean; }; type AppCloseResult = { session: string; closedApp?: string; shutdown?: TargetShutdownResult; identifiers: AgentDeviceIdentifiers; }; type AppInstallFromSourceOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { source: DaemonInstallSource; retainPaths?: boolean; retentionMs?: number; }; type AppInstallFromSourceResult = { appName?: string; appId?: string; bundleId?: string; packageName?: string; launchTarget: string; installablePath?: string; archivePath?: string; materializationId?: string; materializationExpiresAt?: string; identifiers: AgentDeviceIdentifiers; }; type AppListOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { appsFilter?: AppsFilter; }; type MaterializationReleaseOptions = AgentDeviceRequestOverrides & { materializationId: string; }; type MaterializationReleaseResult = { released: boolean; materializationId: string; identifiers: AgentDeviceIdentifiers; }; type Lease = { leaseId: string; tenantId: string; runId: string; backend: LeaseBackend; leaseProvider?: string; deviceKey?: string; clientId?: string; createdAt?: number; heartbeatAt?: number; expiresAt?: number; }; type LeaseOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { ttlMs?: number; }; type LeaseAllocateOptions = LeaseOptions & { tenant: string; runId: string; leaseBackend?: LeaseBackend; leaseProvider?: string; provider?: string; deviceKey?: string; clientId?: string; }; type LeaseScopedOptions = LeaseOptions & { tenant?: string; runId?: string; leaseId: string; leaseBackend?: LeaseBackend; leaseProvider?: string; provider?: string; deviceKey?: string; clientId?: string; }; type MetroPrepareOptions = { projectRoot?: string; kind?: MetroPrepareKind; publicBaseUrl?: string; proxyBaseUrl?: string; bearerToken?: string; bridgeScope?: MetroBridgeScope; launchUrl?: string; companionProfileKey?: string; companionConsumerKey?: string; port?: number; listenHost?: string; statusHost?: string; startupTimeoutMs?: number; probeTimeoutMs?: number; reuseExisting?: boolean; installDependenciesIfNeeded?: boolean; runtimeFilePath?: string; logPath?: string; }; type MetroPrepareResult = PrepareMetroRuntimeResult; type MetroReloadOptions = { metroHost?: string; metroPort?: number; bundleUrl?: string; timeoutMs?: number; }; type MetroReloadResult = ReloadMetroResult; type CaptureSnapshotOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { interactiveOnly?: boolean; depth?: number; scope?: string; raw?: boolean; forceFull?: boolean; timeoutMs?: number; }; type CaptureSnapshotResult = { nodes: SnapshotNode[]; truncated: boolean; appName?: string; appBundleId?: string; visibility?: SnapshotVisibility; unchanged?: SnapshotUnchanged; snapshotDiagnostics?: SnapshotDiagnosticsSummary; identifiers: AgentDeviceIdentifiers; } & PublicSnapshotCaptureAnnotations; type CaptureScreenshotOptions = AgentDeviceRequestOverrides & { path?: string; overlayRefs?: boolean; pixelDensity?: number; fullscreen?: boolean; maxSize?: number; stabilize?: boolean; normalizeStatusBar?: boolean; surface?: SessionSurface; }; type CaptureScreenshotResult = ScreenshotResultData & { path: string; identifiers: AgentDeviceIdentifiers; }; type DeviceCommandBaseOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions; type WaitCommandTarget = { durationMs: number; text?: never; ref?: never; selector?: never; stable?: never; quietMs?: never; timeoutMs?: never; } | (SelectorSnapshotCommandOptions & { text: string; durationMs?: never; ref?: never; selector?: never; stable?: never; quietMs?: never; timeoutMs?: number; }) | (SelectorSnapshotCommandOptions & { ref: string; durationMs?: never; text?: never; selector?: never; stable?: never; quietMs?: never; timeoutMs?: number; }) | (SelectorSnapshotCommandOptions & { selector: string; durationMs?: never; text?: never; ref?: never; stable?: never; quietMs?: never; timeoutMs?: number; }) | (SelectorSnapshotCommandOptions & { stable: true; durationMs?: never; text?: never; ref?: never; selector?: never; quietMs?: number; timeoutMs?: number; }); type WaitCommandOptions = DeviceCommandBaseOptions & WaitCommandTarget; type AlertCommandOptions = DeviceCommandBaseOptions & { action?: AlertAction; timeoutMs?: number; }; type AppStateCommandOptions = DeviceCommandBaseOptions; type BackCommandOptions = DeviceCommandBaseOptions & { mode?: BackMode; }; type HomeCommandOptions = DeviceCommandBaseOptions; type RotateCommandOptions = DeviceCommandBaseOptions & { orientation: DeviceRotation; }; type AppSwitcherCommandOptions = DeviceCommandBaseOptions; type KeyboardCommandOptions = DeviceCommandBaseOptions & { action?: 'status' | 'dismiss' | 'enter' | 'return'; }; type ClipboardCommandOptions = (DeviceCommandBaseOptions & { action: 'read'; }) | (DeviceCommandBaseOptions & { action: 'write'; text: string; }); type TvRemoteCommandOptions = DeviceCommandBaseOptions & { button: TvRemoteButton; durationMs?: number; }; type ReactNativeCommandOptions = DeviceCommandBaseOptions & { action: 'dismiss-overlay'; }; type PrepareCommandOptions = DeviceCommandBaseOptions & { action: 'ios-runner'; timeoutMs?: number; }; type DoctorCommandOptions = DeviceCommandBaseOptions & { targetApp?: string; remote?: boolean; }; type ViewportCommandOptions = DeviceCommandBaseOptions & { width: number; height: number; }; type AgentDeviceCommandClient = { wait: (options: WaitCommandOptions) => Promise>; alert: (options?: AlertCommandOptions) => Promise; appState: (options?: AppStateCommandOptions) => Promise>; back: (options?: BackCommandOptions) => Promise>; home: (options?: HomeCommandOptions) => Promise>; rotate: (options: RotateCommandOptions) => Promise>; appSwitcher: (options?: AppSwitcherCommandOptions) => Promise>; keyboard: (options?: KeyboardCommandOptions) => Promise>; clipboard: (options: ClipboardCommandOptions) => Promise>; tvRemote: (options: TvRemoteCommandOptions) => Promise>; reactNative: (options: ReactNativeCommandOptions) => Promise; doctor: (options?: DoctorCommandOptions) => Promise; /** * JSON prepare results include timing.additiveParts for additive wall-clock phases. * Top-level buildMs/connectMs/healthCheckMs are diagnostics and may overlap. */ prepare: (options: PrepareCommandOptions) => Promise>; viewport: (options: ViewportCommandOptions) => Promise>; }; type SelectorSnapshotCommandOptions = Pick; type FindSnapshotCommandOptions = Pick; type PointTarget = { x: number; y: number; ref?: never; selector?: never; label?: never; }; type RefTarget = { ref: string; label?: string; x?: never; y?: never; selector?: never; }; type SelectorTarget = { selector: string; x?: never; y?: never; ref?: never; label?: never; }; type InteractionTarget = PointTarget | RefTarget | SelectorTarget; type ElementTarget = RefTarget | SelectorTarget; type RepeatedPressOptions = { count?: number; intervalMs?: number; holdMs?: number; jitterPx?: number; doubleTap?: boolean; }; type DeviceBootOptions = DeviceCommandBaseOptions & { headless?: boolean; }; type DeviceShutdownOptions = DeviceCommandBaseOptions; type AppPushOptions = DeviceCommandBaseOptions & { app: string; payload: string | JsonObject; }; type AppTriggerEventOptions = DeviceCommandBaseOptions & { event: string; payload?: JsonObject; }; type CaptureDiffOptions = DeviceCommandBaseOptions & Pick & { kind: 'snapshot'; out?: string; }; /** * Opt-in (#1101): after the action, wait for the UI to go quiet and return the * settled diff vs the pre-action tree (`settle` on the result) in the same * response. Best-effort — never fails the action. `settleQuietMs` tunes the * quiet window (default 500ms); `timeoutMs` bounds the settle wait (default * 10s) when `settle` is true. A bare `timeoutMs` without `settle` is ignored * for compatibility; `settleQuietMs` still requires `settle`. */ type SettleCommandOptions = { settle?: boolean; settleQuietMs?: number; timeoutMs?: number; }; type ClickOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & RepeatedPressOptions & SettleCommandOptions & { button?: ClickButton; /** * Opt-in (#1047): return cheap post-action evidence (AX digest, node counts, * changedFromBefore) in the response instead of requiring a follow-up * snapshot to confirm the action had an effect. */ verify?: boolean; }; type PressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & RepeatedPressOptions & SettleCommandOptions & { verify?: boolean; }; type LongPressOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & SettleCommandOptions & { durationMs?: number; }; type SwipeOptions = DeviceCommandBaseOptions & { from: { x: number; y: number; }; to: { x: number; y: number; }; durationMs?: number; count?: number; pauseMs?: number; pattern?: SwipePattern; }; type PanOptions = DeviceCommandBaseOptions & { x: number; y: number; dx: number; dy: number; durationMs?: number; }; type FlingOptions = DeviceCommandBaseOptions & { direction: ScrollDirection; x: number; y: number; distance?: number; durationMs?: number; }; type SwipeGestureOptions = DeviceCommandBaseOptions & { preset: SwipePreset; durationMs?: number; }; type FocusOptions = DeviceCommandBaseOptions & { x: number; y: number; }; type TypeTextOptions = DeviceCommandBaseOptions & { text: string; delayMs?: number; }; type FillOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & SettleCommandOptions & { text: string; delayMs?: number; verify?: boolean; }; type ScrollOptions = DeviceCommandBaseOptions & { direction: ScrollInputDirection; amount?: number; pixels?: number; durationMs?: number; }; type PinchOptions = DeviceCommandBaseOptions & { scale: number; x?: number; y?: number; }; type RotateGestureOptions = DeviceCommandBaseOptions & { degrees: number; x?: number; y?: number; velocity?: number; }; type TransformGestureOptions = DeviceCommandBaseOptions & TransformGestureParams; type GetOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & ElementTarget & { format: 'text' | 'attrs'; }; type IsTextPredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & { predicate: 'text'; selector: string; value: string; }; type IsStatePredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & { predicate: 'visible' | 'hidden' | 'exists' | 'editable' | 'selected' | 'focused'; selector: string; value?: never; }; type IsOptions = IsTextPredicateOptions | IsStatePredicateOptions; type FindBaseOptions = DeviceCommandBaseOptions & FindSnapshotCommandOptions & { locator?: FindLocator; query: string; first?: boolean; last?: boolean; }; type FindOptions = (FindBaseOptions & { action?: 'click' | 'focus' | 'exists' | 'getText' | 'getAttrs'; }) | (FindBaseOptions & { action: 'wait'; timeoutMs?: number; }) | (FindBaseOptions & { action: 'fill' | 'type'; value: string; }); type ReplayRunOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { path: string; update?: boolean; /** @deprecated Use backend: 'maestro'. */ maestro?: boolean; backend?: string; env?: string[]; timeoutMs?: number; }; type ReplayTestOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & { paths: string[]; update?: boolean; /** @deprecated Use backend: 'maestro'. */ maestro?: boolean; backend?: string; env?: string[]; failFast?: boolean; timeoutMs?: number; retries?: number; recordVideo?: boolean; artifactsDir?: string; /** @deprecated Use the CLI --reporter junit: or --report-junit . */ reportJunit?: string; shardAll?: number; shardSplit?: number; }; type BatchStep = { command: string; input: Record; runtime?: SessionRuntimeHints; }; type BatchRunOptions = AgentDeviceRequestOverrides & { steps: BatchStep[]; onError?: 'stop'; maxSteps?: number; out?: string; }; type PerfOptions = DeviceCommandBaseOptions & { area?: PerfArea; subject?: PerfSubject; action?: PerfAction; kind?: PerfKind; template?: string; out?: string; tracePath?: string; }; type LogsOptions = AgentDeviceRequestOverrides & { action?: LogAction; message?: string; restart?: boolean; }; type EventsOptions = AgentDeviceRequestOverrides & { cursor?: string; limit?: number; }; type NetworkOptions = AgentDeviceRequestOverrides & { action?: 'dump' | 'log'; limit?: number; include?: NetworkIncludeMode; }; type AudioOptions = AgentDeviceRequestOverrides & { action?: 'probe'; probeAction?: 'start' | 'status' | 'stop'; durationMs?: number; bucketMs?: number; }; type RecordOptions = AgentDeviceRequestOverrides & { action: 'start' | 'stop'; path?: string; fps?: number; maxSize?: number; quality?: RecordingExportQuality; hideTouches?: boolean; recordingScope?: RecordingScope; }; type TraceOptions = AgentDeviceRequestOverrides & { action: 'start' | 'stop'; path?: string; }; type PermissionTarget = 'camera' | 'microphone' | 'photos' | 'contacts' | 'contacts-limited' | 'notifications' | 'calendar' | 'location' | 'location-always' | 'media-library' | 'motion' | 'reminders' | 'siri' | 'accessibility' | 'screen-recording' | 'input-monitoring'; type SettingsUpdateOptions = (DeviceCommandBaseOptions & { setting: 'clear-app-state'; state: 'clear'; app?: string; }) | (DeviceCommandBaseOptions & { setting: 'wifi' | 'airplane' | 'location'; state: 'on' | 'off'; }) | (DeviceCommandBaseOptions & { setting: 'location'; state: 'set'; latitude: number; longitude: number; }) | (DeviceCommandBaseOptions & { setting: 'animations'; state: 'on' | 'off'; }) | (DeviceCommandBaseOptions & { setting: 'appearance'; state: 'light' | 'dark' | 'toggle'; }) | (DeviceCommandBaseOptions & { setting: 'faceid' | 'touchid'; state: 'match' | 'nonmatch' | 'enroll' | 'unenroll'; }) | (DeviceCommandBaseOptions & { setting: 'fingerprint'; state: 'match' | 'nonmatch'; }) | (DeviceCommandBaseOptions & { setting: 'permission'; state: 'grant' | 'deny' | 'reset'; permission: PermissionTarget; mode?: 'full' | 'limited'; }); type CommandRequestResult = DaemonResponseData; type AgentDeviceClient = { command: AgentDeviceCommandClient; devices: { list: (options?: AgentDeviceRequestOverrides & AgentDeviceSelectionOptions) => Promise; capabilities: (options?: AgentDeviceRequestOverrides & AgentDeviceSelectionOptions) => Promise; boot: (options?: DeviceBootOptions) => Promise>; shutdown: (options?: DeviceShutdownOptions) => Promise>; }; sessions: { list: (options?: AgentDeviceRequestOverrides) => Promise; stateDir: (options?: AgentDeviceRequestOverrides & Pick) => Promise; close: (options?: AgentDeviceRequestOverrides & { shutdown?: boolean; }) => Promise; artifacts: (options?: CloudArtifactsOptions) => Promise; }; apps: { install: (options: AppInstallOptions) => Promise; reinstall: (options: AppDeployOptions) => Promise; installFromSource: (options: AppInstallFromSourceOptions) => Promise; list: (options?: AppListOptions) => Promise; open: (options: AppOpenOptions) => Promise; close: (options?: AppCloseOptions) => Promise; push: (options: AppPushOptions) => Promise>; triggerEvent: (options: AppTriggerEventOptions) => Promise>; }; materializations: { release: (options: MaterializationReleaseOptions) => Promise; }; leases: { allocate: (options: LeaseAllocateOptions) => Promise; heartbeat: (options: LeaseScopedOptions) => Promise; release: (options: LeaseScopedOptions) => Promise<{ released: boolean; provider?: CloudProviderSessionResult; }>; }; metro: { prepare: (options: MetroPrepareOptions) => Promise; reload: (options?: MetroReloadOptions) => Promise; }; capture: { snapshot: (options?: CaptureSnapshotOptions) => Promise; screenshot: (options?: CaptureScreenshotOptions) => Promise; diff: (options: CaptureDiffOptions) => Promise; }; interactions: { click: (options: ClickOptions) => Promise; press: (options: PressOptions) => Promise; longPress: (options: LongPressOptions) => Promise; swipe: (options: SwipeOptions) => Promise; pan: (options: PanOptions) => Promise; fling: (options: FlingOptions) => Promise; swipeGesture: (options: SwipeGestureOptions) => Promise; focus: (options: FocusOptions) => Promise; type: (options: TypeTextOptions) => Promise; fill: (options: FillOptions) => Promise; scroll: (options: ScrollOptions) => Promise; pinch: (options: PinchOptions) => Promise; rotateGesture: (options: RotateGestureOptions) => Promise; transformGesture: (options: TransformGestureOptions) => Promise; get: (options: GetOptions) => Promise; is: (options: IsOptions) => Promise; find: (options: FindOptions) => Promise; }; replay: { run: (options: ReplayRunOptions) => Promise; test: (options: ReplayTestOptions) => Promise; }; batch: { run: (options: BatchRunOptions) => Promise; }; observability: { perf: (options?: PerfOptions) => Promise; logs: (options?: LogsOptions) => Promise; events: (options?: EventsOptions) => Promise; network: (options?: NetworkOptions) => Promise; audio: (options?: AudioOptions) => Promise; }; debug: { symbols: (options: DebugSymbolsOptions) => Promise; }; recording: { record: (options: RecordOptions) => Promise; trace: (options: TraceOptions) => Promise; }; settings: { update: (options: SettingsUpdateOptions) => Promise; }; }; //#endregion //#region src/client/client.d.ts declare function createAgentDeviceClient(config?: AgentDeviceClientConfig, deps?: { transport?: AgentDeviceDaemonTransport; }): AgentDeviceClient; //#endregion export { AppError, centerOfRect, createAgentDeviceClient, createLocalArtifactAdapter, isAgentDeviceError, normalizeAgentDeviceError };