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
@@ -1,11 +1,17 @@
1
1
  import XCTest
2
+ import AgentDeviceSnapshotPresentation
2
3
 
3
4
  #if os(macOS)
4
5
  import CoreGraphics
5
6
  #endif
6
7
 
8
+ private struct RunnerUnsupportedOperationError: LocalizedError {
9
+ let message: String
10
+
11
+ var errorDescription: String? { message }
12
+ }
13
+
7
14
  private enum RunnerInterfaceOrientation {
8
- static let unknown = 0
9
15
  static let portrait = 1
10
16
  static let portraitUpsideDown = 2
11
17
  static let landscapeRight = 3
@@ -18,11 +24,18 @@ extension RunnerTests {
18
24
  case sampled
19
25
  }
20
26
 
21
- enum SynthesizedDragProfile {
27
+ enum SynthesizedDragProfile: Equatable {
22
28
  case continuous
29
+ case controlledScroll
23
30
  case fastSwipe
24
31
  }
25
32
 
33
+ func scrollDragProfile(
34
+ releaseBehavior: ScrollReleaseBehavior?
35
+ ) -> SynthesizedDragProfile {
36
+ releaseBehavior == .inertial ? .fastSwipe : .controlledScroll
37
+ }
38
+
26
39
  struct TouchVisualizationFrame {
27
40
  let x: Double
28
41
  let y: Double
@@ -229,21 +242,23 @@ extension RunnerTests {
229
242
  let identifier = element.identifier.trimmingCharacters(in: .whitespacesAndNewlines)
230
243
  let valueText = String(describing: element.value ?? "")
231
244
  .trimmingCharacters(in: .whitespacesAndNewlines)
232
- let node = SnapshotNode(
233
- index: 0,
234
- type: elementTypeName(element.elementType),
235
- label: label.isEmpty ? nil : label,
236
- identifier: identifier.isEmpty ? nil : identifier,
237
- value: valueText.isEmpty ? nil : valueText,
238
- rect: snapshotRect(from: element.frame),
239
- enabled: element.isEnabled,
240
- focused: nil,
241
- selected: element.isSelected ? true : nil,
242
- hittable: element.isHittable,
243
- depth: 0,
244
- parentIndex: nil,
245
- hiddenContentAbove: nil,
246
- hiddenContentBelow: nil
245
+ let node = SnapshotPresentation.singleElementRead(
246
+ RawAXNode(
247
+ index: 0,
248
+ type: elementTypeName(element.elementType),
249
+ label: label.isEmpty ? nil : label,
250
+ identifier: identifier.isEmpty ? nil : identifier,
251
+ value: valueText.isEmpty ? nil : valueText,
252
+ rect: snapshotRect(from: element.frame),
253
+ enabled: element.isEnabled,
254
+ focused: nil,
255
+ selected: element.isSelected ? true : nil,
256
+ hittable: element.isHittable,
257
+ depth: 0,
258
+ parentIndex: nil,
259
+ hiddenContentAbove: nil,
260
+ hiddenContentBelow: nil
261
+ )
247
262
  )
248
263
  return Response(
249
264
  ok: true,
@@ -255,6 +270,23 @@ extension RunnerTests {
255
270
  )
256
271
  }
257
272
 
273
+ /// Shared ordering for point-hit candidates: smallest area wins, then top-to-bottom,
274
+ /// left-to-right, then stable element-type order for ties.
275
+ func smallestElementFirst(_ left: XCUIElement, _ right: XCUIElement) -> Bool {
276
+ let leftArea = max(1, left.frame.width * left.frame.height)
277
+ let rightArea = max(1, right.frame.width * right.frame.height)
278
+ if leftArea != rightArea {
279
+ return leftArea < rightArea
280
+ }
281
+ if left.frame.minY != right.frame.minY {
282
+ return left.frame.minY < right.frame.minY
283
+ }
284
+ if left.frame.minX != right.frame.minX {
285
+ return left.frame.minX < right.frame.minX
286
+ }
287
+ return left.elementType.rawValue < right.elementType.rawValue
288
+ }
289
+
258
290
  func readTextAt(app: XCUIApplication, x: Double, y: Double) -> String? {
259
291
  let point = CGPoint(x: x, y: y)
260
292
  let textInputCandidates = textInputCandidatesAt(app: app, point: point)
@@ -268,20 +300,7 @@ extension RunnerTests {
268
300
  .filter { element in
269
301
  element.exists && !element.frame.isEmpty && element.frame.contains(point)
270
302
  }
271
- .sorted { left, right in
272
- let leftArea = max(1, left.frame.width * left.frame.height)
273
- let rightArea = max(1, right.frame.width * right.frame.height)
274
- if leftArea != rightArea {
275
- return leftArea < rightArea
276
- }
277
- if left.frame.minY != right.frame.minY {
278
- return left.frame.minY < right.frame.minY
279
- }
280
- if left.frame.minX != right.frame.minX {
281
- return left.frame.minX < right.frame.minX
282
- }
283
- return left.elementType.rawValue < right.elementType.rawValue
284
- }
303
+ .sorted(by: smallestElementFirst)
285
304
 
286
305
  for element in candidates where prefersExpandedTextRead(element) {
287
306
  if let text = readableText(for: element) {
@@ -317,32 +336,16 @@ extension RunnerTests {
317
336
  .filter { element in
318
337
  guard element.exists else { return false }
319
338
  let frame = element.frame
320
- return !frame.isEmpty && frameContainsPoint(frame, point, tolerance: 2)
321
- }
322
- .sorted { left, right in
323
- let leftArea = max(1, left.frame.width * left.frame.height)
324
- let rightArea = max(1, right.frame.width * right.frame.height)
325
- if leftArea != rightArea {
326
- return leftArea < rightArea
327
- }
328
- if left.frame.minY != right.frame.minY {
329
- return left.frame.minY < right.frame.minY
330
- }
331
- if left.frame.minX != right.frame.minX {
332
- return left.frame.minX < right.frame.minX
333
- }
334
- return left.elementType.rawValue < right.elementType.rawValue
339
+ return isCoordinateTextInputCandidate(
340
+ enabled: element.isEnabled,
341
+ frame: frame,
342
+ point: point
343
+ )
335
344
  }
345
+ .sorted(by: smallestElementFirst)
336
346
  }
337
347
  }
338
348
 
339
- private func frameContainsPoint(_ frame: CGRect, _ point: CGPoint, tolerance: CGFloat) -> Bool {
340
- point.x >= frame.minX - tolerance
341
- && point.x <= frame.maxX + tolerance
342
- && point.y >= frame.minY - tolerance
343
- && point.y <= frame.maxY + tolerance
344
- }
345
-
346
349
  private func readableText(for element: XCUIElement) -> String? {
347
350
  let label = element.label.trimmingCharacters(in: .whitespacesAndNewlines)
348
351
  let identifier = element.identifier.trimmingCharacters(in: .whitespacesAndNewlines)
@@ -369,16 +372,6 @@ extension RunnerTests {
369
372
  }
370
373
  }
371
374
 
372
- func findScopeElement(app: XCUIApplication, scope: String) -> XCUIElement? {
373
- let predicate = NSPredicate(
374
- format: "label CONTAINS[c] %@ OR identifier CONTAINS[c] %@",
375
- scope,
376
- scope
377
- )
378
- let element = app.descendants(matching: .any).matching(predicate).firstMatch
379
- return element.exists ? element : nil
380
- }
381
-
382
375
  func tapAt(app: XCUIApplication, x: Double, y: Double) -> RunnerInteractionOutcome {
383
376
  if let outcome = selectFocusedTvElement(app: app, point: CGPoint(x: x, y: y), action: "tap") {
384
377
  return outcome
@@ -395,30 +388,14 @@ extension RunnerTests {
395
388
  case "secondary":
396
389
  coordinate.rightClick()
397
390
  case "middle":
398
- throw NSError(
399
- domain: "AgentDeviceRunner",
400
- code: 1,
401
- userInfo: [NSLocalizedDescriptionKey: "middle mouse button is not supported"]
402
- )
391
+ throw RunnerUnsupportedOperationError(message: "middle mouse button is not supported")
403
392
  default:
404
- throw NSError(
405
- domain: "AgentDeviceRunner",
406
- code: 1,
407
- userInfo: [NSLocalizedDescriptionKey: "unsupported mouse button: \(button)"]
408
- )
393
+ throw RunnerUnsupportedOperationError(message: "unsupported mouse button: \(button)")
409
394
  }
410
395
  #elseif os(tvOS)
411
- throw NSError(
412
- domain: "AgentDeviceRunner",
413
- code: 1,
414
- userInfo: [NSLocalizedDescriptionKey: "mouseClick is not supported on tvOS"]
415
- )
396
+ throw RunnerUnsupportedOperationError(message: "mouseClick is not supported on tvOS")
416
397
  #else
417
- throw NSError(
418
- domain: "AgentDeviceRunner",
419
- code: 1,
420
- userInfo: [NSLocalizedDescriptionKey: "mouseClick is only supported on macOS"]
421
- )
398
+ throw RunnerUnsupportedOperationError(message: "mouseClick is only supported on macOS")
422
399
  #endif
423
400
  }
424
401
 
@@ -426,22 +403,16 @@ extension RunnerTests {
426
403
  app: XCUIApplication,
427
404
  x: Double,
428
405
  y: Double,
429
- direction: String,
406
+ direction: RunnerScrollDirection,
430
407
  pixels: Double,
431
408
  durationMs: Double?
432
409
  ) throws {
433
410
  #if os(macOS)
434
- guard let events = desktopScrollWheelDeltaEvents(
411
+ let events = desktopScrollWheelDeltaEvents(
435
412
  direction: direction,
436
413
  pixels: pixels,
437
414
  durationMs: durationMs
438
- ) else {
439
- throw NSError(
440
- domain: "AgentDeviceRunner",
441
- code: 1,
442
- userInfo: [NSLocalizedDescriptionKey: "unsupported desktop scroll direction: \(direction)"]
443
- )
444
- }
415
+ )
445
416
 
446
417
  let coordinate = interactionCoordinate(app: app, x: x, y: y)
447
418
  let interval = desktopScrollEventIntervalSeconds(durationMs: durationMs, eventCount: events.count)
@@ -457,44 +428,35 @@ extension RunnerTests {
457
428
  }
458
429
  }
459
430
  #elseif os(tvOS)
460
- throw NSError(
461
- domain: "AgentDeviceRunner",
462
- code: 1,
463
- userInfo: [NSLocalizedDescriptionKey: "desktopScroll is not supported on tvOS"]
464
- )
431
+ throw RunnerUnsupportedOperationError(message: "desktopScroll is not supported on tvOS")
465
432
  #else
466
- throw NSError(
467
- domain: "AgentDeviceRunner",
468
- code: 1,
469
- userInfo: [NSLocalizedDescriptionKey: "desktopScroll is only supported on macOS"]
470
- )
433
+ throw RunnerUnsupportedOperationError(message: "desktopScroll is only supported on macOS")
471
434
  #endif
472
435
  }
473
436
 
474
- func desktopScrollWheelDeltas(direction: String, pixels: Double) -> (vertical: Int32, horizontal: Int32)? {
437
+ func desktopScrollWheelDeltas(
438
+ direction: RunnerScrollDirection,
439
+ pixels: Double
440
+ ) -> (vertical: Int32, horizontal: Int32) {
475
441
  let magnitude = Int32(max(1, min(Double(Int32.max), pixels.rounded())))
476
442
  switch direction {
477
- case "up":
443
+ case .up:
478
444
  return (vertical: magnitude, horizontal: 0)
479
- case "down":
445
+ case .down:
480
446
  return (vertical: -magnitude, horizontal: 0)
481
- case "left":
447
+ case .left:
482
448
  return (vertical: 0, horizontal: magnitude)
483
- case "right":
449
+ case .right:
484
450
  return (vertical: 0, horizontal: -magnitude)
485
- default:
486
- return nil
487
451
  }
488
452
  }
489
453
 
490
454
  func desktopScrollWheelDeltaEvents(
491
- direction: String,
455
+ direction: RunnerScrollDirection,
492
456
  pixels: Double,
493
457
  durationMs: Double?
494
- ) -> [(vertical: Int32, horizontal: Int32)]? {
495
- guard let totalDeltas = desktopScrollWheelDeltas(direction: direction, pixels: pixels) else {
496
- return nil
497
- }
458
+ ) -> [(vertical: Int32, horizontal: Int32)] {
459
+ let totalDeltas = desktopScrollWheelDeltas(direction: direction, pixels: pixels)
498
460
  let magnitude = max(abs(Int(totalDeltas.vertical)), abs(Int(totalDeltas.horizontal)))
499
461
  let duration = max(0, durationMs ?? 0)
500
462
  let requestedEventCount = duration > 0 ? Int(ceil(duration / 16.0)) : 1
@@ -647,6 +609,15 @@ extension RunnerTests {
647
609
  y2: Double(end.y),
648
610
  durationMs: durationMs
649
611
  )
612
+ case .controlledScroll:
613
+ RunnerSynthesizedGesture.synthesizeControlledScroll(
614
+ withApplication: app,
615
+ x: Double(start.x),
616
+ y: Double(start.y),
617
+ x2: Double(end.x),
618
+ y2: Double(end.y),
619
+ durationMs: durationMs
620
+ )
650
621
  case .fastSwipe:
651
622
  RunnerSynthesizedGesture.synthesizeSwipe(
652
623
  withApplication: app,
@@ -108,7 +108,7 @@ extension RunnerTests {
108
108
  // old PID before refreshCachedTargetIfProcessChanged can observe it.
109
109
  clearSnapshotXCTestChannelPenalty(reason: "external_app_relaunch")
110
110
  clearPrivateAXAcceptedDepth(reason: "external_app_relaunch")
111
- needsFirstInteractionDelay = true
111
+ beginFirstInteractionStabilization()
112
112
  return Response(ok: true, data: DataPayload(message: "target reset"))
113
113
  }
114
114
 
@@ -132,7 +132,7 @@ extension RunnerTests {
132
132
  clearSnapshotXCTestChannelPenalty(reason: "target_process_changed")
133
133
  clearPrivateAXAcceptedDepth(reason: "target_process_changed")
134
134
  snapshotXCTestPenaltyWarmupExemptionPending = true
135
- needsFirstInteractionDelay = true
135
+ beginFirstInteractionStabilization()
136
136
  }
137
137
 
138
138
  static func processIdentifier(of target: XCUIApplication) -> Int? {
@@ -205,7 +205,7 @@ extension RunnerTests {
205
205
  currentAppProcessIdentifier = Self.processIdentifier(of: target)
206
206
  clearRememberedTextEntryTap()
207
207
  snapshotXCTestPenaltyWarmupExemptionPending = false
208
- needsFirstInteractionDelay = true
208
+ beginFirstInteractionStabilization()
209
209
  return target
210
210
  }
211
211
 
@@ -320,12 +320,19 @@ extension RunnerTests {
320
320
  sleepFor(postSnapshotInteractionDelay)
321
321
  needsPostSnapshotInteractionDelay = false
322
322
  }
323
- if needsFirstInteractionDelay {
324
- sleepFor(firstInteractionAfterActivateDelay)
325
- needsFirstInteractionDelay = false
323
+ if let readyUptime = firstInteractionReadyUptime {
324
+ sleepFor(readyUptime - ProcessInfo.processInfo.systemUptime)
325
+ firstInteractionReadyUptime = nil
326
326
  }
327
327
  }
328
328
 
329
+ /// Start the post-activation settling window. Measured from now, so the time the caller spends
330
+ /// getting back to us counts towards it instead of being charged twice.
331
+ func beginFirstInteractionStabilization() {
332
+ firstInteractionReadyUptime =
333
+ ProcessInfo.processInfo.systemUptime + firstInteractionAfterActivateDelay
334
+ }
335
+
329
336
  func sleepFor(_ delay: TimeInterval) {
330
337
  guard delay > 0 else { return }
331
338
  // Keep XCTest/UI sources moving during command-local pauses such as delayed typing.
@@ -1,3 +1,5 @@
1
+ import AgentDeviceSnapshotPresentation
2
+
1
3
  // MARK: - Wire Models
2
4
 
3
5
  enum CommandType: String, Codable {
@@ -132,6 +134,7 @@ struct Command: Codable {
132
134
  let direction: String?
133
135
  let amount: Double?
134
136
  let pixels: Double?
137
+ let scrollReleaseBehavior: ScrollReleaseBehavior?
135
138
  let orientation: String?
136
139
  let gesturePlan: RunnerGesturePlan?
137
140
  let outPath: String?
@@ -148,6 +151,11 @@ struct Command: Codable {
148
151
  let steps: [SequenceStep]?
149
152
  }
150
153
 
154
+ enum ScrollReleaseBehavior: String, Codable {
155
+ case controlled
156
+ case inertial
157
+ }
158
+
151
159
  /// Canonical one- or two-pointer plan produced by the portable TypeScript planner.
152
160
  struct RunnerGesturePlan: Codable {
153
161
  let topology: String
@@ -207,14 +215,8 @@ struct SequenceStepResult: Codable {
207
215
 
208
216
  struct Response: Codable {
209
217
  let ok: Bool
210
- let data: DataPayload?
211
- let error: ErrorPayload?
212
-
213
- init(ok: Bool, data: DataPayload? = nil, error: ErrorPayload? = nil) {
214
- self.ok = ok
215
- self.data = data
216
- self.error = error
217
- }
218
+ var data: DataPayload?
219
+ var error: ErrorPayload?
218
220
  }
219
221
 
220
222
  extension Response {
@@ -230,181 +232,76 @@ extension Response {
230
232
  }
231
233
 
232
234
  struct DataPayload: Codable {
233
- let message: String?
234
- let imageBase64: String?
235
- let text: String?
236
- let found: Bool?
237
- let items: [String]?
238
- let nodes: [SnapshotNode]?
239
- let truncated: Bool?
240
- let snapshotQuality: SnapshotQuality?
241
- let gestureStartUptimeMs: Double?
242
- let gestureEndUptimeMs: Double?
243
- let x: Double?
244
- let y: Double?
245
- let x2: Double?
246
- let y2: Double?
247
- let referenceWidth: Double?
248
- let referenceHeight: Double?
235
+ var message: String?
236
+ var imageBase64: String?
237
+ var text: String?
238
+ var found: Bool?
239
+ var items: [String]?
240
+ var nodes: [PresentedNode]?
241
+ var truncated: Bool?
242
+ var qualityPayload: SnapshotQualityPayload? = nil
243
+ var snapshotQuality: SnapshotQuality?
244
+ var gestureStartUptimeMs: Double?
245
+ var gestureEndUptimeMs: Double?
246
+ var x: Double?
247
+ var y: Double?
248
+ var x2: Double?
249
+ var y2: Double?
250
+ var referenceWidth: Double?
251
+ var referenceHeight: Double?
249
252
  var currentUptimeMs: Double?
250
- let commandId: String?
251
- let lifecycleState: String?
252
- let lifecycleCommand: String?
253
- let lifecycleResponseOk: Bool?
254
- let lifecycleResponseJson: String?
255
- let lifecycleErrorCode: String?
256
- let lifecycleErrorMessage: String?
257
- let lifecycleErrorHint: String?
258
- let visible: Bool?
259
- let wasVisible: Bool?
260
- let dismissed: Bool?
261
- let keyboardDismissMechanism: String?
262
- let orientation: String?
263
- let gestureFallback: String?
264
- let gestureFallbackMessage: String?
265
- let gestureFallbackHint: String?
266
- let maestroNonHittableCoordinateFallbackUsed: Bool?
267
- let textEntryRoute: String?
268
- let runnerFatal: Bool?
269
- let runnerFatalReason: String?
270
- let completedSteps: Int?
271
- let failedStepIndex: Int?
272
- let sequenceResults: [SequenceStepResult]?
253
+ var commandId: String?
254
+ var lifecycleState: String?
255
+ var lifecycleCommand: String?
256
+ var lifecycleResponseOk: Bool?
257
+ var lifecycleResponseJson: String?
258
+ var lifecycleErrorCode: String?
259
+ var lifecycleErrorMessage: String?
260
+ var lifecycleErrorHint: String?
261
+ var visible: Bool?
262
+ var wasVisible: Bool?
263
+ var dismissed: Bool?
264
+ var keyboardDismissMechanism: String?
265
+ var orientation: String?
266
+ var gestureFallback: String?
267
+ var gestureFallbackMessage: String?
268
+ var gestureFallbackHint: String?
269
+ var maestroNonHittableCoordinateFallbackUsed: Bool?
270
+ var textEntryRoute: String?
271
+ var runnerFatal: Bool?
272
+ var runnerFatalReason: String?
273
+ var completedSteps: Int?
274
+ var failedStepIndex: Int?
275
+ var sequenceResults: [SequenceStepResult]?
276
+ }
277
+
278
+ struct SnapshotQualityPayload: Codable {
279
+ let nodes: [PresentedNode]
280
+ let truncated: Bool
281
+ let scope: String?
273
282
 
274
- init(
275
- message: String? = nil,
276
- imageBase64: String? = nil,
277
- text: String? = nil,
278
- found: Bool? = nil,
279
- items: [String]? = nil,
280
- nodes: [SnapshotNode]? = nil,
281
- truncated: Bool? = nil,
282
- snapshotQuality: SnapshotQuality? = nil,
283
- gestureStartUptimeMs: Double? = nil,
284
- gestureEndUptimeMs: Double? = nil,
285
- x: Double? = nil,
286
- y: Double? = nil,
287
- x2: Double? = nil,
288
- y2: Double? = nil,
289
- referenceWidth: Double? = nil,
290
- referenceHeight: Double? = nil,
291
- currentUptimeMs: Double? = nil,
292
- commandId: String? = nil,
293
- lifecycleState: String? = nil,
294
- lifecycleCommand: String? = nil,
295
- lifecycleResponseOk: Bool? = nil,
296
- lifecycleResponseJson: String? = nil,
297
- lifecycleErrorCode: String? = nil,
298
- lifecycleErrorMessage: String? = nil,
299
- lifecycleErrorHint: String? = nil,
300
- visible: Bool? = nil,
301
- wasVisible: Bool? = nil,
302
- dismissed: Bool? = nil,
303
- keyboardDismissMechanism: String? = nil,
304
- orientation: String? = nil,
305
- gestureFallback: String? = nil,
306
- gestureFallbackMessage: String? = nil,
307
- gestureFallbackHint: String? = nil,
308
- maestroNonHittableCoordinateFallbackUsed: Bool? = nil,
309
- textEntryRoute: String? = nil,
310
- runnerFatal: Bool? = nil,
311
- runnerFatalReason: String? = nil,
312
- completedSteps: Int? = nil,
313
- failedStepIndex: Int? = nil,
314
- sequenceResults: [SequenceStepResult]? = nil
315
- ) {
316
- self.message = message
317
- self.imageBase64 = imageBase64
318
- self.text = text
319
- self.found = found
320
- self.items = items
283
+ init(nodes: [PresentedNode], truncated: Bool) {
321
284
  self.nodes = nodes
322
285
  self.truncated = truncated
323
- self.snapshotQuality = snapshotQuality
324
- self.gestureStartUptimeMs = gestureStartUptimeMs
325
- self.gestureEndUptimeMs = gestureEndUptimeMs
326
- self.x = x
327
- self.y = y
328
- self.x2 = x2
329
- self.y2 = y2
330
- self.referenceWidth = referenceWidth
331
- self.referenceHeight = referenceHeight
332
- self.currentUptimeMs = currentUptimeMs
333
- self.commandId = commandId
334
- self.lifecycleState = lifecycleState
335
- self.lifecycleCommand = lifecycleCommand
336
- self.lifecycleResponseOk = lifecycleResponseOk
337
- self.lifecycleResponseJson = lifecycleResponseJson
338
- self.lifecycleErrorCode = lifecycleErrorCode
339
- self.lifecycleErrorMessage = lifecycleErrorMessage
340
- self.lifecycleErrorHint = lifecycleErrorHint
341
- self.visible = visible
342
- self.wasVisible = wasVisible
343
- self.dismissed = dismissed
344
- self.keyboardDismissMechanism = keyboardDismissMechanism
345
- self.orientation = orientation
346
- self.gestureFallback = gestureFallback
347
- self.gestureFallbackMessage = gestureFallbackMessage
348
- self.gestureFallbackHint = gestureFallbackHint
349
- self.maestroNonHittableCoordinateFallbackUsed = maestroNonHittableCoordinateFallbackUsed
350
- self.textEntryRoute = textEntryRoute
351
- self.runnerFatal = runnerFatal
352
- self.runnerFatalReason = runnerFatalReason
353
- self.completedSteps = completedSteps
354
- self.failedStepIndex = failedStepIndex
355
- self.sequenceResults = sequenceResults
286
+ self.scope = nil
356
287
  }
357
- }
358
-
359
- struct ErrorPayload: Codable {
360
- let code: String?
361
- let message: String
362
- let hint: String?
363
288
 
364
- init(code: String? = nil, message: String, hint: String? = nil) {
365
- self.code = code
366
- self.message = message
367
- self.hint = hint
289
+ private enum CodingKeys: String, CodingKey {
290
+ case nodes
291
+ case truncated
292
+ case scope
368
293
  }
369
- }
370
-
371
- struct SnapshotRect: Codable {
372
- let x: Double
373
- let y: Double
374
- let width: Double
375
- let height: Double
376
- }
377
294
 
378
- struct SnapshotNode: Codable {
379
- let index: Int
380
- let type: String
381
- let label: String?
382
- let identifier: String?
383
- let value: String?
384
- let rect: SnapshotRect
385
- let enabled: Bool
386
- let focused: Bool?
387
- let selected: Bool?
388
- let hittable: Bool
389
- let depth: Int
390
- let parentIndex: Int?
391
- let hiddenContentAbove: Bool?
392
- let hiddenContentBelow: Bool?
393
- /// Names of the element's UIAccessibilityCustomActions, present only when the
394
- /// capture asked for them and the element carries some.
395
- var actions: [String]? = nil
295
+ func encode(to encoder: Encoder) throws {
296
+ var container = encoder.container(keyedBy: CodingKeys.self)
297
+ try container.encode(nodes, forKey: .nodes)
298
+ try container.encode(truncated, forKey: .truncated)
299
+ try container.encodeNil(forKey: .scope)
300
+ }
396
301
  }
397
302
 
398
- struct SnapshotOptions {
399
- let interactiveOnly: Bool
400
- let depth: Int?
401
- let scope: String?
402
- let raw: Bool
403
- /// Internal daemon ask: capture with this backend first regardless of channel
404
- /// health ("private-ax"). Same-backend evidence probes (tap-outcome
405
- /// corroboration) must be captured the way their baseline was.
406
- var preferredBackend: String? = nil
407
- /// Read UIAccessibilityCustomActions for merged leaves. Opt-in: each element
408
- /// costs its own AX round trip (see RunnerAXSnapshotBridge).
409
- var customActions: Bool = false
303
+ struct ErrorPayload: Codable {
304
+ var code: String?
305
+ let message: String
306
+ var hint: String?
410
307
  }
@@ -81,17 +81,16 @@ extension RunnerTests {
81
81
  return navigationBackKeywords.firstIndex { text.contains($0) }
82
82
  }
83
83
 
84
+ // isFinite/>0 alone don't reject CGRect.infinite — its origin (~-9e307) is finite.
85
+ static func isUsableNavigationFrame(_ frame: CGRect) -> Bool {
86
+ guard frame.width.isFinite, frame.height.isFinite, frame.width > 0, frame.height > 0 else {
87
+ return false
88
+ }
89
+ return !frame.isInfinite
90
+ }
91
+
84
92
  static func isTopNavigationControlFrame(_ candidate: CGRect, in window: CGRect) -> Bool {
85
- guard
86
- candidate.width.isFinite,
87
- candidate.height.isFinite,
88
- window.width.isFinite,
89
- window.height.isFinite,
90
- candidate.width > 0,
91
- candidate.height > 0,
92
- window.width > 0,
93
- window.height > 0
94
- else {
93
+ guard isUsableNavigationFrame(candidate), isUsableNavigationFrame(window) else {
95
94
  return false
96
95
  }
97
96
  // Accept the compact navigation/search header band without matching deep content controls.
@@ -100,7 +99,7 @@ extension RunnerTests {
100
99
  }
101
100
 
102
101
  static func topLeadingNavigationFallbackPoint(in frame: CGRect) -> CGPoint? {
103
- guard frame.width.isFinite, frame.height.isFinite, frame.width > 0, frame.height > 0 else {
102
+ guard isUsableNavigationFrame(frame) else {
104
103
  return nil
105
104
  }
106
105
  // Aim at the standard leading navigation slot, bounded for compact and tablet widths.