agent-device 0.20.9 → 0.21.0

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 (492) hide show
  1. package/README.md +2 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.apk → agent-device-android-ime-helper-0.21.0.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.manifest.json → agent-device-android-ime-helper-0.21.0.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.manifest.json → agent-device-android-snapshot-helper-0.21.0.manifest.json} +6 -6
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +35 -33
  9. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +6 -1
  10. package/apple/snapshot-bridge/LICENSE.idb +23 -0
  11. package/apple/snapshot-bridge/README.md +49 -0
  12. package/apple/snapshot-bridge/SnapshotBridge.m +280 -0
  13. package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +33 -0
  14. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +382 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +2 -2
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +21 -12
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -88
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +110 -107
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +6 -14
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +85 -114
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -6
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +72 -175
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +10 -11
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +78 -64
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +17 -9
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +47 -13
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +232 -438
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +98 -0
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +229 -168
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +110 -0
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +147 -25
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +21 -18
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +24 -307
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +19 -0
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +49 -16
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +2 -11
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +4 -19
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -20
  51. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
  52. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +42 -81
  53. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +35 -82
  54. package/dist/apple/snapshot-presentation/Package.swift +21 -0
  55. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
  56. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
  57. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
  58. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
  59. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
  60. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
  61. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
  62. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
  63. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
  64. package/dist/src/adapter.js +1 -0
  65. package/dist/src/adb-executor.js +2 -0
  66. package/dist/src/adb-failure.js +1 -0
  67. package/dist/src/adb-host.js +1 -0
  68. package/dist/src/adb.js +1 -0
  69. package/dist/src/agent-browser-lifecycle.js +1 -0
  70. package/dist/src/agent-browser-process-record.js +1 -0
  71. package/dist/src/agent-browser-provider.js +1 -0
  72. package/dist/src/agent-browser-tool.js +1 -1
  73. package/dist/src/agent-device-client.js +2 -2
  74. package/dist/src/ai-sdk.d.ts +61 -0
  75. package/dist/src/ai-sdk.js +1 -0
  76. package/dist/src/alert-contract.js +1 -0
  77. package/dist/src/alert-runtime.js +1 -0
  78. package/dist/src/android-adb.d.ts +27 -19
  79. package/dist/src/android-adb.js +1 -1
  80. package/dist/src/android-input-ownership.js +1 -0
  81. package/dist/src/android-system-chrome.js +1 -0
  82. package/dist/src/android.js +1 -1
  83. package/dist/src/api.js +11 -0
  84. package/dist/src/app-catalog.js +1 -0
  85. package/dist/src/app-deployment-resolution.js +2 -0
  86. package/dist/src/app-helpers.js +1 -1
  87. package/dist/src/app-inventory-contract.js +1 -0
  88. package/dist/src/app-inventory.js +1 -0
  89. package/dist/src/app-launch.js +2 -0
  90. package/dist/src/app-lifecycle-facade.js +1 -0
  91. package/dist/src/app-lifecycle.js +3 -6
  92. package/dist/src/app-lifecycle2.js +2 -2
  93. package/dist/src/app-lifecycle3.js +1 -0
  94. package/dist/src/app-log-files.js +1 -1
  95. package/dist/src/app-log-reconnect.js +1 -1
  96. package/dist/src/app-log-runtime.js +1 -4
  97. package/dist/src/app-log-runtime2.js +4 -0
  98. package/dist/src/app-parsers.js +4 -0
  99. package/dist/src/app-resolution-cache.js +1 -0
  100. package/dist/src/app-resolution-facade.js +1 -0
  101. package/dist/src/app-resolution.js +2 -2
  102. package/dist/src/app-state.js +1 -2
  103. package/dist/src/application-lifecycle-interaction.js +1 -0
  104. package/dist/src/application-lifecycle-runtime.js +1 -0
  105. package/dist/src/apps-simctl.js +1 -0
  106. package/dist/src/archive.js +4 -0
  107. package/dist/src/artifact-download.js +1 -0
  108. package/dist/src/artifacts.d.ts +6 -2
  109. package/dist/src/artifacts.js +1 -1
  110. package/dist/src/async-lifecycle.js +1 -0
  111. package/dist/src/audio-probe-result.js +1 -0
  112. package/dist/src/audio-probe-runtime.js +1 -0
  113. package/dist/src/audio-probe-support.js +1 -0
  114. package/dist/src/auth-session.js +1 -1
  115. package/dist/src/auth.js +1 -1
  116. package/dist/src/back-mode.js +1 -0
  117. package/dist/src/{url.js → base-url.js} +1 -1
  118. package/dist/src/boot-diagnostics.js +2 -2
  119. package/dist/src/byte-limit-stream.js +1 -1
  120. package/dist/src/capabilities.js +1 -0
  121. package/dist/src/capture.js +1 -0
  122. package/dist/src/catalog.js +1 -0
  123. package/dist/src/cli-command-aliases.js +1 -0
  124. package/dist/src/cli-config.js +1 -1
  125. package/dist/src/cli-help.js +77 -51
  126. package/dist/src/cli-output.js +1 -1
  127. package/dist/src/cli-runner.js +1 -1
  128. package/dist/src/cli.js +5 -7
  129. package/dist/src/click-button.js +1 -0
  130. package/dist/src/client-metro-companion.js +1 -0
  131. package/dist/src/client-metro.js +1 -1
  132. package/dist/src/client-types.d.ts +1606 -0
  133. package/dist/src/clipboard.js +1 -0
  134. package/dist/src/code-signature-cache.js +1 -0
  135. package/dist/src/code-signature.js +1 -0
  136. package/dist/src/color.js +1 -0
  137. package/dist/src/command-metadata.js +1 -1
  138. package/dist/src/command-schema.js +3 -3
  139. package/dist/src/command-surface.js +1 -1
  140. package/dist/src/command-tools.js +2 -0
  141. package/dist/src/command.js +1 -0
  142. package/dist/src/{selector-vocabulary.js → compatibility-policy.js} +1 -1
  143. package/dist/src/config.js +1 -1
  144. package/dist/src/config2.js +1 -0
  145. package/dist/src/connection-runtime.js +1 -1
  146. package/dist/src/connection.js +5 -5
  147. package/dist/src/contracts.d.ts +1 -1
  148. package/dist/src/contracts.js +1 -1
  149. package/dist/src/daemon-client-lifecycle.js +1 -0
  150. package/dist/src/daemon-process.js +1 -0
  151. package/dist/src/daemon-registration.js +1 -0
  152. package/dist/src/daemon-shutdown-report.js +1 -1
  153. package/dist/src/daemon.js +2 -2
  154. package/dist/src/debug-symbols-facade.js +5 -0
  155. package/dist/src/deploy-result-target.js +1 -0
  156. package/dist/src/device-claim-inspection.js +1 -1
  157. package/dist/src/device-claim-rule.js +1 -0
  158. package/dist/src/device-input-state.d.ts +190 -3
  159. package/dist/src/device-inventory-context.js +1 -0
  160. package/dist/src/device-isolation.js +1 -0
  161. package/dist/src/device-release.js +1 -0
  162. package/dist/src/device-rotation.js +1 -0
  163. package/dist/src/device-selection-resolver.js +1 -0
  164. package/dist/src/device-session.js +1 -0
  165. package/dist/src/device.js +1 -1
  166. package/dist/src/device2.js +3 -2
  167. package/dist/src/diagnostics.js +3 -0
  168. package/dist/src/diagnostics2.js +1 -0
  169. package/dist/src/dispatch-resolve.js +1 -0
  170. package/dist/src/doctor-facade.js +1 -0
  171. package/dist/src/doctor-output.js +1 -0
  172. package/dist/src/doctor.js +1 -0
  173. package/dist/src/doctor2.js +1 -0
  174. package/dist/src/doctor3.js +1 -0
  175. package/dist/src/durable-resource.js +1 -0
  176. package/dist/src/entities.js +1 -1
  177. package/dist/src/error.js +2 -0
  178. package/dist/src/exec.js +1 -0
  179. package/dist/src/file.js +1 -0
  180. package/dist/src/find.js +1 -1
  181. package/dist/src/finders.js +1 -1
  182. package/dist/src/format.js +2 -0
  183. package/dist/src/generic-settle.js +1 -1
  184. package/dist/src/generic.js +1 -1
  185. package/dist/src/gesture-admission.js +1 -0
  186. package/dist/src/gesture-plan-types.js +1 -0
  187. package/dist/src/gesture-plan.js +1 -0
  188. package/dist/src/gesture-runtime.js +1 -0
  189. package/dist/src/harmonyos.js +1 -1
  190. package/dist/src/hdc.js +1 -1
  191. package/dist/src/helper.js +2 -2
  192. package/dist/src/host-file.js +1 -0
  193. package/dist/src/human-control-contract.js +1 -0
  194. package/dist/src/human-control.js +1 -0
  195. package/dist/src/index.d.ts +2 -1578
  196. package/dist/src/index.js +1 -1
  197. package/dist/src/input-actions.js +1 -4
  198. package/dist/src/input-actions2.js +2 -1
  199. package/dist/src/install-artifact-facade.js +1 -0
  200. package/dist/src/install-source-network-transport.js +1 -0
  201. package/dist/src/install-source.d.ts +3 -10
  202. package/dist/src/install-source2.js +1 -1
  203. package/dist/src/interaction-positionals.js +1 -0
  204. package/dist/src/interaction-ref-policy.js +1 -0
  205. package/dist/src/interaction.js +1 -1
  206. package/dist/src/interaction2.js +1 -1
  207. package/dist/src/interactor-operation-catalog.js +1 -0
  208. package/dist/src/interactor-types.js +1 -0
  209. package/dist/src/interactor.js +6 -2
  210. package/dist/src/interactor2.js +1 -1
  211. package/dist/src/interactors.js +1 -1
  212. package/dist/src/internal/bin.d.ts +1 -1
  213. package/dist/src/internal/bin.js +1 -2
  214. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  215. package/dist/src/internal/companion-tunnel.js +1 -1
  216. package/dist/src/internal/daemon.d.ts +1 -1
  217. package/dist/src/internal/daemon.js +2 -4
  218. package/dist/src/internal/png-worker.d.ts +4 -4
  219. package/dist/src/internal/png-worker.js +1 -1
  220. package/dist/src/internal/run-script-http-child.d.ts +4 -0
  221. package/dist/src/internal/run-script-http-child.js +1 -0
  222. package/dist/src/internal/update-check-entry.d.ts +1 -1
  223. package/dist/src/inventory.js +4 -4
  224. package/dist/src/inventory2.js +1 -1
  225. package/dist/src/inventory3.js +1 -1
  226. package/dist/src/inventory5.js +1 -1
  227. package/dist/src/inventory6.js +1 -1
  228. package/dist/src/ios-client.js +16 -0
  229. package/dist/src/ios-snapshot-acquisition.js +1 -0
  230. package/dist/src/ios-snapshot-adapter.js +1 -0
  231. package/dist/src/ios-snapshot-planning.js +1 -0
  232. package/dist/src/ios-snapshot-runtime.js +1 -0
  233. package/dist/src/json.js +1 -0
  234. package/dist/src/keyboard-actions.js +1 -0
  235. package/dist/src/launch-console.js +1 -0
  236. package/dist/src/lease-context.js +1 -1
  237. package/dist/src/lease-scope.js +1 -0
  238. package/dist/src/lease.js +1 -1
  239. package/dist/src/limrun-runtime-dependencies.js +1 -1
  240. package/dist/src/limrun.d.ts +1618 -7
  241. package/dist/src/limrun.js +1 -1
  242. package/dist/src/linux.js +1 -1
  243. package/dist/src/local-interactor-operation-set.js +1 -0
  244. package/dist/src/location-coordinates.js +1 -1
  245. package/dist/src/logcat.js +1 -1
  246. package/dist/src/macos-facade.js +1 -0
  247. package/dist/src/managed-device-scope.js +1 -0
  248. package/dist/src/mechanics.js +19 -0
  249. package/dist/src/metro.d.ts +4 -2
  250. package/dist/src/metro.js +1 -1
  251. package/dist/src/metro2.js +1 -1
  252. package/dist/src/mobile-snapshot-semantics.js +1 -0
  253. package/dist/src/multitouch-support.js +1 -0
  254. package/dist/src/numeric.js +1 -0
  255. package/dist/src/observability.js +1 -1
  256. package/dist/src/observation.js +2 -0
  257. package/dist/src/output-path.js +1 -1
  258. package/dist/src/owner-identity.js +3 -1
  259. package/dist/src/parameterized-recorded-fill.js +1 -0
  260. package/dist/src/parser.js +1 -1
  261. package/dist/src/perf-facade.js +2 -0
  262. package/dist/src/perf-runtime-operation-builder.js +1 -0
  263. package/dist/src/perf-runtime-plan.js +1 -0
  264. package/dist/src/perf-runtime.js +1 -0
  265. package/dist/src/perf.js +1 -4
  266. package/dist/src/physical-device-control.js +1 -1
  267. package/dist/src/physical-device-facade.js +1 -0
  268. package/dist/src/platform-request-scope.js +1 -0
  269. package/dist/src/platform-runtime-android-adb-host.js +1 -0
  270. package/dist/src/platform-runtime-android-mechanics.js +1 -0
  271. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  272. package/dist/src/platform-runtime-app-log-process.js +1 -1
  273. package/dist/src/platform-runtime-apple-resources.js +1 -0
  274. package/dist/src/platform-runtime-host.js +1 -1
  275. package/dist/src/platform-runtime-managed-owner.js +1 -0
  276. package/dist/src/platform-runtime-network-web-transport.js +1 -1
  277. package/dist/src/platform-runtime-open-target.js +1 -1
  278. package/dist/src/platform-runtime-operation-host.js +4 -4
  279. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  280. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  281. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
  282. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
  283. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  284. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
  285. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  286. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  287. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
  288. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
  289. package/dist/src/platform-runtime-unavailable.js +1 -0
  290. package/dist/src/platform-runtime.js +1 -1
  291. package/dist/src/platform-runtime2.js +1 -1
  292. package/dist/src/plist.js +1 -1
  293. package/dist/src/png-worker-contract.js +1 -1
  294. package/dist/src/prepare-kind.js +1 -15
  295. package/dist/src/process-exit.js +1 -1
  296. package/dist/src/process.js +1 -0
  297. package/dist/src/provider-device-runtime.js +1 -0
  298. package/dist/src/provider-session-ownership.js +2 -0
  299. package/dist/src/provider-webdriver.js +1 -1
  300. package/dist/src/provider.js +1 -1
  301. package/dist/src/providers.js +1 -0
  302. package/dist/src/proxy.js +2 -2
  303. package/dist/src/react-native-overlay.js +1 -0
  304. package/dist/src/react-native.js +1 -1
  305. package/dist/src/record-runtime.js +1 -1
  306. package/dist/src/record-trace.js +1 -1
  307. package/dist/src/rect-center.js +1 -0
  308. package/dist/src/register-builtins.js +1 -0
  309. package/dist/src/registry.js +39 -28
  310. package/dist/src/remote-config2.js +1 -1
  311. package/dist/src/replay-divergence.js +2 -0
  312. package/dist/src/replay.js +2 -2
  313. package/dist/src/reporting.js +8 -8
  314. package/dist/src/request-admission.js +1 -0
  315. package/dist/src/request-cancel.js +1 -0
  316. package/dist/src/request-cancellation.js +1 -0
  317. package/dist/src/request-progress-protocol.js +1 -0
  318. package/dist/src/request-providers.js +1 -0
  319. package/dist/src/request-runtime-binding.js +1 -0
  320. package/dist/src/request.js +1 -0
  321. package/dist/src/result-serialization.js +1 -0
  322. package/dist/src/retry.js +1 -0
  323. package/dist/src/rolldown-runtime.js +1 -1
  324. package/dist/src/runner-cache-metadata.js +2 -0
  325. package/dist/src/runner-client.js +1 -1
  326. package/dist/src/runner-disposal.js +1 -1
  327. package/dist/src/runner-operations-facade.js +1 -0
  328. package/dist/src/runner-owner-facade.js +1 -0
  329. package/dist/src/runner-owner-state.js +1 -0
  330. package/dist/src/runner-presentation.js +1 -0
  331. package/dist/src/runner-selector-query.js +1 -0
  332. package/dist/src/runner.js +1 -0
  333. package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
  334. package/dist/src/runtime.js +3 -3
  335. package/dist/src/runtime2.js +4 -4
  336. package/dist/src/runtime3.js +1 -1
  337. package/dist/src/runtime4.js +4 -3
  338. package/dist/src/runtime5.js +1 -1
  339. package/dist/src/runtime6.js +1 -1
  340. package/dist/src/runtime7.js +1 -1
  341. package/dist/src/runtime8.js +1 -1
  342. package/dist/src/runtime9.js +1 -1
  343. package/dist/src/scoped-provider.js +1 -1
  344. package/dist/src/screen-recording-completion.js +1 -0
  345. package/dist/src/screen-recording-live-handle.js +1 -0
  346. package/dist/src/screen-recording-options.js +1 -0
  347. package/dist/src/screen-recording-resource-recovery.js +1 -0
  348. package/dist/src/screen-recording-runtime.js +1 -0
  349. package/dist/src/screenshot-density.js +1 -1
  350. package/dist/src/screenshot-result.js +1 -6
  351. package/dist/src/screenshot-runtime.js +1 -0
  352. package/dist/src/screenshot.js +1 -1
  353. package/dist/src/screenshot2.js +1 -0
  354. package/dist/src/screenshot3.js +5 -0
  355. package/dist/src/script.js +1 -0
  356. package/dist/src/scroll-command.js +1 -0
  357. package/dist/src/scroll-gesture.js +1 -0
  358. package/dist/src/scroll-indicator.js +1 -0
  359. package/dist/src/sdk-batch-runner.d.ts +23 -6
  360. package/dist/src/sdk-batch-runner.js +2 -3
  361. package/dist/src/sdk-batch.js +2 -0
  362. package/dist/src/sdk-contracts.d.ts +222 -99
  363. package/dist/src/sdk-contracts.js +2 -2
  364. package/dist/src/sdk-device.js +1 -1
  365. package/dist/src/sdk-finders.d.ts +1 -1
  366. package/dist/src/sdk-finders.js +1 -1
  367. package/dist/src/sdk-io.js +1 -1
  368. package/dist/src/sdk-remote-config.d.ts +1 -1
  369. package/dist/src/sdk-remote-config.js +1 -1
  370. package/dist/src/sdk-selectors.d.ts +539 -199
  371. package/dist/src/sdk-selectors.js +1 -1
  372. package/dist/src/selection.js +1 -0
  373. package/dist/src/selector-runtime.js +1 -1
  374. package/dist/src/selectors.js +1 -1
  375. package/dist/src/semantic-index.js +1 -0
  376. package/dist/src/server.js +10 -3
  377. package/dist/src/session-allocation.js +1 -0
  378. package/dist/src/session-artifact-paths.js +1 -0
  379. package/dist/src/session-paths.js +1 -0
  380. package/dist/src/session-repair-tombstone.js +1 -0
  381. package/dist/src/session-routing.js +1 -0
  382. package/dist/src/session-runtime-admission.js +1 -0
  383. package/dist/src/session-snapshot.js +1 -0
  384. package/dist/src/session-store.js +4 -0
  385. package/dist/src/session-target-evidence.js +1 -1
  386. package/dist/src/session2.js +5 -28
  387. package/dist/src/settings.js +1 -0
  388. package/dist/src/shared.js +2 -2
  389. package/dist/src/simctl-facade.js +1 -0
  390. package/dist/src/simctl.js +1 -1
  391. package/dist/src/simulator-facade.js +1 -0
  392. package/dist/src/simulator.js +1 -1
  393. package/dist/src/snapshot-capture-annotations.js +1 -0
  394. package/dist/src/snapshot-desktop-projection.js +1 -0
  395. package/dist/src/snapshot-diagnostics.js +1 -0
  396. package/dist/src/snapshot-process.js +1 -0
  397. package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
  398. package/dist/src/snapshot-quality-verdict.js +1 -0
  399. package/dist/src/snapshot-runtime-binding.js +1 -0
  400. package/dist/src/snapshot-runtime.js +1 -1
  401. package/dist/src/snapshot-scope.js +1 -0
  402. package/dist/src/snapshot-state.js +1 -0
  403. package/dist/src/snapshot.js +1 -8
  404. package/dist/src/snapshot2.js +1 -1
  405. package/dist/src/snapshot3.js +1 -1
  406. package/dist/src/snapshot4.js +1 -0
  407. package/dist/src/src.js +1 -1
  408. package/dist/src/src2.js +1 -1
  409. package/dist/src/src3.js +1 -2
  410. package/dist/src/src4.js +1 -0
  411. package/dist/src/src5.js +1 -0
  412. package/dist/src/src6.js +1 -0
  413. package/dist/src/src7.js +2 -0
  414. package/dist/src/src8.js +115 -0
  415. package/dist/src/startup-recovery-fence.js +1 -0
  416. package/dist/src/status-markers.js +1 -0
  417. package/dist/src/string-enum.js +1 -1
  418. package/dist/src/success-text.js +1 -0
  419. package/dist/src/surface-snapshot.js +1 -0
  420. package/dist/src/surface-snapshot2.js +1 -0
  421. package/dist/src/takeover.js +5 -0
  422. package/dist/src/tool-provider-facade.js +1 -0
  423. package/dist/src/tool-provider.js +4 -3
  424. package/dist/src/tool-provider2.js +1 -1
  425. package/dist/src/tool-provider3.js +1 -0
  426. package/dist/src/toolchain-probe.js +2 -0
  427. package/dist/src/touch-runtime.js +1 -0
  428. package/dist/src/transport.js +3 -0
  429. package/dist/src/tree.js +1 -0
  430. package/dist/src/ttl-memo.js +1 -0
  431. package/dist/src/tv-remote.js +1 -0
  432. package/dist/src/type-text-runtime.js +1 -0
  433. package/dist/src/undici.js +99 -0
  434. package/dist/src/update-check.js +1 -1
  435. package/dist/src/verified-file.js +1 -1
  436. package/dist/src/version.js +1 -1
  437. package/dist/src/video.js +2 -2
  438. package/dist/src/web.js +2 -1
  439. package/dist/src/web2.js +1 -0
  440. package/dist/src/webdriver-ios-snapshot.js +1 -0
  441. package/dist/src/webdriver-source.js +1 -0
  442. package/linux/atspi-dump.py +54 -9
  443. package/package.json +73 -38
  444. package/server.json +9 -3
  445. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +0 -1
  446. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk +0 -0
  447. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +0 -1
  448. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
  449. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -75
  450. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
  451. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
  452. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
  453. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
  454. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
  455. package/dist/src/appearance.js +0 -1
  456. package/dist/src/apps.js +0 -5
  457. package/dist/src/audio-probe.js +0 -1
  458. package/dist/src/cancel.js +0 -1
  459. package/dist/src/cli-grammar.js +0 -1
  460. package/dist/src/command-catalog.js +0 -1
  461. package/dist/src/debug-symbols.js +0 -5
  462. package/dist/src/device-input-state.js +0 -2
  463. package/dist/src/device-ready.js +0 -1
  464. package/dist/src/dispatch.js +0 -1
  465. package/dist/src/handler-utils.js +0 -1
  466. package/dist/src/helper-package-install.js +0 -1
  467. package/dist/src/host-process.js +0 -3
  468. package/dist/src/ime-lifecycle.js +0 -2
  469. package/dist/src/ime-recovery-marker.js +0 -1
  470. package/dist/src/input-actions3.js +0 -1
  471. package/dist/src/install-artifact.js +0 -1
  472. package/dist/src/install-artifact2.js +0 -1
  473. package/dist/src/interaction-common.js +0 -1
  474. package/dist/src/interaction-runtime.js +0 -1
  475. package/dist/src/interaction-snapshot.js +0 -1
  476. package/dist/src/manifest.js +0 -1
  477. package/dist/src/method-scope.js +0 -1
  478. package/dist/src/png-resize.js +0 -1
  479. package/dist/src/process-lock.js +0 -1
  480. package/dist/src/runner-lease.js +0 -1
  481. package/dist/src/runner-sequence.js +0 -1
  482. package/dist/src/screenshot-geometry.js +0 -1
  483. package/dist/src/sdk-android-adb.d.ts +0 -245
  484. package/dist/src/sdk-android-adb.js +0 -4
  485. package/dist/src/sdk.js +0 -1
  486. package/dist/src/setting-state.js +0 -1
  487. package/dist/src/shell-quote.js +0 -1
  488. package/dist/src/snapshot-session.js +0 -1
  489. package/dist/src/timing-safe-equal.js +0 -1
  490. package/dist/src/unsupported-interactor.js +0 -1
  491. package/dist/src/verdict.js +0 -1
  492. /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
