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,4 +1,5 @@
1
1
  import XCTest
2
+ import AgentDeviceSnapshotPresentation
2
3
 
3
4
 
4
5
  extension RunnerTests {
@@ -164,16 +165,6 @@ extension RunnerTests {
164
165
  }
165
166
 
166
167
 
167
- func execute(command: Command) throws -> Response {
168
- if command.command == .status {
169
- return executeStatus(command: command)
170
- }
171
- if command.command == .uptime {
172
- return executeUptime()
173
- }
174
- commandJournal.accept(command: command)
175
- return try executeAccepted(command: command)
176
- }
177
168
 
178
169
  func executeAccepted(command: Command) throws -> Response {
179
170
  commandJournal.start(command: command)
@@ -189,9 +180,7 @@ extension RunnerTests {
189
180
 
190
181
  func executeStatus(command: Command) -> Response {
191
182
  guard
192
- let statusCommandId = command.statusCommandId?
193
- .trimmingCharacters(in: .whitespacesAndNewlines),
194
- !statusCommandId.isEmpty
183
+ let statusCommandId = command.statusCommandId?.trimmedNonEmpty
195
184
  else {
196
185
  return Response(
197
186
  ok: false,
@@ -202,7 +191,7 @@ extension RunnerTests {
202
191
  )
203
192
  )
204
193
  }
205
- return Response(ok: true, data: commandJournal.status(commandId: statusCommandId))
194
+ return Response(ok: true, data: commandJournal.status(normalizedCommandId: statusCommandId))
206
195
  }
207
196
 
208
197
  func executeUptime() -> Response {
@@ -308,10 +297,7 @@ extension RunnerTests {
308
297
  ? Date().addingTimeInterval(Self.alertCommandTimeout(timeoutMs: command.timeoutMs))
309
298
  : nil
310
299
  if Thread.isMainThread {
311
- let routeToSpringboard = shouldRouteToSpringboardBlockingSystemModal(
312
- command,
313
- deadline: alertDeadline
314
- )
300
+ let routeToSpringboard = shouldRouteToSpringboardBlockingSystemModal(command)
315
301
  return try executeOnMainSafely(
316
302
  command: command,
317
303
  alertDeadline: alertDeadline,
@@ -321,10 +307,7 @@ extension RunnerTests {
321
307
  // Resolve this before the command's outer main-thread block. If the bounded probe abandons
322
308
  // slow XCTest enumeration, return the established recoverable response instead of queueing
323
309
  // command preparation behind work that may outlive the 30-second command watchdog.
324
- let routeToSpringboard = shouldRouteToSpringboardBlockingSystemModal(
325
- command,
326
- deadline: alertDeadline
327
- )
310
+ let routeToSpringboard = shouldRouteToSpringboardBlockingSystemModal(command)
328
311
  if let unavailable = runnerUnavailableResponse(command: command) {
329
312
  return unavailable
330
313
  }
@@ -333,7 +316,6 @@ extension RunnerTests {
333
316
  }
334
317
  if command.command == .alert, let deadline = alertDeadline {
335
318
  return try runMainThreadWork(
336
- command: command,
337
319
  timeout: max(0.001, deadline.timeIntervalSinceNow),
338
320
  timeoutError: mainThreadExecutionTimeoutError
339
321
  ) {
@@ -345,7 +327,6 @@ extension RunnerTests {
345
327
  }
346
328
  }
347
329
  return try runMainThreadWork(
348
- command: command,
349
330
  timeout: mainThreadExecutionTimeout,
350
331
  timeoutError: mainThreadExecutionTimeoutError
351
332
  ) {
@@ -354,7 +335,6 @@ extension RunnerTests {
354
335
  }
355
336
 
356
337
  func runMainThreadWork<T>(
357
- command: Command?,
358
338
  timeout: TimeInterval,
359
339
  timeoutError: @escaping () -> Error,
360
340
  onAbandoned: (() -> Void)? = nil,
@@ -512,7 +492,6 @@ extension RunnerTests {
512
492
  var hasRetried = false
513
493
  while true {
514
494
  let failureCountBefore = try runMainThreadWork(
515
- command: command,
516
495
  timeout: mainThreadExecutionTimeout,
517
496
  timeoutError: mainThreadExecutionTimeoutError
518
497
  ) {
@@ -529,7 +508,6 @@ extension RunnerTests {
529
508
  return response
530
509
  }
531
510
  let recordedFailureResponse = try runMainThreadWork(
532
- command: command,
533
511
  timeout: mainThreadExecutionTimeout,
534
512
  timeoutError: mainThreadExecutionTimeoutError
535
513
  ) {
@@ -539,7 +517,6 @@ extension RunnerTests {
539
517
  }
540
518
  if let recordedFailureResponse {
541
519
  try runMainThreadWork(
542
- command: command,
543
520
  timeout: mainThreadExecutionTimeout,
544
521
  timeoutError: mainThreadExecutionTimeoutError
545
522
  ) {
@@ -554,7 +531,6 @@ extension RunnerTests {
554
531
  )
555
532
  hasRetried = true
556
533
  try runMainThreadWork(
557
- command: command,
558
534
  timeout: mainThreadExecutionTimeout,
559
535
  timeoutError: mainThreadExecutionTimeoutError
560
536
  ) {
@@ -569,7 +545,6 @@ extension RunnerTests {
569
545
 
570
546
  private func executeSnapshotDispatchedOnce(command: Command) throws -> Response {
571
547
  let preparation = try runMainThreadWork(
572
- command: command,
573
548
  timeout: mainThreadExecutionTimeout,
574
549
  timeoutError: mainThreadExecutionTimeoutError
575
550
  ) {
@@ -584,10 +559,10 @@ extension RunnerTests {
584
559
  }
585
560
 
586
561
  /// Pure command→options projection, extracted so the runner unit bundle can
587
- /// prove the decoded wire field actually reaches capture options (#1634 P2).
588
- static func snapshotOptions(from command: Command) -> SnapshotOptions {
562
+ /// prove the decoded wire field actually reaches presentation options (#1634 P2).
563
+ static func presentationOptions(from command: Command) -> PresentationOptions {
589
564
  let customActions = command.customActions ?? false
590
- return SnapshotOptions(
565
+ return PresentationOptions(
591
566
  interactiveOnly: command.interactiveOnly ?? false,
592
567
  depth: command.depth,
593
568
  scope: command.scope,
@@ -602,7 +577,7 @@ extension RunnerTests {
602
577
  }
603
578
 
604
579
  private func executeSnapshotPrepared(command: Command, activeApp: XCUIApplication) throws -> Response {
605
- let options = Self.snapshotOptions(from: command)
580
+ let options = Self.presentationOptions(from: command)
606
581
  do {
607
582
  let payload: DataPayload
608
583
  if options.raw {
@@ -636,7 +611,6 @@ extension RunnerTests {
636
611
  }
637
612
  do {
638
613
  try runMainThreadWork(
639
- command: nil,
640
614
  timeout: 1,
641
615
  timeoutError: mainThreadExecutionTimeoutError
642
616
  ) {
@@ -654,7 +628,6 @@ extension RunnerTests {
654
628
  }
655
629
  do {
656
630
  try runMainThreadWork(
657
- command: nil,
658
631
  timeout: 1,
659
632
  timeoutError: mainThreadExecutionTimeoutError
660
633
  ) {
@@ -1117,13 +1090,14 @@ extension RunnerTests {
1117
1090
  guard let x = command.x, let y = command.y, let x2 = command.x2, let y2 = command.y2 else {
1118
1091
  return Response(ok: false, error: ErrorPayload(message: "drag requires x, y, x2, and y2"))
1119
1092
  }
1093
+ let defaults = runnerDragCommandDefaults(command)
1120
1094
  return executeDragGesture(
1121
1095
  activeApp: activeApp,
1122
1096
  x: x,
1123
1097
  y: y,
1124
1098
  x2: x2,
1125
1099
  y2: y2,
1126
- durationMs: command.durationMs,
1100
+ durationMs: defaults.durationMs,
1127
1101
  synthesized: command.synthesized == true,
1128
1102
  message: "dragged",
1129
1103
  synthesizedPolicyKind: .synthesizedDrag
@@ -1132,16 +1106,10 @@ extension RunnerTests {
1132
1106
  // Fused frame-resolve + drag scroll for non-tvOS. On iOS this intentionally stays on the
1133
1107
  // AX-free synthesized coordinate lane so scroll keeps working when XCTest cannot serialize
1134
1108
  // the accessibility tree.
1135
- guard let direction = command.direction,
1136
- direction == "up" || direction == "down" || direction == "left" || direction == "right"
1109
+ guard let rawDirection = command.direction,
1110
+ let direction = RunnerScrollDirection(rawValue: rawDirection)
1137
1111
  else {
1138
- return Response(
1139
- ok: false,
1140
- error: ErrorPayload(
1141
- code: "INVALID_ARGS",
1142
- message: "scroll requires direction up|down|left|right"
1143
- )
1144
- )
1112
+ return invalidScrollDirectionResponse(commandName: "scroll")
1145
1113
  }
1146
1114
  let scrollPolicyKind = SynthesizedGesturePolicyKind.scroll
1147
1115
  guard let scrollContext = synthesizedCoordinateContext(
@@ -1160,9 +1128,10 @@ extension RunnerTests {
1160
1128
  error: ErrorPayload(message: "scroll could not resolve a usable interaction frame")
1161
1129
  )
1162
1130
  }
1131
+ let defaults = runnerDragCommandDefaults(command)
1163
1132
  guard let plan = runnerScrollGesturePlan(
1164
1133
  direction: direction,
1165
- amount: command.amount,
1134
+ amount: defaults.scrollAmount,
1166
1135
  pixels: command.pixels,
1167
1136
  referenceWidth: frame.width,
1168
1137
  referenceHeight: frame.height
@@ -1175,40 +1144,25 @@ extension RunnerTests {
1175
1144
  )
1176
1145
  )
1177
1146
  }
1178
- if let durationMs = command.durationMs,
1179
- durationMs.isFinite == false || durationMs < 0 || durationMs > 10000
1180
- {
1181
- return Response(
1182
- ok: false,
1183
- error: ErrorPayload(
1184
- code: "INVALID_ARGS",
1185
- message: "scroll durationMs must be between 0 and 10000"
1186
- )
1187
- )
1147
+ guard scrollDurationIsValid(command.durationMs) else {
1148
+ return invalidScrollDurationResponse(commandName: "scroll")
1188
1149
  }
1189
- return executeDragGesture(
1150
+ return executeScrollDragGesture(
1190
1151
  activeApp: activeApp,
1191
1152
  x: frame.minX + plan.x1,
1192
1153
  y: frame.minY + plan.y1,
1193
1154
  x2: frame.minX + plan.x2,
1194
1155
  y2: frame.minY + plan.y2,
1195
- durationMs: command.durationMs,
1196
- synthesized: shouldUseSynthesizedScrollPath(),
1156
+ durationMs: defaults.durationMs,
1197
1157
  message: "scrolled",
1198
- synthesizedContext: scrollContext.withReferenceFrame(frame),
1199
- synthesizedPolicyKind: scrollPolicyKind
1158
+ context: scrollContext.withReferenceFrame(frame),
1159
+ releaseBehavior: command.scrollReleaseBehavior
1200
1160
  )
1201
1161
  case .desktopScroll:
1202
- guard let direction = command.direction,
1203
- direction == "up" || direction == "down" || direction == "left" || direction == "right"
1162
+ guard let rawDirection = command.direction,
1163
+ let direction = RunnerScrollDirection(rawValue: rawDirection)
1204
1164
  else {
1205
- return Response(
1206
- ok: false,
1207
- error: ErrorPayload(
1208
- code: "INVALID_ARGS",
1209
- message: "desktopScroll requires direction up|down|left|right"
1210
- )
1211
- )
1165
+ return invalidScrollDirectionResponse(commandName: "desktopScroll")
1212
1166
  }
1213
1167
  let appFrame = activeApp.frame
1214
1168
  let frame = resolvedTouchReferenceFrame(app: activeApp, appFrame: appFrame)
@@ -1237,16 +1191,8 @@ extension RunnerTests {
1237
1191
  let y = frame.midY
1238
1192
  let localX = x - (appFrame.isEmpty ? frame.minX : appFrame.minX)
1239
1193
  let localY = y - (appFrame.isEmpty ? frame.minY : appFrame.minY)
1240
- if let durationMs = command.durationMs,
1241
- durationMs.isFinite == false || durationMs < 0 || durationMs > 10000
1242
- {
1243
- return Response(
1244
- ok: false,
1245
- error: ErrorPayload(
1246
- code: "INVALID_ARGS",
1247
- message: "desktopScroll durationMs must be between 0 and 10000"
1248
- )
1249
- )
1194
+ guard scrollDurationIsValid(command.durationMs) else {
1195
+ return invalidScrollDurationResponse(commandName: "desktopScroll")
1250
1196
  }
1251
1197
  let touchFrame = resolvedTouchVisualizationFrame(
1252
1198
  app: activeApp,
@@ -1441,7 +1387,12 @@ extension RunnerTests {
1441
1387
  Self.alertCommandTimeout(timeoutMs: command.timeoutMs)
1442
1388
  )
1443
1389
  guard let alert = resolveAlert(app: activeApp, deadline: deadline) else {
1444
- return Response(ok: false, error: ErrorPayload(message: "alert not found"))
1390
+ // Typed so the host retries on absence alone: a transport or runner failure carries no
1391
+ // code and must not be mistaken for "no alert yet" (ALERT_NOT_FOUND_RUNNER_CODE).
1392
+ return Response(
1393
+ ok: false,
1394
+ error: ErrorPayload(code: "ALERT_NOT_FOUND", message: "alert not found")
1395
+ )
1445
1396
  }
1446
1397
  return handleAlert(alert, action: action, deadline: deadline)
1447
1398
  case .gesture:
@@ -1493,9 +1444,73 @@ extension RunnerTests {
1493
1444
  }
1494
1445
  }
1495
1446
 
1496
- /// Shared drag execution for `.drag` and the fused `.scroll`. The iOS synthesized lane keeps
1497
- /// each command's fallback policy explicit: scroll requires private synthesis, while explicit
1498
- /// synthesized drag can still use the coordinate fallback unless AX is known unavailable.
1447
+ private func invalidScrollDirectionResponse(commandName: String) -> Response {
1448
+ Response(
1449
+ ok: false,
1450
+ error: ErrorPayload(
1451
+ code: "INVALID_ARGS",
1452
+ message: "\(commandName) requires direction up|down|left|right"
1453
+ )
1454
+ )
1455
+ }
1456
+
1457
+ private func scrollDurationIsValid(_ durationMs: Double?) -> Bool {
1458
+ guard let durationMs else { return true }
1459
+ return durationMs.isFinite && durationMs >= 0 && durationMs <= 10000
1460
+ }
1461
+
1462
+ private func invalidScrollDurationResponse(commandName: String) -> Response {
1463
+ return Response(
1464
+ ok: false,
1465
+ error: ErrorPayload(
1466
+ code: "INVALID_ARGS",
1467
+ message: "\(commandName) durationMs must be between 0 and 10000"
1468
+ )
1469
+ )
1470
+ }
1471
+
1472
+ private func executeScrollDragGesture(
1473
+ activeApp: XCUIApplication,
1474
+ x: Double,
1475
+ y: Double,
1476
+ x2: Double,
1477
+ y2: Double,
1478
+ durationMs: Double,
1479
+ message: String,
1480
+ context: SynthesizedCoordinateContext,
1481
+ releaseBehavior: ScrollReleaseBehavior?
1482
+ ) -> Response {
1483
+ #if os(iOS)
1484
+ return executeDragGesture(
1485
+ activeApp: activeApp,
1486
+ x: x,
1487
+ y: y,
1488
+ x2: x2,
1489
+ y2: y2,
1490
+ durationMs: durationMs,
1491
+ synthesized: true,
1492
+ message: message,
1493
+ synthesizedContext: context,
1494
+ synthesizedPolicyKind: .scroll,
1495
+ synthesizedProfile: scrollDragProfile(releaseBehavior: releaseBehavior)
1496
+ )
1497
+ #else
1498
+ return executeDragGesture(
1499
+ activeApp: activeApp,
1500
+ x: x,
1501
+ y: y,
1502
+ x2: x2,
1503
+ y2: y2,
1504
+ durationMs: durationMs,
1505
+ synthesized: false,
1506
+ message: message,
1507
+ synthesizedPolicyKind: .scroll
1508
+ )
1509
+ #endif
1510
+ }
1511
+
1512
+ /// Shared drag execution for explicit drag commands. The iOS synthesized lane keeps its
1513
+ /// fallback policy explicit; viewport scrolling owns a separate single drag specification.
1499
1514
  private func executeDragGesture(
1500
1515
  activeApp: XCUIApplication,
1501
1516
  x: Double,
@@ -1509,6 +1524,7 @@ extension RunnerTests {
1509
1524
  synthesizedPolicyKind: SynthesizedGesturePolicyKind,
1510
1525
  synthesizedProfile: SynthesizedDragProfile = .continuous
1511
1526
  ) -> Response {
1527
+ let durationMs = durationMs ?? runnerDefaultDragDurationMs
1512
1528
  let commandName = dragCommandName(message: message)
1513
1529
  guard x.isFinite, y.isFinite, x2.isFinite, y2.isFinite else {
1514
1530
  return Response(
@@ -1540,7 +1556,7 @@ extension RunnerTests {
1540
1556
  )
1541
1557
  var fallback: GestureFallback?
1542
1558
  if synthesized {
1543
- let durationMs = min(max(durationMs ?? 250, 16), 10000)
1559
+ let durationMs = min(max(durationMs, 16), 10000)
1544
1560
  let context = synthesizedCoordinateContext(
1545
1561
  app: activeApp,
1546
1562
  policy: synthesizedGesturePolicy(synthesizedPolicyKind)
@@ -1563,7 +1579,7 @@ extension RunnerTests {
1563
1579
  fallback = gestureFallback(strategy: "xctest-coordinate-drag", from: outcome)
1564
1580
  }
1565
1581
  let holdDuration = synthesized
1566
- ? synthesizedSwipeFallbackHoldDuration(durationMs: durationMs ?? 250)
1582
+ ? synthesizedSwipeFallbackHoldDuration(durationMs: durationMs)
1567
1583
  : coordinateDragHoldDuration()
1568
1584
  let (timing, outcome) = performGesture(activeApp) {
1569
1585
  dragAt(
@@ -1592,7 +1608,7 @@ extension RunnerTests {
1592
1608
  y: Double,
1593
1609
  x2: Double,
1594
1610
  y2: Double,
1595
- durationMs: Double?,
1611
+ durationMs: Double,
1596
1612
  message: String,
1597
1613
  context: SynthesizedCoordinateContext?,
1598
1614
  policyKind: SynthesizedGesturePolicyKind,
@@ -1632,7 +1648,7 @@ extension RunnerTests {
1632
1648
  )
1633
1649
  )
1634
1650
  }
1635
- let durationMs = min(max(durationMs ?? 250, 16), 10000)
1651
+ let durationMs = min(max(durationMs, 16), 10000)
1636
1652
  let dragFrame = axFreeDragVisualizationFrame(
1637
1653
  x: plan.points.x,
1638
1654
  y: plan.points.y,
@@ -1682,7 +1698,7 @@ extension RunnerTests {
1682
1698
  y: Double,
1683
1699
  x2: Double,
1684
1700
  y2: Double,
1685
- durationMs: Double?,
1701
+ durationMs: Double,
1686
1702
  message: String,
1687
1703
  fallback: GestureFallback?
1688
1704
  ) -> Response {
@@ -1694,7 +1710,7 @@ extension RunnerTests {
1694
1710
  x2: dragPoints.x2,
1695
1711
  y2: dragPoints.y2
1696
1712
  )
1697
- let holdDuration = synthesizedSwipeFallbackHoldDuration(durationMs: durationMs ?? 250)
1713
+ let holdDuration = synthesizedSwipeFallbackHoldDuration(durationMs: durationMs)
1698
1714
  let (timing, outcome) = performGesture(activeApp) {
1699
1715
  dragAt(
1700
1716
  app: activeApp,
@@ -1724,14 +1740,6 @@ extension RunnerTests {
1724
1740
  #endif
1725
1741
  }
1726
1742
 
1727
- private func shouldUseSynthesizedScrollPath() -> Bool {
1728
- #if os(iOS)
1729
- return true
1730
- #else
1731
- return false
1732
- #endif
1733
- }
1734
-
1735
1743
  private func dragCommandName(message: String) -> String {
1736
1744
  return message == "scrolled" ? "scroll" : "drag"
1737
1745
  }
@@ -1762,9 +1770,6 @@ extension RunnerTests {
1762
1770
  )
1763
1771
  }
1764
1772
 
1765
- func runnerCommandFixture(_ json: String) throws -> Command {
1766
- try JSONDecoder().decode(Command.self, from: Data(json.utf8))
1767
- }
1768
1773
 
1769
1774
  private func shouldSkipAppActivationPreflight(_ command: Command) -> Bool {
1770
1775
  #if os(iOS)
@@ -1784,15 +1789,13 @@ extension RunnerTests {
1784
1789
  }
1785
1790
 
1786
1791
  private func shouldRouteToSpringboardBlockingSystemModal(
1787
- _ command: Command,
1788
- deadline: Date? = nil
1792
+ _ command: Command
1789
1793
  ) -> Bool {
1790
1794
  #if os(iOS)
1791
- guard command.command == .alert || isCoordinateOnlyTap(command) else {
1795
+ guard isCoordinateOnlyTap(command) else {
1792
1796
  return false
1793
1797
  }
1794
- let budgetDeadline = Date().addingTimeInterval(systemModalProbeBudget)
1795
- let probeDeadline = deadline.map { min($0, budgetDeadline) } ?? budgetDeadline
1798
+ let probeDeadline = Date().addingTimeInterval(systemModalProbeBudget)
1796
1799
  // `runMainThreadWork` executes inline for a main-thread caller, so that path cannot use its
1797
1800
  // timeout machinery. Direct main-thread dispatch keeps the prior synchronous modal check;
1798
1801
  // normal off-main command dispatch uses the bounded probe and post-probe busy recovery.
@@ -1,5 +1,6 @@
1
1
  import Foundation
2
2
  import XCTest
3
+ import AgentDeviceSnapshotPresentation
3
4
 
4
5
  enum RunnerCommandLifecycleState: String {
5
6
  case notAccepted
@@ -26,7 +27,7 @@ final class RunnerCommandJournal {
26
27
  private var order: [String] = []
27
28
 
28
29
  func accept(command: Command) {
29
- guard let commandId = normalizedCommandId(command.commandId) else { return }
30
+ guard let commandId = command.commandId?.trimmedNonEmpty else { return }
30
31
  lock.lock()
31
32
  defer { lock.unlock() }
32
33
  entries[commandId] = RunnerCommandJournalEntry(
@@ -66,16 +67,13 @@ final class RunnerCommandJournal {
66
67
  )
67
68
  }
68
69
 
69
- func status(commandId: String) -> DataPayload {
70
- guard let normalized = normalizedCommandId(commandId) else {
71
- return DataPayload(lifecycleState: RunnerCommandLifecycleState.notAccepted.rawValue)
72
- }
70
+ func status(normalizedCommandId commandId: String) -> DataPayload {
73
71
  lock.lock()
74
- let entry = entries[normalized]
72
+ let entry = entries[commandId]
75
73
  lock.unlock()
76
74
  guard let entry else {
77
75
  return DataPayload(
78
- commandId: normalized,
76
+ commandId: commandId,
79
77
  lifecycleState: RunnerCommandLifecycleState.notAccepted.rawValue
80
78
  )
81
79
  }
@@ -98,7 +96,7 @@ final class RunnerCommandJournal {
98
96
  responseJson: String?,
99
97
  error: ErrorPayload?
100
98
  ) {
101
- guard let commandId = normalizedCommandId(command.commandId) else { return }
99
+ guard let commandId = command.commandId?.trimmedNonEmpty else { return }
102
100
  lock.lock()
103
101
  defer { lock.unlock() }
104
102
  var entry = entries[commandId] ?? RunnerCommandJournalEntry(
@@ -126,12 +124,6 @@ final class RunnerCommandJournal {
126
124
  }
127
125
  }
128
126
 
129
- private func normalizedCommandId(_ value: String?) -> String? {
130
- guard let value else { return nil }
131
- let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
132
- return trimmed.isEmpty ? nil : trimmed
133
- }
134
-
135
127
  private func encodeResponseJson(command: Command, response: Response) -> String? {
136
128
  guard shouldRetainResponseJson(command: command) else { return nil }
137
129
  guard let data = try? JSONEncoder().encode(response) else { return nil }