agent-device 0.20.5 → 0.20.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/README.md +5 -3
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.5.apk → agent-device-android-ime-helper-0.20.7.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.5.manifest.json → agent-device-android-ime-helper-0.20.7.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.5.apk → agent-device-android-snapshot-helper-0.20.7.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.5.manifest.json → agent-device-android-snapshot-helper-0.20.7.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +48 -0
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +108 -1
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +630 -89
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +78 -0
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +126 -187
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +32 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +212 -0
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +149 -10
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +161 -32
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +4 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -28
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +23 -5
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +10 -0
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -67
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +18 -1
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +2 -22
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +4 -0
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +2 -1
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +145 -20
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -20
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +4 -0
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +234 -0
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +106 -448
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +4 -0
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +602 -0
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +18 -0
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.h +72 -0
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.m +89 -0
  37. package/dist/src/agent-browser-tool.js +1 -1
  38. package/dist/src/agent-device-client.js +2 -2
  39. package/dist/src/android-adb.js +1 -1
  40. package/dist/src/android.js +1 -1
  41. package/dist/src/app-helpers.js +1 -1
  42. package/dist/src/app-lifecycle.js +7 -7
  43. package/dist/src/app-lifecycle2.js +2 -0
  44. package/dist/src/app-log-files.js +1 -0
  45. package/dist/src/app-log-reconnect.js +1 -0
  46. package/dist/src/app-log-runtime.js +4 -0
  47. package/dist/src/app-resolution.js +2 -1
  48. package/dist/src/apps.js +5 -5
  49. package/dist/src/audio-probe.js +1 -1
  50. package/dist/src/auth-session.js +1 -0
  51. package/dist/src/auth.js +2 -0
  52. package/dist/src/boot-diagnostics.js +2 -2
  53. package/dist/src/cli-config.js +1 -1
  54. package/dist/src/cli-grammar.js +1 -0
  55. package/dist/src/cli-help.js +204 -254
  56. package/dist/src/cli-output.js +1 -0
  57. package/dist/src/cli-runner.js +1 -2
  58. package/dist/src/cli.js +6 -16
  59. package/dist/src/client-metro.js +1 -1
  60. package/dist/src/cloud-artifacts.d.ts +2 -137
  61. package/dist/src/command-metadata.js +1 -1
  62. package/dist/src/command-schema.js +3 -3
  63. package/dist/src/connection-runtime.js +1 -0
  64. package/dist/src/connection.js +5 -0
  65. package/dist/src/context.js +1 -1
  66. package/dist/src/daemon-shutdown-report.js +1 -0
  67. package/dist/src/daemon.js +2 -0
  68. package/dist/src/debug-symbols.js +3 -3
  69. package/dist/src/device-claim-inspection.js +1 -0
  70. package/dist/src/device-input-state.js +2 -2
  71. package/dist/src/device.js +1 -1
  72. package/dist/src/device2.js +2 -0
  73. package/dist/src/find.js +1 -1
  74. package/dist/src/finders.js +1 -1
  75. package/dist/src/generic-settle.js +1 -0
  76. package/dist/src/generic.js +1 -1
  77. package/dist/src/harmonyos.js +1 -0
  78. package/dist/src/helper.js +1 -1
  79. package/dist/src/host-process.js +2 -2
  80. package/dist/src/ime-lifecycle.js +7 -7
  81. package/dist/src/index.d.ts +69 -18
  82. package/dist/src/input-actions.js +4 -4
  83. package/dist/src/input-actions2.js +1 -1
  84. package/dist/src/input-actions3.js +1 -0
  85. package/dist/src/install-artifact.js +1 -5
  86. package/dist/src/install-artifact2.js +1 -1
  87. package/dist/src/install-source2.js +1 -1
  88. package/dist/src/interaction-runtime.js +1 -0
  89. package/dist/src/interaction-snapshot.js +1 -1
  90. package/dist/src/interaction-touch-reference-frame.js +1 -0
  91. package/dist/src/interaction.js +1 -1
  92. package/dist/src/interactor.js +2 -2
  93. package/dist/src/interactor2.js +1 -1
  94. package/dist/src/internal/bin.js +2 -2
  95. package/dist/src/internal/daemon.js +9 -16
  96. package/dist/src/inventory.js +5 -0
  97. package/dist/src/inventory2.js +1 -0
  98. package/dist/src/inventory3.js +2 -0
  99. package/dist/src/inventory4.js +1 -0
  100. package/dist/src/inventory5.js +1 -0
  101. package/dist/src/inventory6.js +1 -0
  102. package/dist/src/lease-context.js +1 -1
  103. package/dist/src/lease.js +1 -1
  104. package/dist/src/limrun-runtime-dependencies.js +1 -0
  105. package/dist/src/limrun.d.ts +10 -104
  106. package/dist/src/limrun.js +1 -1
  107. package/dist/src/linux.js +1 -1
  108. package/dist/src/logcat.js +1 -1
  109. package/dist/src/manifest.js +1 -1
  110. package/dist/src/owner-identity.js +1 -0
  111. package/dist/src/physical-device-control.js +1 -1
  112. package/dist/src/platform-runtime-app-log-android-transport.js +1 -0
  113. package/dist/src/platform-runtime-app-log-process.js +1 -0
  114. package/dist/src/platform-runtime-host.js +1 -0
  115. package/dist/src/platform-runtime-network-web-transport.js +1 -0
  116. package/dist/src/platform-runtime-operation-host.js +5 -0
  117. package/dist/src/platform-runtime-toolchain-host.js +1 -0
  118. package/dist/src/platform-runtime.js +1 -0
  119. package/dist/src/prepare-kind.js +15 -0
  120. package/dist/src/process-entry.js +1 -0
  121. package/dist/src/process-exit.js +1 -0
  122. package/dist/src/process-lock.js +1 -1
  123. package/dist/src/provider-webdriver.js +1 -0
  124. package/dist/src/provider.js +1 -0
  125. package/dist/src/proxy.js +2 -0
  126. package/dist/src/react-native.js +1 -1
  127. package/dist/src/record-trace.js +1 -1
  128. package/dist/src/registry.js +25 -24
  129. package/dist/src/remote-config.js +1 -1
  130. package/dist/src/remote-config2.js +1 -1
  131. package/dist/src/replay.js +3 -0
  132. package/dist/src/reporting.js +4 -4
  133. package/dist/src/runner-client.js +1 -1
  134. package/dist/src/runner-disposal.js +1 -1
  135. package/dist/src/runner-lease.js +1 -1
  136. package/dist/src/runtime.js +3 -3
  137. package/dist/src/runtime2.js +4 -0
  138. package/dist/src/runtime3.js +3 -0
  139. package/dist/src/runtime4.js +1 -0
  140. package/dist/src/runtime5.js +1 -0
  141. package/dist/src/runtime6.js +1 -0
  142. package/dist/src/runtime7.js +1 -0
  143. package/dist/src/screenshot-result.js +4 -4
  144. package/dist/src/screenshot.js +1 -0
  145. package/dist/src/sdk-android-adb.d.ts +20 -2
  146. package/dist/src/sdk-android-adb.js +2 -2
  147. package/dist/src/sdk-batch-runner.js +3 -3
  148. package/dist/src/sdk-contracts.d.ts +47 -6
  149. package/dist/src/sdk-contracts.js +1 -1
  150. package/dist/src/sdk-device.js +1 -1
  151. package/dist/src/sdk-finders.d.ts +4 -20
  152. package/dist/src/sdk-finders.js +1 -1
  153. package/dist/src/sdk-remote-config.js +1 -1
  154. package/dist/src/sdk-selectors.d.ts +601 -0
  155. package/dist/src/sdk-selectors.js +1 -1
  156. package/dist/src/selector-runtime.js +1 -1
  157. package/dist/src/selector-vocabulary.js +1 -1
  158. package/dist/src/selectors.d.ts +1 -46
  159. package/dist/src/selectors.js +1 -1
  160. package/dist/src/server.js +3 -3
  161. package/dist/src/session-target-evidence.js +1 -1
  162. package/dist/src/session.js +10 -9
  163. package/dist/src/shared.js +2 -0
  164. package/dist/src/shell-quote.js +1 -0
  165. package/dist/src/simulator.js +1 -1
  166. package/dist/src/snapshot-runtime.js +1 -0
  167. package/dist/src/snapshot-session.js +1 -0
  168. package/dist/src/snapshot.js +1 -1
  169. package/dist/src/snapshot2.js +1 -1
  170. package/dist/src/src.js +1 -1
  171. package/dist/src/src2.js +2 -0
  172. package/dist/src/src3.js +1 -0
  173. package/dist/src/text-surface.js +1 -0
  174. package/dist/src/timing-safe-equal.js +1 -0
  175. package/dist/src/tool-provider.js +3 -3
  176. package/dist/src/tool-provider2.js +1 -1
  177. package/dist/src/tool-provider3.js +1 -1
  178. package/dist/src/update-check.js +1 -1
  179. package/dist/src/version.js +1 -1
  180. package/dist/src/web.js +1 -1
  181. package/package.json +72 -50
  182. package/server.json +3 -3
  183. package/skills/agent-device/SKILL.md +6 -31
  184. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.5.apk.sha256 +0 -1
  185. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.5.apk.sha256 +0 -1
  186. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -225
  187. package/dist/src/app-log-request-scope.js +0 -1
  188. package/dist/src/devices.js +0 -1
  189. package/dist/src/devices2.js +0 -1
  190. package/dist/src/devices3.js +0 -1
  191. package/dist/src/devices4.js +0 -1
  192. package/dist/src/interaction.d.ts +0 -230
  193. package/dist/src/provider-limrun-runtime.js +0 -1
  194. package/dist/src/register-builtins.js +0 -1
  195. package/dist/src/screenshot-geometry.js +0 -1
  196. package/dist/src/viewport-dimension.js +0 -14