@@ -0,0 +1,153 @@
1
+ import Foundation
2
+ import CoreGraphics
3
+
4
+ public enum SnapshotPresentation {
5
+ public static func present(
6
+ _ acquisition: SnapshotAcquisition,
7
+ options: PresentationOptions
8
+ ) throws -> SnapshotPresentationResult? {
9
+ let requested = captureHint(for: options)
10
+ guard acquisition.hint.projection == requested.projection else {
11
+ return nil
12
+ }
13
+ switch requested.projection {
14
+ case .regular:
15
+ return try presentRegular(acquisition, options: options)
16
+ case .raw:
17
+ return presentRaw(acquisition, options: options)
18
+ }
19
+ }
20
+
21
+ public static func presentRegular(
22
+ _ acquisition: SnapshotAcquisition,
23
+ options: PresentationOptions,
24
+ policy: SnapshotVisibilityFold.Policy = .platformDefault
25
+ ) throws -> SnapshotPresentationResult {
26
+ let folded = SnapshotVisibilityFold.fold(
27
+ acquisition.nodes,
28
+ viewport: acquisition.viewport,
29
+ interactiveOnly: options.interactiveOnly,
30
+ policy: policy
31
+ )
32
+ try SnapshotPresentationInvariant.validateRegular(
33
+ folded,
34
+ viewport: acquisition.viewport,
35
+ policy: policy
36
+ )
37
+ return project(
38
+ folded,
39
+ acquisition: acquisition,
40
+ options: options,
41
+ projection: .regular
42
+ )
43
+ }
44
+
45
+ public static func presentRaw(
46
+ _ acquisition: SnapshotAcquisition,
47
+ options: PresentationOptions
48
+ ) -> SnapshotPresentationResult {
49
+ project(
50
+ acquisition.nodes.map(SnapshotPresentationNode.reported),
51
+ acquisition: acquisition,
52
+ options: options,
53
+ projection: .raw
54
+ )
55
+ }
56
+
57
+ public static func captureHint(for options: PresentationOptions) -> CaptureHint {
58
+ let scoped = SnapshotScopePolicy.isActive(options.scope)
59
+ let projection: CaptureHint.Projection = options.raw ? .raw : .regular
60
+ return CaptureHint(
61
+ projection: projection,
62
+ depth: scoped || projection == .regular ? nil : options.depth,
63
+ regularPresentedDepth: scoped || projection == .raw ? nil : options.depth,
64
+ interactiveOnly: projection == .raw ? false : options.interactiveOnly,
65
+ customActions: options.customActions
66
+ )
67
+ }
68
+
69
+ public static func shouldAcquireChildren(
70
+ for hint: CaptureHint,
71
+ rawDepth: Int,
72
+ regularPresentedDepth: Int
73
+ ) -> Bool {
74
+ if let rawLimit = hint.rawTraversalDepth {
75
+ return rawDepth < rawLimit
76
+ }
77
+ if let presentedLimit = hint.regularPresentedDepth {
78
+ return regularPresentedDepth < presentedLimit
79
+ }
80
+ return true
81
+ }
82
+
83
+ public static func regularTraversalTransition(
84
+ for raw: RawAXNode,
85
+ parentPresentedDepth: Int,
86
+ parentTraversal: SnapshotVisibilityFold.TraversalState,
87
+ hint: CaptureHint,
88
+ rawDepth: Int,
89
+ viewport: CGRect,
90
+ hasChildren: Bool,
91
+ isDuplicate: Bool,
92
+ policy: SnapshotVisibilityFold.Policy = .platformDefault
93
+ ) -> (
94
+ presentedDepth: Int,
95
+ traversal: SnapshotVisibilityFold.TraversalState,
96
+ shouldVisitChildren: Bool
97
+ ) {
98
+ guard hint.regularPresentedDepth != nil else {
99
+ return (
100
+ parentPresentedDepth,
101
+ parentTraversal,
102
+ shouldAcquireChildren(
103
+ for: hint,
104
+ rawDepth: rawDepth,
105
+ regularPresentedDepth: parentPresentedDepth
106
+ )
107
+ )
108
+ }
109
+
110
+ let visibility = SnapshotVisibilityFold.traversalDecision(
111
+ for: raw,
112
+ parent: parentTraversal,
113
+ viewport: viewport,
114
+ interactiveOnly: hint.interactiveOnly,
115
+ hasChildren: hasChildren,
116
+ policy: policy
117
+ )
118
+ let presentedDepth = regularPresentedDepth(
119
+ for: raw,
120
+ parentPresentedDepth: parentPresentedDepth,
121
+ visibility: visibility
122
+ )
123
+ let nextPresentedDepth = isDuplicate ? parentPresentedDepth : presentedDepth
124
+ let nextTraversal = isDuplicate ? parentTraversal : visibility.descendants
125
+ let descendantsMayBeVisible = isDuplicate
126
+ ? parentTraversal.descendantsMayBeVisible
127
+ : visibility.descendantsMayBeVisible
128
+ return (
129
+ nextPresentedDepth,
130
+ nextTraversal,
131
+ shouldAcquireChildren(
132
+ for: hint,
133
+ rawDepth: rawDepth,
134
+ regularPresentedDepth: nextPresentedDepth
135
+ ) && descendantsMayBeVisible
136
+ )
137
+ }
138
+
139
+ public static func regularPresentedDepth(
140
+ for raw: RawAXNode,
141
+ parentPresentedDepth: Int,
142
+ visibility: SnapshotVisibilityFold.TraversalDecision
143
+ ) -> Int {
144
+ guard raw.parentIndex != nil else { return 0 }
145
+ return visibility.isIncluded && isEligibleForRegularPresentation(raw)
146
+ ? parentPresentedDepth + 1
147
+ : parentPresentedDepth
148
+ }
149
+
150
+ public static func singleElementRead(_ node: RawAXNode) -> PresentedNode {
151
+ PresentedNode(presenting: node)
152
+ }
153
+ }
@@ -0,0 +1,27 @@
1
+ import Foundation
2
+
3
+ public enum SnapshotPresentationFailure: Error {
4
+ case regularNodeOutsideCumulativeClip(index: Int, frame: SnapshotRect, clip: SnapshotRect)
5
+ case regularDegenerateNodeIsActionable(index: Int, frame: SnapshotRect)
6
+
7
+ public var code: String {
8
+ "IOS_SNAPSHOT_PRESENTATION_FAILED"
9
+ }
10
+
11
+ public var qualityReasonCode: String {
12
+ "presentation-failed"
13
+ }
14
+
15
+ public var message: String {
16
+ switch self {
17
+ case .regularNodeOutsideCumulativeClip(let index, _, _):
18
+ return "regular snapshot node \(index) escaped its cumulative clip"
19
+ case .regularDegenerateNodeIsActionable(let index, _):
20
+ return "regular snapshot node \(index) with a frameless or degenerate frame was marked hittable"
21
+ }
22
+ }
23
+
24
+ public var hint: String {
25
+ "This is a runner presentation bug: report it with the failing command and the app under test."
26
+ }
27
+ }
@@ -0,0 +1,91 @@
1
+ import Foundation
2
+ import CoreGraphics
3
+
4
+ public enum SnapshotPresentationInvariant {
5
+ struct ValidationStats: Equatable {
6
+ let parentClipLookups: Int
7
+
8
+ init(parentClipLookups: Int) {
9
+ self.parentClipLookups = parentClipLookups
10
+ }
11
+ }
12
+
13
+ public static func validateRegular(
14
+ _ nodes: [SnapshotPresentationNode],
15
+ viewport: CGRect,
16
+ policy: SnapshotVisibilityFold.Policy
17
+ ) throws {
18
+ _ = try validateRegularWithStats(nodes, viewport: viewport, policy: policy)
19
+ }
20
+
21
+ static func validateRegularWithStats(
22
+ _ nodes: [SnapshotPresentationNode],
23
+ viewport: CGRect,
24
+ policy: SnapshotVisibilityFold.Policy
25
+ ) throws -> ValidationStats {
26
+ var parentClipLookups = 0
27
+ var clipIncludingNodeByIndex: [Int: CGRect] = [:]
28
+ clipIncludingNodeByIndex.reserveCapacity(nodes.count)
29
+
30
+ for node in nodes {
31
+ let ancestorClip: CGRect
32
+ if let parentIndex = node.raw.parentIndex {
33
+ parentClipLookups += 1
34
+ ancestorClip = clipIncludingNodeByIndex[parentIndex] ?? viewport
35
+ } else {
36
+ ancestorClip = viewport
37
+ }
38
+
39
+ let frame = node.effectiveRect.cgRect
40
+ let clipIncludingNode: CGRect
41
+ if policy == .cursorProjected,
42
+ SnapshotVisibilityFold.scrollContainerTypeNames.contains(node.raw.type),
43
+ !frame.isNull,
44
+ !frame.isEmpty
45
+ {
46
+ clipIncludingNode = frame
47
+ } else {
48
+ clipIncludingNode = ancestorClip
49
+ }
50
+ clipIncludingNodeByIndex[node.raw.index] = clipIncludingNode
51
+
52
+ guard !frame.isNull, !frame.isEmpty else {
53
+ if node.raw.hittable {
54
+ throw SnapshotPresentationFailure.regularDegenerateNodeIsActionable(
55
+ index: node.raw.index,
56
+ frame: node.effectiveRect
57
+ )
58
+ }
59
+ continue
60
+ }
61
+
62
+ guard contains(frame, in: ancestorClip) else {
63
+ throw SnapshotPresentationFailure.regularNodeOutsideCumulativeClip(
64
+ index: node.raw.index,
65
+ frame: node.effectiveRect,
66
+ clip: snapshotRect(from: ancestorClip)
67
+ )
68
+ }
69
+ }
70
+
71
+ return ValidationStats(parentClipLookups: parentClipLookups)
72
+ }
73
+
74
+ private static func contains(_ frame: CGRect, in clip: CGRect) -> Bool {
75
+ guard !clip.isNull, !clip.isEmpty else { return false }
76
+ let tolerance = 0.0001
77
+ return frame.minX >= clip.minX - tolerance
78
+ && frame.minY >= clip.minY - tolerance
79
+ && frame.maxX <= clip.maxX + tolerance
80
+ && frame.maxY <= clip.maxY + tolerance
81
+ }
82
+
83
+ private static func snapshotRect(from rect: CGRect) -> SnapshotRect {
84
+ SnapshotRect(
85
+ x: Double(rect.minX),
86
+ y: Double(rect.minY),
87
+ width: Double(rect.width),
88
+ height: Double(rect.height)
89
+ )
90
+ }
91
+ }
@@ -0,0 +1,161 @@
1
+ import Foundation
2
+
3
+ extension SnapshotPresentation {
4
+ static let eligibleInteractiveTypes: Set<String> = [
5
+ "Button",
6
+ "Cell",
7
+ "CheckBox",
8
+ "CollectionView",
9
+ "Link",
10
+ "MenuItem",
11
+ "Picker",
12
+ "SearchField",
13
+ "SecureTextField",
14
+ "SegmentedControl",
15
+ "Slider",
16
+ "ScrollView",
17
+ "Stepper",
18
+ "Switch",
19
+ "TabBar",
20
+ "Table",
21
+ "TextField",
22
+ "TextView",
23
+ "WebView",
24
+ ]
25
+
26
+ static func project(
27
+ _ projectionNodes: [SnapshotPresentationNode],
28
+ acquisition: SnapshotAcquisition,
29
+ options: PresentationOptions,
30
+ projection: CaptureHint.Projection
31
+ ) -> SnapshotPresentationResult {
32
+ let scopedRawNodes = applyScope(to: projectionNodes, options: options, projection: projection)
33
+ let nodes = presentedNodes(
34
+ from: scopedRawNodes,
35
+ projection: projection,
36
+ maximumDepth: projection == .regular ? options.depth : nil
37
+ )
38
+ let qualityNodes: [PresentedNode]? = SnapshotScopePolicy.isActive(options.scope)
39
+ ? presentedNodes(from: projectionNodes, projection: projection, maximumDepth: nil)
40
+ : nil
41
+ return SnapshotPresentationResult(
42
+ nodes: nodes,
43
+ truncated: acquisition.truncated,
44
+ effectiveDepth: acquisition.effectiveDepth,
45
+ customActions: acquisition.customActions,
46
+ qualityNodes: qualityNodes
47
+ )
48
+ }
49
+
50
+ static func presentedNodes(
51
+ from rawNodes: [SnapshotPresentationNode],
52
+ projection: CaptureHint.Projection,
53
+ maximumDepth: Int? = nil
54
+ ) -> [PresentedNode] {
55
+ if projection == .raw {
56
+ return rawNodes.map { PresentedNode(presenting: $0) }
57
+ }
58
+
59
+ var nodes: [PresentedNode] = []
60
+ var nearestPresentedNodeByRawIndex: [Int: (index: Int, depth: Int)] = [:]
61
+ for node in rawNodes {
62
+ let raw = node.raw
63
+ let presentedParent = raw.parentIndex.flatMap { nearestPresentedNodeByRawIndex[$0] }
64
+ guard isEligibleForRegularPresentation(raw) else {
65
+ if let presentedParent {
66
+ nearestPresentedNodeByRawIndex[raw.index] = presentedParent
67
+ }
68
+ continue
69
+ }
70
+
71
+ let presentedIndex = nodes.count
72
+ let presentedDepth = presentedParent.map { $0.depth + 1 } ?? 0
73
+ if let maximumDepth, presentedDepth > maximumDepth {
74
+ if let presentedParent {
75
+ nearestPresentedNodeByRawIndex[raw.index] = presentedParent
76
+ }
77
+ continue
78
+ }
79
+ nearestPresentedNodeByRawIndex[raw.index] = (presentedIndex, presentedDepth)
80
+ nodes.append(
81
+ PresentedNode(
82
+ presenting: raw,
83
+ rect: node.effectiveRect,
84
+ index: presentedIndex,
85
+ depth: presentedDepth,
86
+ parentIndex: presentedParent?.index
87
+ )
88
+ )
89
+ }
90
+ return nodes
91
+ }
92
+
93
+ static func applyScope(
94
+ to rawNodes: [SnapshotPresentationNode],
95
+ options: PresentationOptions,
96
+ projection: CaptureHint.Projection
97
+ ) -> [SnapshotPresentationNode] {
98
+ switch SnapshotScopePolicy.select(
99
+ fromPreorder: rawNodes,
100
+ scope: options.scope,
101
+ depth: { $0.raw.depth },
102
+ semanticValues: { [$0.raw.label, $0.raw.identifier, $0.raw.value] },
103
+ subtreeContributes: { range in
104
+ projection == .raw || rawNodes[range].contains { isEligibleForRegularPresentation($0.raw) }
105
+ }
106
+ ) {
107
+ case .unscoped:
108
+ return rawNodes
109
+ case .missing:
110
+ return []
111
+ case .matched(let startIndex):
112
+ let startDepth = rawNodes[startIndex].raw.depth
113
+ let range = SnapshotScopePolicy.subtreeRange(
114
+ from: startIndex,
115
+ in: rawNodes,
116
+ depth: { $0.raw.depth }
117
+ )
118
+ let maxDepth = options.depth ?? Int.max
119
+ let scopedNodes = projection == .raw
120
+ ? Array(rawNodes[range]).filter { $0.raw.depth - startDepth <= maxDepth }
121
+ : Array(rawNodes[range])
122
+ return reindex(scopedNodes, depthOffset: startDepth)
123
+ }
124
+ }
125
+
126
+ static func reindex(
127
+ _ nodes: [SnapshotPresentationNode],
128
+ depthOffset: Int
129
+ ) -> [SnapshotPresentationNode] {
130
+ let indexMap = Dictionary(
131
+ uniqueKeysWithValues: nodes.enumerated().map { ($0.element.raw.index, $0.offset) })
132
+ return nodes.enumerated().map { offset, node in
133
+ let raw = node.raw
134
+ return SnapshotPresentationNode(
135
+ raw: RawAXNode(
136
+ index: offset,
137
+ type: raw.type,
138
+ label: raw.label,
139
+ identifier: raw.identifier,
140
+ value: raw.value,
141
+ rect: raw.rect,
142
+ enabled: raw.enabled,
143
+ focused: raw.focused,
144
+ selected: raw.selected,
145
+ hittable: raw.hittable,
146
+ depth: max(0, raw.depth - depthOffset),
147
+ parentIndex: raw.parentIndex.flatMap { indexMap[$0] },
148
+ hiddenContentAbove: raw.hiddenContentAbove,
149
+ hiddenContentBelow: raw.hiddenContentBelow,
150
+ actions: raw.actions
151
+ ),
152
+ effectiveRect: node.effectiveRect
153
+ )
154
+ }
155
+ }
156
+
157
+ static func isEligibleForRegularPresentation(_ node: RawAXNode) -> Bool {
158
+ if node.parentIndex == nil { return true }
159
+ return eligibleInteractiveTypes.contains(node.type) || node.hasSemanticContent
160
+ }
161
+ }
@@ -0,0 +1,53 @@
1
+ import Foundation
2
+
3
+ public enum SnapshotScopeSelection: Equatable {
4
+ case unscoped
5
+ case matched(Int)
6
+ case missing
7
+ }
8
+
9
+ public enum SnapshotScopePolicy {
10
+ public static func select<Node>(
11
+ fromPreorder nodes: [Node],
12
+ scope: String?,
13
+ depth: (Node) -> Int,
14
+ semanticValues: (Node) -> [String?],
15
+ subtreeContributes: (Range<Int>) -> Bool
16
+ ) -> SnapshotScopeSelection {
17
+ guard let query = normalized(scope) else { return .unscoped }
18
+ for (index, node) in nodes.enumerated() {
19
+ guard semanticValues(node).contains(where: { value in
20
+ value?.lowercased().contains(query) == true
21
+ }) else { continue }
22
+ let range = subtreeRange(from: index, in: nodes, depth: depth)
23
+ if subtreeContributes(range) {
24
+ return .matched(index)
25
+ }
26
+ }
27
+ return .missing
28
+ }
29
+
30
+ public static func isActive(_ scope: String?) -> Bool {
31
+ normalized(scope) != nil
32
+ }
33
+
34
+ public static func subtreeRange<Node>(
35
+ from start: Int,
36
+ in nodes: [Node],
37
+ depth: (Node) -> Int
38
+ ) -> Range<Int> {
39
+ let rootDepth = depth(nodes[start])
40
+ var end = start + 1
41
+ while end < nodes.count, depth(nodes[end]) > rootDepth {
42
+ end += 1
43
+ }
44
+ return start..<end
45
+ }
46
+
47
+ private static func normalized(_ scope: String?) -> String? {
48
+ guard let query = scope?.trimmingCharacters(in: .whitespacesAndNewlines), !query.isEmpty else {
49
+ return nil
50
+ }
51
+ return query.lowercased()
52
+ }
53
+ }