@@ -0,0 +1,601 @@
1
+ import { A as SnapshotNode, D as Rect, E as RawSnapshotNode, M as SnapshotQualityVerdict, N as SnapshotState, O as ScreenshotOverlayRef, T as Point, U as PublicPlatform, V as Platform, j as SnapshotOptions$1, k as SnapshotBackend, m as ResponseCost } from "./sdk-contracts.js";
2
+ import { c as ScrollDirection, o as GesturePlan } from "./sdk-android-adb.js";
3
+ //#region packages/contracts/src/back-mode.d.ts
4
+ declare const BACK_MODES: readonly ['in-app', 'system'];
5
+ type BackMode = (typeof BACK_MODES)[number];
6
+ //#endregion
7
+ //#region packages/contracts/src/click-button.d.ts
8
+ declare const CLICK_BUTTONS: readonly ['primary', 'secondary', 'middle'];
9
+ type ClickButton = (typeof CLICK_BUTTONS)[number];
10
+ //#endregion
11
+ //#region packages/contracts/src/device-rotation.d.ts
12
+ declare const DEVICE_ROTATIONS: readonly ['portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right'];
13
+ type DeviceRotation = (typeof DEVICE_ROTATIONS)[number];
14
+ //#endregion
15
+ //#region packages/contracts/src/tv-remote.d.ts
16
+ declare const TV_REMOTE_BUTTON_DEFINITIONS: {
17
+ readonly up: {
18
+ readonly aliases: readonly [];
19
+ readonly androidKeyevent: 'KEYCODE_DPAD_UP';
20
+ readonly appleRemoteButton: 'up';
21
+ readonly vegaKey: 'KEY_UP';
22
+ };
23
+ readonly down: {
24
+ readonly aliases: readonly [];
25
+ readonly androidKeyevent: 'KEYCODE_DPAD_DOWN';
26
+ readonly appleRemoteButton: 'down';
27
+ readonly vegaKey: 'KEY_DOWN';
28
+ };
29
+ readonly left: {
30
+ readonly aliases: readonly [];
31
+ readonly androidKeyevent: 'KEYCODE_DPAD_LEFT';
32
+ readonly appleRemoteButton: 'left';
33
+ readonly vegaKey: 'KEY_LEFT';
34
+ };
35
+ readonly right: {
36
+ readonly aliases: readonly [];
37
+ readonly androidKeyevent: 'KEYCODE_DPAD_RIGHT';
38
+ readonly appleRemoteButton: 'right';
39
+ readonly vegaKey: 'KEY_RIGHT';
40
+ };
41
+ readonly select: {
42
+ readonly aliases: readonly ["ok", "center", "enter"];
43
+ readonly androidKeyevent: 'KEYCODE_DPAD_CENTER';
44
+ readonly appleRemoteButton: 'select';
45
+ readonly vegaKey: 'KEY_ENTER';
46
+ };
47
+ readonly menu: {
48
+ readonly aliases: readonly [];
49
+ readonly androidKeyevent: 'KEYCODE_MENU';
50
+ readonly appleRemoteButton: 'menu';
51
+ readonly vegaKey: 'KEY_MENU';
52
+ };
53
+ readonly home: {
54
+ readonly aliases: readonly [];
55
+ readonly androidKeyevent: 'KEYCODE_HOME';
56
+ readonly appleRemoteButton: 'home';
57
+ readonly vegaKey: 'KEY_HOMEPAGE';
58
+ };
59
+ readonly back: {
60
+ readonly aliases: readonly [];
61
+ readonly androidKeyevent: 'KEYCODE_BACK';
62
+ readonly appleRemoteButton: 'menu';
63
+ readonly vegaKey: 'KEY_BACK';
64
+ };
65
+ };
66
+ declare const TV_REMOTE_BUTTONS: (keyof typeof TV_REMOTE_BUTTON_DEFINITIONS)[];
67
+ type TvRemoteButton = (typeof TV_REMOTE_BUTTONS)[number];
68
+ //#endregion
69
+ //#region packages/contracts/src/settings.d.ts
70
+ type SettingOptions = {
71
+ permissionTarget?: string;
72
+ permissionMode?: string;
73
+ latitude?: number;
74
+ longitude?: number;
75
+ };
76
+ //#endregion
77
+ //#region packages/contracts/src/session-surface.d.ts
78
+ declare const SESSION_SURFACES: readonly ['app', 'frontmost-app', 'desktop', 'menubar'];
79
+ type SessionSurface = (typeof SESSION_SURFACES)[number];
80
+ //#endregion
81
+ //#region packages/contracts/src/snapshot-diagnostics.d.ts
82
+ type SnapshotTimingStats = {
83
+ count: number;
84
+ p50Ms: number;
85
+ p95Ms: number;
86
+ maxMs: number;
87
+ slowThresholdMs: number;
88
+ platform?: PublicPlatform;
89
+ backends?: Record<string, number>;
90
+ };
91
+ type SnapshotDiagnosticsSummary = {
92
+ stats: SnapshotTimingStats;
93
+ warning?: string;
94
+ };
95
+ //#endregion
96
+ //#region packages/contracts/src/snapshot-types.d.ts
97
+ type ScreenshotResultData = {
98
+ path?: string;
99
+ width?: number;
100
+ height?: number;
101
+ logicalWidth?: number;
102
+ logicalHeight?: number;
103
+ pixelDensity?: number;
104
+ overlayRefs?: ScreenshotOverlayRef[];
105
+ };
106
+ type BackendSnapshotResult = {
107
+ nodes?: SnapshotNode[];
108
+ truncated?: boolean;
109
+ backend?: string;
110
+ snapshot?: SnapshotState;
111
+ appName?: string;
112
+ appBundleId?: string;
113
+ snapshotDiagnostics?: SnapshotDiagnosticsSummary;
114
+ analysis?: {
115
+ rawNodeCount: number;
116
+ maxDepth: number;
117
+ };
118
+ androidSnapshot?: AndroidSnapshotBackendMetadata;
119
+ freshness?: {
120
+ action: string;
121
+ retryCount: number;
122
+ staleAfterRetries: boolean;
123
+ reason?: 'empty-interactive' | 'sharp-drop' | 'stuck-route';
124
+ };
125
+ quality?: SnapshotQualityVerdict;
126
+ warnings?: string[];
127
+ };
128
+ type AndroidSnapshotBackendMetadata = {
129
+ backend: 'android-helper';
130
+ helperVersion?: string;
131
+ helperApiVersion?: string;
132
+ helperTransport?: string;
133
+ helperSessionReused?: boolean;
134
+ installReason?: string;
135
+ waitForIdleTimeoutMs?: number;
136
+ waitForIdleQuietMs?: number;
137
+ timeoutMs?: number;
138
+ maxDepth?: number;
139
+ maxNodes?: number;
140
+ rootPresent?: boolean;
141
+ captureMode?: string;
142
+ systemSurfaceOnly?: boolean;
143
+ windowCount?: number;
144
+ nodeCount?: number;
145
+ helperTruncated?: boolean;
146
+ elapsedMs?: number;
147
+ };
148
+ type FindLocator = 'any' | 'text' | 'label' | 'value' | 'role' | 'id';
149
+ //#endregion
150
+ //#region packages/contracts/src/runner-lease-context.d.ts
151
+ type RunnerLogicalLeaseContext = {
152
+ leaseId?: string;
153
+ clientId?: string;
154
+ tenantId?: string;
155
+ runId?: string;
156
+ leaseProvider?: string;
157
+ deviceKey?: string;
158
+ };
159
+ //#endregion
160
+ //#region packages/contracts/src/interactor-types.d.ts
161
+ type RunnerContext = {
162
+ requestId?: string;
163
+ signal?: AbortSignal;
164
+ appBundleId?: string;
165
+ verbose?: boolean;
166
+ logPath?: string;
167
+ traceLogPath?: string;
168
+ iosXctestrunFile?: string;
169
+ iosXctestDerivedDataPath?: string;
170
+ iosXctestEnvDir?: string;
171
+ runnerLeaseContext?: RunnerLogicalLeaseContext;
172
+ };
173
+ type ScreenshotOptions = {
174
+ appBundleId?: string;
175
+ pixelDensity?: number;
176
+ fullscreen?: boolean;
177
+ normalizeStatusBar?: boolean;
178
+ stabilize?: boolean;
179
+ surface?: SessionSurface;
180
+ skipIosSimulatorBootCheck?: boolean;
181
+ captureBackend?: 'runner';
182
+ };
183
+ type ElementSelectorKey = 'id' | 'label' | 'text' | 'value';
184
+ type ElementSelectorTapOptions = {
185
+ key: ElementSelectorKey;
186
+ value: string;
187
+ allowNonHittableCoordinateFallback?: boolean;
188
+ expectedPoint?: Point;
189
+ };
190
+ /**
191
+ * The channel the XCTest runner actually entered text through — the Swift
192
+ * `TextEntryResult.textEntryRoute` (RunnerTests+TextTyping.swift,
193
+ * RunnerTests+SynthesizedTextEntry.swift). Closed set, because the runner is
194
+ * its only producer and the boundary that narrows it
195
+ * (readTypeTextBackendResult, src/platforms/apple/interactions.ts) drops a
196
+ * route it cannot name — so a Swift-side addition would silently vanish. The
197
+ * route-parity test in src/platforms/apple/core/__tests__/interactions.test.ts
198
+ * reads the Swift sources and fails instead.
199
+ */
200
+ declare const TEXT_ENTRY_ROUTES: readonly ['xctest-element', 'synthesized-first-responder', 'synthesized-first-responder-replacement', 'xctest-application-fallback'];
201
+ type TextEntryRoute = (typeof TEXT_ENTRY_ROUTES)[number];
202
+ /**
203
+ * What `Interactor.type` reports back about the entry it performed. Only the
204
+ * Apple runner populates it; every other platform types blind and returns void.
205
+ */
206
+ type TypeTextBackendResult = {
207
+ textEntryRoute?: TextEntryRoute;
208
+ };
209
+ type FillVerificationTarget = {
210
+ resourceId: string | null;
211
+ className: string | null;
212
+ packageName: string | null;
213
+ rect: Rect;
214
+ };
215
+ type FillUnconfirmedVerification = {
216
+ verification: 'unconfirmed';
217
+ requested: string;
218
+ before: string | null;
219
+ after: string | null;
220
+ target: FillVerificationTarget;
221
+ };
222
+ type SnapshotOptions = SnapshotOptions$1 & {
223
+ appBundleId?: string;
224
+ signal?: AbortSignal;
225
+ includeRects?: boolean;
226
+ includeHiddenContentHints?: boolean;
227
+ surface?: SessionSurface;
228
+ };
229
+ type SnapshotResult = Omit<BackendSnapshotResult, 'backend' | 'nodes'> & {
230
+ nodes?: RawSnapshotNode[];
231
+ backend: Extract<SnapshotBackend, 'android' | 'harmonyos-arkui' | 'xctest' | 'linux-atspi' | 'web'>;
232
+ };
233
+ type Interactor = {
234
+ open(app: string, options?: {
235
+ activity?: string;
236
+ appBundleId?: string;
237
+ launchConsole?: string;
238
+ launchArgs?: string[];
239
+ terminateRunningApp?: boolean;
240
+ url?: string;
241
+ }): Promise<void>;
242
+ openDevice(): Promise<void>;
243
+ close(app: string): Promise<void>;
244
+ tap(x: number, y: number): Promise<Record<string, unknown> | void>;
245
+ tapElementSelector?(selector: ElementSelectorTapOptions): Promise<Record<string, unknown> | void>;
246
+ doubleTap(x: number, y: number): Promise<Record<string, unknown> | void>;
247
+ longPress(x: number, y: number, durationMs?: number): Promise<Record<string, unknown> | void>;
248
+ focus(x: number, y: number): Promise<Record<string, unknown> | void>;
249
+ type(text: string, delayMs?: number): Promise<TypeTextBackendResult | void>;
250
+ fillElementSelector?(selector: ElementSelectorTapOptions, text: string, delayMs?: number): Promise<Record<string, unknown> | void>;
251
+ fill(x: number, y: number, text: string, delayMs?: number, options?: {
252
+ allowNonHittableCoordinateFallback?: boolean;
253
+ }): Promise<Record<string, unknown> | void>;
254
+ scroll(direction: ScrollDirection, options?: {
255
+ amount?: number;
256
+ pixels?: number;
257
+ durationMs?: number;
258
+ }): Promise<Record<string, unknown> | void>;
259
+ screenshot(outPath: string, options?: ScreenshotOptions): Promise<void>;
260
+ setViewport?(width: number, height: number): Promise<Record<string, unknown> | void>;
261
+ snapshot(options?: SnapshotOptions): Promise<SnapshotResult>;
262
+ gestureViewport?(): Promise<Rect>;
263
+ back(mode?: BackMode): Promise<void>;
264
+ home(): Promise<void>;
265
+ setOrientation(orientation: DeviceRotation): Promise<{
266
+ orientation?: DeviceRotation;
267
+ } | void>;
268
+ performGesture?(plan: GesturePlan): Promise<Record<string, unknown> | void>;
269
+ appSwitcher(): Promise<void>;
270
+ tvRemote(button: TvRemoteButton, durationMs?: number): Promise<void>;
271
+ readClipboard(): Promise<string>;
272
+ writeClipboard(text: string): Promise<void>;
273
+ setSetting(setting: string, state: string, appId?: string, options?: SettingOptions): Promise<Record<string, unknown> | void>;
274
+ };
275
+ //#endregion
276
+ //#region packages/contracts/src/interaction.d.ts
277
+ /** The decisive criterion separating a resolveSelectorChain winner from its strongest runner-up (ADR 0012). */
278
+ type DisambiguationTiebreak = 'visible' | 'deepest' | 'smallest-area' | 'structural-equivalence';
279
+ /**
280
+ * A disambiguation winner or losing alternative. `diagnosticRef` is an opaque,
281
+ * non-`@` token — never a snapshot ref, never issued via `refsGeneration`,
282
+ * never pinnable or usable as an `@ref` target. Strings are UTF-8 truncated
283
+ * to 256 bytes.
284
+ */
285
+ type ResolutionDiagnosticEntry = {
286
+ diagnosticRef: string;
287
+ role?: string;
288
+ label?: string;
289
+ };
290
+ /**
291
+ * ADR 0012 decision 2: pre-action disclosure of how the acting path resolved
292
+ * its target, including each endpoint of a target-authored drag. Never ref-issuing.
293
+ * `direct-ios`/`not-observed` = the XCTest fast path has no daemon tree to
294
+ * report from; `ref`/`label-fallback` = a stale `@ref` recovered via
295
+ * first-match label lookup, never exact ref provenance; `alternatives` holds
296
+ * at most 5 losing candidates, winner excluded.
297
+ */
298
+ type ResolutionDisclosure = {
299
+ source: 'runtime';
300
+ phase: 'pre-action';
301
+ kind: 'unique';
302
+ } | {
303
+ source: 'runtime';
304
+ phase: 'pre-action';
305
+ kind: 'disambiguated';
306
+ matchCount: number;
307
+ winnerDiagnostic: ResolutionDiagnosticEntry;
308
+ tiebreak: DisambiguationTiebreak;
309
+ alternatives: ResolutionDiagnosticEntry[];
310
+ } | {
311
+ source: 'ref';
312
+ phase: 'pre-action';
313
+ kind: 'exact';
314
+ } | {
315
+ source: 'ref';
316
+ phase: 'pre-action';
317
+ kind: 'label-fallback';
318
+ } | {
319
+ source: 'direct-ios';
320
+ kind: 'not-observed';
321
+ };
322
+ /**
323
+ * Opt-in (`--verify`) cheap post-condition evidence for mutating interaction
324
+ * commands (#1047). `digest`/`nodeCount`/`interactiveNodeCount` describe a single
325
+ * interactive-only capture taken right after the action; `changedFromBefore`
326
+ * compares that digest against the pre-action capture the resolution path already
327
+ * held, so no extra device round trip is spent beyond the one verify capture.
328
+ * `changedFromBefore: false` is evidence, not failure — the command still
329
+ * succeeded.
330
+ */
331
+ type InteractionEvidence = {
332
+ foregroundApp?: string;
333
+ nodeCount: number;
334
+ interactiveNodeCount: number;
335
+ digest: string;
336
+ changedFromBefore: boolean;
337
+ };
338
+ type SettleDiffLine = {
339
+ kind: 'added' | 'removed';
340
+ text: string;
341
+ /**
342
+ * Plain ref body (`e12`) for ADDED lines: minted from the settled tree that
343
+ * became the stored session snapshot, so it is immediately actionable and
344
+ * lets the MCP layer pin it at `refsGeneration`. Removed lines never carry
345
+ * one — their refs name nodes of the replaced tree.
346
+ */
347
+ ref?: string;
348
+ };
349
+ /**
350
+ * One still-present, actionable element on the settled tree, surfaced by the
351
+ * unchanged-interactive tail (see `SettleObservation.tail`).
352
+ */
353
+ type SettleTailEntry = {
354
+ ref: string;
355
+ role: string;
356
+ label?: string;
357
+ };
358
+ type SettleObservation = {
359
+ settled: boolean;
360
+ waitedMs: number;
361
+ captures: number;
362
+ quietMs: number;
363
+ timeoutMs: number;
364
+ /**
365
+ * The session's snapshot generation after the settled tree became the stored
366
+ * snapshot (#1076 versioned refs). Attached by the daemon response layer
367
+ * when `diff` is present: added lines carry refs minted from that tree, so
368
+ * the response is ref-issuing — the MCP layer merges per-ref pins from it
369
+ * exactly like snapshot/find responses.
370
+ */
371
+ refsGeneration?: number;
372
+ /**
373
+ * Digest response view only: capped added-line refs preserved without the
374
+ * verbose diff line text, so MCP can still pin refs when `diff.lines` is
375
+ * intentionally omitted.
376
+ */
377
+ refs?: Array<{
378
+ ref: string;
379
+ }>;
380
+ /** Present only for `settled: true` observations that stored the settled tree. */
381
+ diff?: {
382
+ summary: {
383
+ additions: number;
384
+ removals: number;
385
+ unchanged: number;
386
+ };
387
+ lines: SettleDiffLine[];
388
+ /** Present (true) when lines were capped to the response bound. */
389
+ truncated?: boolean;
390
+ };
391
+ /**
392
+ * Unchanged interactive refs tail: benchmarks (July 2026) showed 27% of
393
+ * `--settle` actions were followed by a fallback `snapshot -i` because a
394
+ * change-only diff omits refs for elements that did not change — after a
395
+ * modal dismiss the diff shows only removals, and the next button to press
396
+ * (already on screen, untouched) is absent from the response. `tail` lists
397
+ * the settled tree's remaining uncovered interactive elements (excluding
398
+ * structural application/window chrome and the keyboard window's chrome)
399
+ * so the response stays actionable without that extra round trip. Attached
400
+ * ONLY when `diff` carries zero added-line refs naming a NEW target (the
401
+ * modal-dismiss/toast-only/fill signature) — a diff whose added refs hand
402
+ * the next target already pays its way, so the tail would be pure byte
403
+ * cost. Keyboard-chrome refs and self-echo refs (added lines whose node
404
+ * contains the action point: the acted-on element re-describing itself,
405
+ * e.g. a filled field re-labeled with its new value) do not count as new
406
+ * targets. Refs already present on `diff`'s added lines are excluded.
407
+ * Capped; `tailTruncated` marks when candidates exceeded the cap.
408
+ */
409
+ tail?: SettleTailEntry[];
410
+ tailTruncated?: true;
411
+ hint?: string;
412
+ };
413
+ /**
414
+ * Public daemon response data shared by press/click/fill/longpress.
415
+ * `buildInteractionResponseData` emits this shape (ADR 0011 Layer 2):
416
+ * `targetKind` discriminates the resolved target, identity fields are FLAT
417
+ * (`ref`, `selector`, `x`, `y`), and per-command extras ride alongside.
418
+ */
419
+ type TouchResponseDataBase = {
420
+ message?: string;
421
+ warning?: string;
422
+ x?: number;
423
+ y?: number;
424
+ referenceWidth?: number;
425
+ referenceHeight?: number;
426
+ evidence?: InteractionEvidence;
427
+ settle?: SettleObservation;
428
+ resolution?: ResolutionDisclosure;
429
+ cost?: ResponseCost;
430
+ /** Direct iOS Maestro coordinate-fallback signals. */
431
+ maestroNonHittableCoordinateFallbackAllowed?: boolean;
432
+ maestroNonHittableCoordinateFallbackUsed?: boolean;
433
+ maestroFallbackReason?: 'non-hittable-coordinate';
434
+ };
435
+ type TouchResponsePoint = TouchResponseDataBase & {
436
+ targetKind: 'point';
437
+ x: number;
438
+ y: number;
439
+ };
440
+ type TouchResponseRef = TouchResponseDataBase & {
441
+ targetKind: 'ref';
442
+ ref: string;
443
+ refLabel?: string;
444
+ selectorChain?: string[];
445
+ targetHittable?: boolean;
446
+ hint?: string;
447
+ };
448
+ type TouchResponseSelector = TouchResponseDataBase & {
449
+ targetKind: 'selector';
450
+ selector: string;
451
+ selectorChain?: string[];
452
+ refLabel?: string;
453
+ targetHittable?: boolean;
454
+ hint?: string;
455
+ };
456
+ type TouchPressExtras = {
457
+ button?: ClickButton;
458
+ count?: number;
459
+ intervalMs?: number;
460
+ holdMs?: number;
461
+ jitterPx?: number;
462
+ doubleTap?: boolean;
463
+ };
464
+ type PressCommandResponseData = (TouchResponsePoint & TouchPressExtras) | (TouchResponseRef & TouchPressExtras) | (TouchResponseSelector & TouchPressExtras);
465
+ type ClickCommandResponseData = PressCommandResponseData;
466
+ type TouchFillExtras = {
467
+ text: string;
468
+ delayMs?: number;
469
+ } & ({
470
+ verification?: never;
471
+ requested?: never;
472
+ before?: never;
473
+ after?: never;
474
+ target?: never;
475
+ } | FillUnconfirmedVerification);
476
+ type FillCommandResponseData = (TouchResponsePoint & TouchFillExtras) | (TouchResponseRef & TouchFillExtras) | (TouchResponseSelector & TouchFillExtras);
477
+ type TouchLongPressExtras = {
478
+ durationMs?: number;
479
+ gesture: 'longpress';
480
+ };
481
+ type LongPressCommandResponseData = (TouchResponsePoint & TouchLongPressExtras) | (TouchResponseRef & TouchLongPressExtras) | (TouchResponseSelector & TouchLongPressExtras);
482
+ /**
483
+ * Daemon response data for the `find` command. Read-only actions (`exists`,
484
+ * `wait`, `get_text`, `get_attrs`) may issue a pinnable ref with
485
+ * `refsGeneration`; mutating actions (`click`, `fill`, `focus`, `type`) carry
486
+ * `ref` as diagnostic pre-action identity and intentionally omit `refsGeneration`
487
+ * (ADR 0014). The shape is intentionally a flat, optional-field record because
488
+ * the action positional changes which fields are present.
489
+ */
490
+ type FindCommandResponseData = {
491
+ ref?: string;
492
+ refsGeneration?: number;
493
+ found?: true;
494
+ waitedMs?: number;
495
+ text?: string;
496
+ node?: SnapshotNode;
497
+ /** Every match of the read-only `list` action (#1625), each ref pinnable at `refsGeneration`. */
498
+ matches?: Array<{
499
+ ref: string;
500
+ node: SnapshotNode;
501
+ }>;
502
+ locator?: string;
503
+ query?: string;
504
+ x?: number;
505
+ y?: number;
506
+ message?: string;
507
+ settle?: SettleObservation;
508
+ cost?: ResponseCost;
509
+ };
510
+ //#endregion
511
+ //#region packages/selectors/src/internal/public-resolution-types.d.ts
512
+ /** One per-alternative diagnostic returned by selector resolution. */
513
+ type SelectorDiagnostics = {
514
+ selector: string;
515
+ matches: number;
516
+ };
517
+ /**
518
+ * The disclosure for an ambiguous selector that was resolved by the heuristic;
519
+ * present only when the heuristic picked among N>1 matches (ADR 0012).
520
+ */
521
+ type SelectorDisambiguationDisclosure = {
522
+ matchCount: number;
523
+ tiebreak: DisambiguationTiebreak;
524
+ /** Every losing matched node, document order, uncapped (response layer caps). */
525
+ alternatives: SnapshotNode[];
526
+ };
527
+ /**
528
+ * The options every selector lookup takes. Stated once here rather than inline
529
+ * per function so a façade wrapper and the parser-side function it forwards to
530
+ * cannot drift apart.
531
+ */
532
+ type SelectorMatchOptions = {
533
+ platform: Platform | PublicPlatform;
534
+ requireRect?: boolean;
535
+ };
536
+ /** {@link SelectorMatchOptions} plus the uniqueness policy resolution adds. */
537
+ type SelectorResolutionOptions = SelectorMatchOptions & {
538
+ requireUnique?: boolean;
539
+ disambiguateAmbiguous?: boolean;
540
+ };
541
+ //#endregion
542
+ //#region packages/selectors/src/internal/parse.d.ts
543
+ type SelectorKey = 'id' | 'role' | 'text' | 'label' | 'value' | 'appname' | 'windowtitle' | 'visible' | 'hidden' | 'editable' | 'selected' | 'focused' | 'enabled' | 'hittable';
544
+ type SelectorTerm = {
545
+ key: SelectorKey;
546
+ value: string | boolean;
547
+ };
548
+ type Selector = {
549
+ raw: string;
550
+ terms: SelectorTerm[];
551
+ };
552
+ type SelectorChain = {
553
+ raw: string;
554
+ selectors: Selector[];
555
+ };
556
+ declare function parseSelectorChain(expression: string): SelectorChain;
557
+ declare function tryParseSelectorChain(expression: string): SelectorChain | null;
558
+ declare function isSelectorToken(token: string): boolean;
559
+ //#endregion
560
+ //#region packages/selectors/src/internal/resolve.d.ts
561
+ /**
562
+ * The parser-side twin of the façade's `SelectorResolution`: identical except
563
+ * that the winning alternative is the `Selector` node itself, which the façade
564
+ * flattens to its `raw` text before any consumer sees it. Only the fields that
565
+ * differ are restated; everything else is shared with
566
+ * `public-resolution-types.ts`.
567
+ */
568
+ type AstSelectorResolution = {
569
+ node: SnapshotNode;
570
+ selector: Selector;
571
+ selectorIndex: number;
572
+ matches: number;
573
+ diagnostics: SelectorDiagnostics[];
574
+ disambiguation?: SelectorDisambiguationDisclosure;
575
+ };
576
+ declare function resolveSelectorChain(nodes: SnapshotState['nodes'], chain: SelectorChain, options: SelectorResolutionOptions): AstSelectorResolution | null;
577
+ /** The parser-side twin of the façade's `SelectorChainMatch`. */
578
+ type AstSelectorChainMatch = {
579
+ selectorIndex: number;
580
+ selector: Selector;
581
+ matches: number;
582
+ diagnostics: SelectorDiagnostics[];
583
+ };
584
+ declare function findSelectorChainMatch(nodes: SnapshotState['nodes'], chain: SelectorChain, options: SelectorMatchOptions): AstSelectorChainMatch | null;
585
+ //#endregion
586
+ //#region packages/selectors/src/internal/node.d.ts
587
+ declare function isNodeVisible(node: SnapshotNode): boolean;
588
+ declare function isNodeEditable(node: SnapshotNode, platform: Platform | PublicPlatform): boolean;
589
+ //#endregion
590
+ //#region packages/selectors/src/ast.d.ts
591
+ /**
592
+ * The published signature takes a parsed chain or the raw text it came from;
593
+ * the engine only ever needs the text. Kept here rather than widening
594
+ * `internal/resolve.ts` back to a union, so the compatibility obligation sits
595
+ * at the boundary that owes it.
596
+ */
597
+ declare function formatSelectorFailure(chain: SelectorChain | string, diagnostics: SelectorDiagnostics[], options: {
598
+ unique?: boolean;
599
+ }): string;
600
+ //#endregion
601
+ export { SessionSurface as C, BackMode as D, ClickButton as E, SnapshotDiagnosticsSummary as S, DeviceRotation as T, Interactor as _, resolveSelectorChain as a, FindLocator as b, parseSelectorChain as c, ClickCommandResponseData as d, FillCommandResponseData as f, SettleObservation as g, PressCommandResponseData as h, findSelectorChainMatch as i, tryParseSelectorChain as l, LongPressCommandResponseData as m, isNodeEditable as n, SelectorChain as o, FindCommandResponseData as p, isNodeVisible as r, isSelectorToken as s, formatSelectorFailure as t, SelectorDiagnostics as u, RunnerContext as v, TvRemoteButton as w, ScreenshotResultData as x, AndroidSnapshotBackendMetadata as y };
@@ -1 +1 @@
1
- import{_ as e,u as t}from"./sdk-contracts.js";import{F as n,U as r,W as i}from"./sdk-batch-runner.js";function a(e,t){return{ok:!1,code:`INVALID_ARGS`,message:e,...t?{hint:t}:{}}}function o(e){return!!(e&&[e.x,e.y,e.width,e.height].every(Number.isFinite)&&e.width>0&&e.height>0)}function s(e,t){return t.x>=e.x&&t.y>=e.y&&t.x+t.width<=e.x+e.width&&t.y+t.height<=e.y+e.height}function c(e){return e.width*e.height}function l(e,n){let r=t(n),i=e.filter(e=>d(e.rect)),a=i.filter(e=>{let t=(e.type??``).toLowerCase();return t.includes(`application`)||t.includes(`window`)});return p(a.map(e=>e.rect).filter(e=>f(e,r.x,r.y)))||p(a.map(e=>e.rect))||p(i.map(e=>e.rect).filter(e=>f(e,r.x,r.y)))||null}function u(e,t){return m(e.x,e.x+e.width,t.x,t.x+t.width)&&m(e.y,e.y+e.height,t.y,t.y+t.height)}function d(e){return e?Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height):!1}function f(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function p(e){let t=null,n=-1;for(let r of e){let e=r.width*r.height;e>n&&(t=r,n=e)}return t}function m(e,t,n,r){return Math.max(e,n)<=Math.min(t,r)}function ee(e){let t=e.trim().toLowerCase();return t?/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(t):!1}function h(e,t){if(!(e?.trim().toLowerCase()??``).includes(`vertical scroll bar`))return null;let n=te(t);return n===null?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}function te(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}function ne(e){let t=new Map;for(let[n,r]of e.entries())t.set(r.index,n);let n=[],r=[];for(let[i,a]of e.entries()){let e=Math.max(0,a.depth??0);for(;r.length>0&&e<=r[r.length-1].depth;)r.pop();let o=i,s=typeof a.parentIndex==`number`?t.get(a.parentIndex):void 0,c=typeof s==`number`&&s<o?s:r[r.length-1]?.index;n.push({...a,index:o,depth:e,parentIndex:c}),r.push({depth:e,index:o})}return n}function g(e){return new Map(e.map(e=>[e.index,e]))}function _(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||``}function v(e){let t=`${e??``}`.toLowerCase();return t.includes(`scroll`)||t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)||t.includes(`collectionview`)||t===`table`}function y(e){return v(e.type)?!0:`${e.role??``} ${e.subrole??``}`.toLowerCase().includes(`scroll`)}function re(e){if(e.length===0)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:i}=b(e),a=n.size===0?e:e.filter(e=>n.has(e.index));return{nodes:a.map(e=>de(e,i.directionsByContainer)),hiddenCount:n.size===0?0:e.length-a.length,summaryLines:fe(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&me(e)),e,t)}}function ie(e){if(e.length===0)return new Map;let{hintedContainers:t}=b(e);return ue(t.directionsByContainer)}function b(e){let t=g(e),n=new Set,r=[];for(let i of e){if(x(i,e,t)){ge(i,n,t);continue}r.push(i)}return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:le(e,r,n,t)}}function x(e,t,n=g(t)){if(!e.rect)return!0;let r=C(e,t,n);return r?u(e.rect,r):!0}function ae(e,t,n=g(t)){if(!e.rect)return!0;if(!x(e,t,n))return!1;let r=l(t,e.rect);return S(e.rect,r)}function S(e,t){return!t||t.width<=0||t.height<=0?!0:f(t,e.x+e.width/2,e.y+e.height/2)}function oe(e,t){return e.hittable&&S(e.rect,t)}function C(e,t,n=g(t)){return ye(e,n)||l(t,e.rect??{x:0,y:0,width:0,height:0})}function se(e,t,n=g(t)){if(!e.rect)return null;let r=C(e,t,n);if(r&&!u(e.rect,r)){let t=ce(e.rect,r);if(t)return t}let i=l(t,e.rect);if(i&&!S(e.rect,i)){let t=ce(e.rect,i);if(t)return t}return null}function ce(e,t){let n=e.x+e.width/2,r=e.y+e.height/2,i=[{direction:`down`,amount:r-(t.y+t.height)},{direction:`up`,amount:t.y-r},{direction:`right`,amount:n-(t.x+t.width)},{direction:`left`,amount:t.x-n}],a=null;for(let e of i)e.amount>0&&(!a||e.amount>a.amount)&&(a=e);return a?.direction??null}function le(e,t,n,r){let i=new Map,a=new Map,o=new Set;for(let e of t){if(!e.rect)continue;let t=T(e,n,r);if(!t?.rect)continue;let s=w(e.rect,t.rect);if(!s)continue;let c=i.get(t.index)??new Set;c.add(s),i.set(t.index,c);let l=a.get(t.index)??new Set;l.add(s),a.set(t.index,l),o.add(e.index)}return _e(e,n,r,i,a),{directionsByContainer:i,coveredNodeIndexes:o}}function ue(e){let t=new Map;for(let[n,r]of e){let e={};r.has(`above`)&&(e.hiddenContentAbove=!0),r.has(`below`)&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n,e)}return t}function de(e,t){let n=t.get(e.index);if(!n||n.size===0)return e;let r=e.hiddenContentAbove===!0||n.has(`above`)?!0:void 0,i=e.hiddenContentBelow===!0||n.has(`below`)?!0:void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:i}}function fe(e,t,n){let r=new Map;for(let i of e){let e=pe(i,t,n);if(!e)continue;let a=r.get(e)??[];a.push(i),r.set(e,a)}return[`above`,`below`].flatMap(e=>{let t=r.get(e);if(!t||t.length===0)return[];let n=he(t).slice(0,3).map(e=>`"${e}"`),i=t.length===1?`interactive item`:`interactive items`,a=n.length>0?`: ${n.join(`, `)}`:``;return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}function pe(e,t,n){if(!e.rect)return null;let r=C(e,t,n);return r?w(e.rect,r):null}function w(e,t){return e.y+e.height<=t.y?`above`:e.y>=t.y+t.height?`below`:null}function me(e){if(e.hittable===!0)return!0;let t=(e.type??``).toLowerCase();return t.includes(`button`)||t.includes(`link`)||t.includes(`textfield`)||t.includes(`edittext`)||t.includes(`searchfield`)||t.includes(`checkbox`)||t.includes(`radio`)||t.includes(`switch`)||t.includes(`menuitem`)||!!_(e)}function he(e){let t=new Set,n=[];for(let r of e){let e=_(r);!e||t.has(e)||(t.add(e),n.push(e))}return n}function ge(e,t,n){let r=e,i=new Set;for(;r&&!i.has(r.index);)i.add(r.index),t.add(r.index),r=typeof r.parentIndex==`number`?n.get(r.parentIndex):void 0}function T(e,t,n){return E(e,n,e=>t.has(e.index))}function _e(e,t,n,r,i){for(let a of e){let e=ve(a);if(!e||e.size===0)continue;let o=T(a,t,n);if(!o)continue;let s=r.get(o.index)??new Set,c=i.get(o.index);for(let t of e)c&&c.size>0&&!c.has(t)||s.add(t);r.set(o.index,s)}}function ve(e){let t=h(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add(`above`),t.below&&n.add(`below`),n.size>0?n:null}function ye(e,t){return E(e,t,e=>!!e.rect)?.rect??null}function E(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0,i=new Set;for(;r&&!i.has(r.index);){if(i.add(r.index),n(r)&&y(r))return r;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}return null}function D(e){let t=O(e.label),n=O(e.value),r=O(e.identifier),i=we(r)?r:``;return A(e.type??``)?n||t||i:t||n||i}function be(e,t){if(t===`text-view`||t===`text-field`||t===`search`)return!0;let n=k(e.type??``),r=`${e.role??``} ${e.subrole??``}`.toLowerCase();return n.includes(`textview`)||n.includes(`textarea`)||n.includes(`textfield`)||n.includes(`securetextfield`)||n.includes(`searchfield`)||n.includes(`edittext`)||r.includes(`text area`)||r.includes(`text field`)}function xe(e){let t=e.replace(/\s+/g,` `).trim();return t.length<=48?t:`${t.slice(0,45)}...`}function Se(e,t){let n=D(e),r=be(e,t);return{text:n,isLargeSurface:r,shouldSummarize:r&&Ce(n)}}function Ce(e){return e?e.length>80||/[\r\n]/.test(e):!1}function O(e){return typeof e==`string`?e.trim():``}function k(e){let t=e.trim().replace(/XCUIElementType/gi,``).replace(/^AX/,``).toLowerCase(),n=Math.max(t.lastIndexOf(`.`),t.lastIndexOf(`/`));return n!==-1&&(t=t.slice(n+1)),t}function A(e){let t=k(e);return t.includes(`textfield`)||t.includes(`securetextfield`)||t.includes(`searchfield`)||t.includes(`edittext`)||t.includes(`textview`)||t.includes(`textarea`)}function we(e){return e?!/^[\w.]+:id\/[\w.-]+$/i.test(e)&&!/^_?NS:\d+$/i.test(e):!1}function Te(e,t){let n=t.toLowerCase();return e.find(e=>{let t=(e.label??``).toLowerCase(),r=(e.value??``).toLowerCase(),i=(e.identifier??``).toLowerCase();return t.includes(n)||r.includes(n)||i.includes(n)})??null}function Ee(e,t){let n=[e.label,e.value,e.identifier].map(e=>typeof e==`string`?e.trim():``).find(e=>e&&e.length>0);return n&&j(n)?n:De(e,t)??(n&&j(n)?n:void 0)}function j(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function De(e,t){if(!e.rect)return;let n=e.rect.y+e.rect.height/2,r=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>typeof e==`string`?e.trim():``).find(e=>e&&e.length>0);if(!t||!j(t))continue;let i=e.rect.y+e.rect.height/2,a=Math.abs(i-n);(!r||a<r.distance)&&(r={label:t,distance:a})}return r?.label}function Oe(e){let t=[],n=[];for(let r of e){let e=r.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let i=k(r.type??``),a=[r.label,r.value,r.identifier].map(e=>typeof e==`string`?e.trim():``).find(e=>e&&e.length>0),o=a?j(a):!1;if((i===`group`||i===`ioscontentgroup`)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);n.push({...r,depth:s})}return n}function M(e,t){let n=k(e);return n?t===`android`?n.includes(`edittext`)||n.includes(`autocompletetextview`):n.includes(`textfield`)||n.includes(`securetextfield`)||n.includes(`searchfield`)||n.includes(`textview`)||n.includes(`textarea`)||n===`search`:!0}function ke(e,t){return t.hittable?t:F(e,t,e=>e.hittable===!0)}function N(e){return new Map(e.map(e=>[e.index,e]))}function P(e,t,n,r){let i=t,a=new Set;for(;typeof i.parentIndex==`number`&&!a.has(i.index);){if(a.add(i.index),i=n.get(i.parentIndex)??e[i.parentIndex],!i)return null;let t=r(i);if(t!==null)return t}return null}function F(e,t,n){return P(e,t,N(e),e=>n(e)?e:null)}function I(e){return[e.label,e.value,e.identifier].map(e=>typeof e==`string`?e.trim():``).filter(e=>e.length>0)[0]??``}function Ae(e){return D(e)}function L(e){return e.hittable===!0?!0:e.rect?e.rect.width>0&&e.rect.height>0:!1}function R(e,t){return M(e.type??``,t)&&e.enabled!==!1}function z(e){return[`visible`,`hidden`,`exists`,`editable`,`selected`,`focused`,`text`].includes(e)}function B(e){let t=e.toLowerCase();return z(t)?{ok:!0,predicate:t}:a(`is requires predicate: visible|hidden|exists|editable|selected|focused|text`,je)}const je=`Use "is <predicate> <selector>" or "is <selector> <predicate>". visible|hidden|editable|selected|focused double as selector keys: a bare predicate token after the selector is read as the predicate, so write key=true (e.g. visible=true) inside the selector to use it as a filter instead.`;function Me(e){if(z((e[0]??``).toLowerCase()))return e;for(let t=1;t<e.length;t+=1){let n=(e[t]??``).toLowerCase();if(z(n)&&i(e.slice(0,t).join(` `)))return[n,...e.slice(0,t),...e.slice(t+1)]}return e}function Ne(e){let{predicate:t,node:n,nodes:r,expectedText:i,platform:a}=e,o=I(n),s=R(n,a),c=n.selected===!0,l=n.focused===!0,u=t===`text`?L(n):Pe(n,r,a),d=!1;switch(t){case`visible`:d=u;break;case`hidden`:d=!u;break;case`editable`:d=s;break;case`selected`:d=c;break;case`focused`:d=l;break;case`text`:d=o===(i??``);break}let f=t===`text`?`expected="${i??``}" actual="${o}"`:`actual=${JSON.stringify({visible:u,editable:s,selected:c,focused:l})}`;return{pass:d,actualText:o,details:f}}function Pe(e,t,n){if(n===`android`&&e.visibleToUser===!1)return!1;if(o(e.rect))return Fe(e,t);if(e.rect)return!1;if(n!==`android`&&e.hittable===!0)return!0;let r=Ie(e,t,n);return r?o(r.rect)?Fe(r,t):n!==`android`&&r.hittable===!0:!1}function Fe(e,t){return x(e,t)}function Ie(e,t,n){return P(t,e,N(t),e=>Le(e,n)?e:null)}function Le(e,t){if(t===`android`&&e.visibleToUser===!1)return!1;let n=k(e.type??``);return n.includes(`application`)||n.includes(`window`)||n.includes(`scrollview`)||n.includes(`tableview`)||n.includes(`collectionview`)||n===`table`||n===`list`||n===`listview`?!1:t===`android`?e.hittable===!0&&o(e.rect):e.hittable===!0||o(e.rect)}function Re(e){let t=Me(e),n=t[0]??``;return{predicate:n,split:r(t.slice(1),{preferTrailingValue:n===`text`})}}const ze=`is requires a selector expression`,Be=`is text requires expected text value`;function Ve(e){let{predicate:t,split:n}=Re([...e]),r=B(t);if(!r.ok)return r;if(!n)return a(ze);let i=n.rest.join(` `).trim();return r.predicate===`text`&&!i?a(Be):r.predicate!==`text`&&n.rest.length>0?a(`is ${r.predicate} does not accept trailing values`):{ok:!0,predicate:r.predicate,selectorExpression:n.selectorExpression,expectedText:i}}function He(e){return e===`text`||e===`attrs`?{ok:!0,format:e}:a(`get only supports text or attrs`)}function Ue(e){let t=e[0];if(t?.startsWith(`@`)){let n=e.slice(1).join(` `).trim();return{ok:!0,ref:t,...n?{label:n}:{}}}let n=e.join(` `).trim();return n?{ok:!0,selector:n}:a(`get requires @ref or selector expression`)}function We(e){return e?{ok:!0,text:e}:a(`wait requires text`)}function V(e,t,n){return t.terms.every(t=>Ge(e,t,n))}function Ge(e,t,n){switch(t.key){case`id`:return H(e.identifier,String(t.value));case`role`:return H(k(e.type??``),String(t.value));case`label`:return H(e.label,String(t.value));case`value`:return H(e.value,String(t.value));case`text`:return H(I(e),String(t.value));case`appname`:return H(e.appName,String(t.value));case`windowtitle`:return H(e.windowTitle,String(t.value));case`visible`:return L(e)===!!t.value;case`hidden`:return!L(e)==!!t.value;case`editable`:return R(e,n)===!!t.value;case`selected`:return e.selected===!0==!!t.value;case`focused`:return e.focused===!0==!!t.value;case`enabled`:return e.enabled!==!1==!!t.value;case`hittable`:return e.hittable===!0==!!t.value;default:return!1}}function H(e,t){return n(e??``)===n(t)}function Ke(e,t,n){let r=n.requireRect??!1,i=n.requireUnique??!0,a=[];for(let[o,s]of t.selectors.entries()){let t=Qe(e,s,n.platform,r);if(a.push({selector:s.raw,matches:t.count}),!(t.count===0||!t.firstNode)){if(i&&t.count!==1){if(!n.disambiguateAmbiguous||!t.disambiguated||!t.tiebreak)continue;return{node:t.disambiguated,selector:s,selectorIndex:o,matches:t.count,diagnostics:a,disambiguation:{matchCount:t.count,tiebreak:t.tiebreak,alternatives:t.candidates.filter(e=>e!==t.disambiguated)}}}return{node:t.firstNode,selector:s,selectorIndex:o,matches:t.count,diagnostics:a}}}return null}function qe(e,t,n){let r=n.requireRect??!1;for(let[i,a]of t.selectors.entries()){let t=e.filter(e=>r&&!e.rect?!1:V(e,a,n.platform));if(t.length>0)return{selector:a,selectorIndex:i,matchedNodes:t}}return null}function Je(e,t,n){let r=n.requireRect??!1,i=[];for(let[a,o]of t.selectors.entries()){let t=nt(e,o,n.platform,r);if(i.push({selector:o.raw,matches:t}),t>0)return{selectorIndex:a,selector:o,matches:t,diagnostics:i}}return null}const Ye=`Snapshot refs expire when the UI changes. Run snapshot -i and retry with a fresh @ref.`;function Xe(e){return e.some(e=>e.matches>1)?`Add more terms to disambiguate (e.g. role=button text="Sign in"), use an @ref from snapshot -i, or use find <text> --first/--last.`:`Selector text/label values match exactly (quote multi-word values: text="Sign in"). Run snapshot -i to see current elements and refs, or use find <text> for contains matching.`}function Ze(e,t,n){if(t.length===0)return`Selector did not match: ${e.raw}`;let r=t.map(e=>`${e.selector} -> ${e.matches}`).join(`, `);return n.unique??!0?`Selector did not resolve uniquely (${r})`:`Selector did not match (${r})`}function Qe(e,t,n,r){let i=0,a=null,o=[],s={best:null,bestVisible:!1,tie:!1},c,l=t=>(c??=g(e),ae(t,e,c));for(let c of e)r&&!c.rect||V(c,t,n)&&(i+=1,a??=c,o.push(c),$e(s,c,l));return{count:i,firstNode:a,disambiguated:s.tie?null:s.best,tiebreak:s.tie?null:et(o,s.best,l),candidates:o}}function $e(e,t,n){if(!e.best){e.best=t;return}e.bestVisible||=n(e.best);let r=n(t);if(r!==e.bestVisible){r&&(e.best=t,e.bestVisible=!0,e.tie=!1);return}let i=rt(t,e.best);i.result>0?(e.best=t,e.tie=!1):i.result===0&&(e.tie=!0)}function et(e,t,n){if(!t)return null;let r=null;for(let i of e)i!==t&&(!r||tt(i,r,n).result>0)&&(r=i);return r?tt(t,r,n).criterion:null}function tt(e,t,n){let r=n(e);return r===n(t)?rt(e,t):{result:r?1:-1,criterion:`visible`}}function nt(e,t,n,r){let i=0;for(let a of e)r&&!a.rect||V(a,t,n)&&(i+=1);return i}function rt(e,t){let n=e.depth??0,r=t.depth??0;if(n!==r)return{result:n>r?1:-1,criterion:`deepest`};let i=it(e),a=it(t);return i===a?{result:0,criterion:null}:{result:i<a?1:-1,criterion:`smallest-area`}}function it(e){return e.rect?e.rect.width*e.rect.height:1/0}const at=/^#\s*agent-device:target-v(\d+)(?:\s+(\S.*))?$/,ot=4096;function U(e){return e.normalize(`NFC`)}function st(e){if(e===void 0)return;let t=U(e);return t.length>0?t:void 0}function ct(e){return U(e)}function lt(e){if(e===void 0)return;let t=U(e).trim().replace(/\s+/g,` `);return t.length>0?t:void 0}function W(e){return Buffer.byteLength(e,`utf8`)}function G(e,t){if(W(e)<=t)return e;let n=e.length;for(;n>0&&W(e.slice(0,n))>t;)--n;if(n>0){let t=e.charCodeAt(n-1);t>=55296&&t<=56319&&--n}return e.slice(0,n)}function ut(e){let t={};return e.id!==void 0&&(t.id=e.id),t.role=e.role,e.label!==void 0&&(t.label=e.label),t.ancestry=e.ancestry.map(dt),t.sibling=e.sibling,t.viewportOrder=e.viewportOrder,e.scrollRegion&&(t.scrollRegion=ft(e.scrollRegion)),e.rect&&(t.rect=pt(e.rect)),t.verification=e.verification,t}function dt(e){let t={role:e.role};return e.label!==void 0&&(t.label=e.label),t}function ft(e){let t={role:e.role};return e.id!==void 0&&(t.id=e.id),e.label!==void 0&&(t.label=e.label),t}function pt(e){return{x:e.x,y:e.y,width:e.width,height:e.height}}function mt(e){return JSON.stringify(ut(e))}function ht(e){return`# agent-device:target-v1 ${mt(e)}`}function gt(e){let t=e.trim();if(!t.startsWith(`#`))return{kind:`none`};let n=at.exec(t);return n?Number(n[1])===1?{kind:`v1`,evidence:_t((n[2]??``).trim())}:{kind:`future-version`}:{kind:`none`}}function _t(t){if(W(t)>4096)throw new e(`INVALID_ARGS`,`target-v1 annotation exceeds the ${ot}-byte payload cap.`);let n;try{n=JSON.parse(t)}catch{throw new e(`INVALID_ARGS`,`target-v1 annotation is not valid JSON.`)}if(typeof n!=`object`||!n||Array.isArray(n))throw new e(`INVALID_ARGS`,`target-v1 annotation must be a JSON object.`);let r=n,i=K(r.role,`role`),a=vt(r.id,`id`),o=q(r.label,`label`),s=yt(r.ancestry),c=xt(r.sibling,`sibling`,0),l=xt(r.viewportOrder,`viewportOrder`,0),u=St(r.scrollRegion),d=Ct(r.rect),f=wt(r.verification);return{...a===void 0?{}:{id:a},role:i,...o===void 0?{}:{label:o},ancestry:s,sibling:c,viewportOrder:l,...u?{scrollRegion:u}:{},...d?{rect:d}:{},verification:f}}function K(t,n){if(t===void 0)throw new e(`INVALID_ARGS`,`target-v1 "${n}" is required.`);if(typeof t!=`string`)throw new e(`INVALID_ARGS`,`target-v1 "${n}" must be a string.`);return J(ct(t),n)}function vt(t,n){if(t===void 0)return;if(typeof t!=`string`)throw new e(`INVALID_ARGS`,`target-v1 "${n}" must be a string.`);let r=st(t);return r===void 0?void 0:J(r,n)}function q(t,n){if(t===void 0)return;if(typeof t!=`string`)throw new e(`INVALID_ARGS`,`target-v1 "${n}" must be a string.`);let r=lt(t);return r===void 0?void 0:J(r,n)}function J(t,n){if(W(t)>256)throw new e(`INVALID_ARGS`,`target-v1 "${n}" exceeds the 256-byte field cap.`);return t}function yt(t){if(t===void 0)return[];if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`target-v1 "ancestry" must be an array.`);if(t.length>8)throw new e(`INVALID_ARGS`,`target-v1 "ancestry" exceeds the 8-entry cap.`);return t.map((e,t)=>bt(e,t))}function bt(t,n){if(typeof t!=`object`||!t||Array.isArray(t))throw new e(`INVALID_ARGS`,`target-v1 "ancestry[${n}]" must be an object.`);let r=t,i=K(r.role,`ancestry[${n}].role`),a=q(r.label,`ancestry[${n}].label`);return{role:i,...a===void 0?{}:{label:a}}}function xt(t,n,r){if(t===void 0)return r;if(typeof t!=`number`||!Number.isSafeInteger(t)||t<0)throw new e(`INVALID_ARGS`,`target-v1 "${n}" must be a non-negative integer.`);return t}function St(t){if(t===void 0)return;if(typeof t!=`object`||!t||Array.isArray(t))throw new e(`INVALID_ARGS`,`target-v1 "scrollRegion" must be an object.`);let n=t,r=K(n.role,`scrollRegion.role`),i=vt(n.id,`id`),a=q(n.label,`scrollRegion.label`);return{role:r,...i===void 0?{}:{id:i},...a===void 0?{}:{label:a}}}function Ct(t){if(t===void 0)return;if(typeof t!=`object`||!t||Array.isArray(t))throw new e(`INVALID_ARGS`,`target-v1 "rect" must be an object.`);let n=t;return{x:Y(n.x,`rect.x`),y:Y(n.y,`rect.y`),width:Y(n.width,`rect.width`),height:Y(n.height,`rect.height`)}}function Y(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`target-v1 "${n}" must be a finite number.`);return t}function wt(t){if(t===`verified`||t===`unverifiable`)return t;throw new e(`INVALID_ARGS`,`target-v1 "verification" must be "verified" or "unverifiable".`)}function X(e){let t=ct(k(e.type??``)),n=st(e.identifier),r=lt(e.label);return{...n===void 0?{}:{id:G(n,256)},role:G(t,256),...r===void 0?{}:{label:G(r,256)}}}function Tt(e,t){return e.id===t.id&&e.role===t.role&&e.label===t.label}function Et(e,t){let n=0;for(let r of e)X(r).id===t&&(n+=1);return n}function Dt(e,t){if(e.id===void 0||Et(t,e.id)<=1)return e;let{role:n,label:r}=e;return{role:n,...r===void 0?{}:{label:r}}}function Z(e,t){let n=0;for(let r of e)if(r.parentIndex===t.parentIndex){if(r.index===t.index)return n;n+=1}return 0}function Ot(e,t){return{documentOrder:e.index,sibling:Z(t,e)}}function kt(e,t){return e.documentOrder===t.documentOrder&&e.sibling===t.sibling}const At=`replay_target_guard_mismatch`,jt=`wait_landmark_identity_mismatch`;function Mt(e,t,n={}){let r=[],i=k(e.type??``),a=Nt(e,n.nodes),o=$(e.label),s=$(e.value),c=$(I(e)),l=n.action===`fill`;a&&r.push(`id=${Q(a)}`),i&&o&&r.push(l?`role=${Q(i)} label=${Q(o)} editable=true`:`role=${Q(i)} label=${Q(o)}`),o&&r.push(l?`label=${Q(o)} editable=true`:`label=${Q(o)}`),s&&r.push(l?`value=${Q(s)} editable=true`:`value=${Q(s)}`),c&&c!==o&&c!==s&&r.push(l?`text=${Q(c)} editable=true`:`text=${Q(c)}`),i&&l&&!r.some(e=>e.includes(`editable=true`))&&r.push(`role=${Q(i)} editable=true`);let u=Pt(r);return u.length===0&&i&&u.push(l?`role=${Q(i)} editable=true`:`role=${Q(i)}`),u.length===0&&L(e)&&u.push(`visible=true`),u}function Nt(e,t){let n=$(e.identifier);if(!n||!t)return n;let r=X(e).id;return r===void 0?n:Et(t,r)>1?null:n}function Pt(e){return Array.from(new Set(e))}function Q(e){return JSON.stringify(e)}function $(e){return e&&e.trim()||null}export{x as $,B as A,M as B,Be as C,Ve as D,He as E,Ae as F,D as G,Ee as H,I,O as J,k as K,F as L,Me as M,R as N,We as O,L as P,oe as Q,ke as R,V as S,Ue as T,xe as U,Oe as V,Se as W,se as X,re as Y,ie as Z,Je as _,Dt as a,_ as at,Ke as b,Ot as c,ee as ct,ot as d,l as dt,ae as et,ht as f,o as ft,Ye as g,W as h,jt as i,g as it,Ne as j,Re as k,Z as l,f as lt,mt as m,s as mt,$ as n,y as nt,Tt as o,ne as ot,gt as p,c as pt,A as q,At as r,v as rt,X as s,h as st,Mt as t,C as tt,kt as u,p as ut,Ze as v,ze as w,Xe as x,qe as y,Te as z};
1
+ import{tn as e}from"./sdk-batch-runner.js";function t(t,n,r){return e(typeof t==`string`?t:t.raw,n,r)}export{t};