agent-device 0.20.10 → 0.21.1

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 (510) hide show
  1. package/README.md +2 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.10.apk → agent-device-android-ime-helper-0.21.1.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.1.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.10.manifest.json → agent-device-android-ime-helper-0.21.1.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.10.manifest.json → agent-device-android-snapshot-helper-0.21.1.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 +106 -0
  12. package/apple/snapshot-bridge/SnapshotBridge.m +286 -0
  13. package/apple/snapshot-bridge/SnapshotBridgeCapture.h +25 -0
  14. package/apple/snapshot-bridge/SnapshotBridgeCapture.m +138 -0
  15. package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +34 -0
  16. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +411 -0
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +12 -0
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +20 -0
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +15 -15
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +72 -0
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +63 -14
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +677 -83
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +35 -92
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +39 -4
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1058 -213
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +296 -14
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +1 -1
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +10 -10
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +309 -149
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +101 -42
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +24 -17
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +124 -199
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +71 -4
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +211 -78
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +30 -10
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +254 -24
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +206 -22
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +465 -494
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +168 -0
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +802 -247
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +185 -0
  51. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
  52. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +83 -5
  53. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +156 -34
  54. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +5 -4
  55. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +35 -318
  56. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
  57. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
  58. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +28 -0
  59. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputProbe.swift +101 -0
  60. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +56 -23
  61. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +56 -27
  62. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +30 -24
  63. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +126 -80
  64. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
  65. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +47 -86
  66. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +32 -79
  67. package/dist/apple/snapshot-presentation/Package.swift +21 -0
  68. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
  69. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
  70. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
  71. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
  72. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
  73. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
  74. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
  75. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
  76. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
  77. package/dist/src/adapter.js +1 -0
  78. package/dist/src/adb-executor.js +2 -0
  79. package/dist/src/adb-failure.js +1 -0
  80. package/dist/src/adb-host.js +1 -0
  81. package/dist/src/adb.js +1 -0
  82. package/dist/src/agent-browser-lifecycle.js +1 -0
  83. package/dist/src/agent-browser-process-record.js +1 -0
  84. package/dist/src/agent-browser-provider.js +1 -0
  85. package/dist/src/agent-browser-tool.js +1 -1
  86. package/dist/src/agent-device-client.js +2 -2
  87. package/dist/src/ai-sdk.d.ts +2 -2
  88. package/dist/src/ai-sdk.js +1 -1
  89. package/dist/src/alert-contract.js +1 -0
  90. package/dist/src/alert-runtime.js +1 -0
  91. package/dist/src/android-adb.d.ts +27 -19
  92. package/dist/src/android-adb.js +1 -1
  93. package/dist/src/android-input-ownership.js +1 -0
  94. package/dist/src/android-system-chrome.js +1 -0
  95. package/dist/src/android.js +1 -1
  96. package/dist/src/api.js +11 -0
  97. package/dist/src/app-catalog.js +1 -0
  98. package/dist/src/app-deployment-resolution.js +2 -0
  99. package/dist/src/app-helpers.js +1 -1
  100. package/dist/src/app-inventory-contract.js +1 -0
  101. package/dist/src/app-inventory.js +1 -0
  102. package/dist/src/app-launch.js +2 -0
  103. package/dist/src/app-lifecycle-facade.js +1 -0
  104. package/dist/src/app-lifecycle.js +3 -6
  105. package/dist/src/app-lifecycle2.js +2 -2
  106. package/dist/src/app-lifecycle3.js +1 -0
  107. package/dist/src/app-log-files.js +1 -1
  108. package/dist/src/app-log-reconnect.js +1 -1
  109. package/dist/src/app-log-runtime.js +1 -4
  110. package/dist/src/app-log-runtime2.js +4 -0
  111. package/dist/src/app-parsers.js +4 -0
  112. package/dist/src/app-resolution-cache.js +1 -0
  113. package/dist/src/app-resolution-facade.js +1 -0
  114. package/dist/src/app-resolution.js +2 -2
  115. package/dist/src/app-state.js +1 -2
  116. package/dist/src/apple-runner-platform.js +1 -0
  117. package/dist/src/application-lifecycle-interaction.js +1 -0
  118. package/dist/src/application-lifecycle-runtime.js +1 -0
  119. package/dist/src/apps-simctl.js +1 -0
  120. package/dist/src/archive.js +4 -0
  121. package/dist/src/artifact-download.js +1 -0
  122. package/dist/src/artifacts.d.ts +6 -2
  123. package/dist/src/artifacts.js +1 -1
  124. package/dist/src/async-lifecycle.js +1 -0
  125. package/dist/src/audio-probe-result.js +1 -0
  126. package/dist/src/audio-probe-runtime.js +1 -0
  127. package/dist/src/audio-probe-support.js +1 -0
  128. package/dist/src/auth-session.js +1 -1
  129. package/dist/src/auth.js +1 -1
  130. package/dist/src/backend-snapshot-options.js +1 -1
  131. package/dist/src/{url.js → base-url.js} +1 -1
  132. package/dist/src/boot-diagnostics.js +2 -2
  133. package/dist/src/byte-limit-stream.js +1 -1
  134. package/dist/src/capabilities.js +1 -0
  135. package/dist/src/capture.js +1 -0
  136. package/dist/src/catalog.js +1 -0
  137. package/dist/src/cli-command-aliases.js +1 -0
  138. package/dist/src/cli-config.js +1 -1
  139. package/dist/src/cli-help.js +74 -51
  140. package/dist/src/cli-output.js +1 -1
  141. package/dist/src/cli-runner.js +1 -1
  142. package/dist/src/cli.js +4 -6
  143. package/dist/src/click-button.js +1 -0
  144. package/dist/src/client-metro-companion.js +1 -0
  145. package/dist/src/client-metro.js +1 -1
  146. package/dist/src/client-types.d.ts +280 -242
  147. package/dist/src/clipboard.js +1 -0
  148. package/dist/src/code-signature-cache.js +1 -0
  149. package/dist/src/code-signature.js +1 -0
  150. package/dist/src/color.js +1 -0
  151. package/dist/src/command-metadata.js +1 -1
  152. package/dist/src/command-schema.js +3 -3
  153. package/dist/src/command-surface.js +1 -1
  154. package/dist/src/command-tools.js +2 -2
  155. package/dist/src/command.js +1 -0
  156. package/dist/src/compatibility-policy.js +1 -0
  157. package/dist/src/config.js +1 -1
  158. package/dist/src/config2.js +1 -0
  159. package/dist/src/connection-runtime.js +1 -1
  160. package/dist/src/connection.js +5 -5
  161. package/dist/src/contracts.d.ts +1 -1
  162. package/dist/src/contracts.js +1 -1
  163. package/dist/src/daemon-client-lifecycle.js +1 -0
  164. package/dist/src/daemon-process.js +1 -0
  165. package/dist/src/daemon-registration.js +1 -0
  166. package/dist/src/daemon-shutdown-report.js +1 -1
  167. package/dist/src/daemon.js +2 -2
  168. package/dist/src/debug-symbols-facade.js +5 -0
  169. package/dist/src/deploy-result-target.js +1 -0
  170. package/dist/src/device-claim-inspection.js +1 -1
  171. package/dist/src/device-claim-rule.js +1 -0
  172. package/dist/src/device-input-state.d.ts +190 -3
  173. package/dist/src/device-inventory-context.js +1 -0
  174. package/dist/src/device-isolation.js +1 -0
  175. package/dist/src/device-release.js +1 -0
  176. package/dist/src/device-rotation.js +1 -0
  177. package/dist/src/device-selection-resolver.js +1 -0
  178. package/dist/src/device-session.js +1 -0
  179. package/dist/src/device.js +1 -1
  180. package/dist/src/device2.js +3 -2
  181. package/dist/src/diagnostics.js +3 -0
  182. package/dist/src/diagnostics2.js +1 -0
  183. package/dist/src/dispatch-resolve.js +1 -0
  184. package/dist/src/doctor-facade.js +1 -0
  185. package/dist/src/doctor-output.js +1 -0
  186. package/dist/src/doctor.js +1 -0
  187. package/dist/src/doctor2.js +1 -0
  188. package/dist/src/doctor3.js +1 -0
  189. package/dist/src/durable-resource.js +1 -0
  190. package/dist/src/entities.js +1 -1
  191. package/dist/src/error.js +2 -0
  192. package/dist/src/exec.js +1 -0
  193. package/dist/src/file.js +1 -0
  194. package/dist/src/find.js +1 -1
  195. package/dist/src/finders.js +1 -1
  196. package/dist/src/generic-settle.js +1 -1
  197. package/dist/src/generic.js +1 -1
  198. package/dist/src/gesture-admission.js +1 -0
  199. package/dist/src/gesture-plan-types.js +1 -0
  200. package/dist/src/gesture-plan.js +1 -0
  201. package/dist/src/gesture-runtime.js +1 -0
  202. package/dist/src/harmonyos.js +1 -1
  203. package/dist/src/hdc.js +1 -1
  204. package/dist/src/helper.js +2 -2
  205. package/dist/src/host-file.js +1 -0
  206. package/dist/src/human-control-contract.js +1 -0
  207. package/dist/src/human-control.js +1 -0
  208. package/dist/src/index.d.ts +1 -1
  209. package/dist/src/index.js +1 -1
  210. package/dist/src/input-actions.js +1 -4
  211. package/dist/src/input-actions2.js +2 -1
  212. package/dist/src/install-artifact-facade.js +1 -0
  213. package/dist/src/install-source-network-transport.js +1 -0
  214. package/dist/src/install-source.d.ts +3 -10
  215. package/dist/src/install-source2.js +1 -1
  216. package/dist/src/interaction-positionals.js +1 -0
  217. package/dist/src/interaction-ref-policy.js +1 -0
  218. package/dist/src/interaction.js +1 -1
  219. package/dist/src/interaction2.js +1 -1
  220. package/dist/src/interactor-operation-catalog.js +1 -0
  221. package/dist/src/interactor-types.js +1 -0
  222. package/dist/src/interactor.js +6 -2
  223. package/dist/src/interactor2.js +1 -1
  224. package/dist/src/interactors.js +1 -1
  225. package/dist/src/internal/bin.d.ts +1 -1
  226. package/dist/src/internal/bin.js +1 -2
  227. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  228. package/dist/src/internal/companion-tunnel.js +1 -1
  229. package/dist/src/internal/daemon.d.ts +1 -1
  230. package/dist/src/internal/daemon.js +2 -4
  231. package/dist/src/internal/png-worker.d.ts +4 -4
  232. package/dist/src/internal/png-worker.js +1 -1
  233. package/dist/src/internal/run-script-http-child.d.ts +4 -0
  234. package/dist/src/internal/run-script-http-child.js +1 -0
  235. package/dist/src/internal/update-check-entry.d.ts +1 -1
  236. package/dist/src/inventory.js +4 -4
  237. package/dist/src/inventory2.js +1 -1
  238. package/dist/src/inventory3.js +1 -1
  239. package/dist/src/inventory5.js +1 -1
  240. package/dist/src/inventory6.js +1 -1
  241. package/dist/src/ios-client.js +16 -0
  242. package/dist/src/ios-snapshot-acquisition.js +1 -0
  243. package/dist/src/ios-snapshot-adapter.js +1 -0
  244. package/dist/src/ios-snapshot-planning.js +1 -0
  245. package/dist/src/ios-snapshot-runtime.js +1 -0
  246. package/dist/src/ios-system-surface.js +1 -0
  247. package/dist/src/json.js +1 -0
  248. package/dist/src/keyboard-actions.js +1 -0
  249. package/dist/src/launch-console.js +1 -0
  250. package/dist/src/lease-context.js +1 -1
  251. package/dist/src/lease-scope.js +1 -0
  252. package/dist/src/lease.js +1 -1
  253. package/dist/src/limrun-runtime-dependencies.js +1 -1
  254. package/dist/src/limrun.d.ts +1610 -7
  255. package/dist/src/limrun.js +1 -1
  256. package/dist/src/linux.js +1 -1
  257. package/dist/src/local-interactor-operation-set.js +1 -0
  258. package/dist/src/location-coordinates.js +1 -1
  259. package/dist/src/logcat.js +1 -1
  260. package/dist/src/macos-facade.js +1 -0
  261. package/dist/src/managed-device-scope.js +1 -0
  262. package/dist/src/mechanics.js +19 -0
  263. package/dist/src/metro.d.ts +4 -2
  264. package/dist/src/metro.js +1 -1
  265. package/dist/src/metro2.js +1 -1
  266. package/dist/src/mobile-snapshot-semantics.js +1 -1
  267. package/dist/src/multitouch-support.js +1 -0
  268. package/dist/src/numeric.js +1 -0
  269. package/dist/src/observability.js +1 -1
  270. package/dist/src/observation.js +2 -0
  271. package/dist/src/open-target-resolution.js +1 -0
  272. package/dist/src/output-path.js +1 -1
  273. package/dist/src/owner-identity.js +3 -1
  274. package/dist/src/parameterized-recorded-fill.js +1 -0
  275. package/dist/src/parser.js +1 -1
  276. package/dist/src/perf-facade.js +2 -0
  277. package/dist/src/perf-process-identity.js +1 -0
  278. package/dist/src/perf-runtime-operation-builder.js +1 -0
  279. package/dist/src/perf-runtime-plan.js +1 -0
  280. package/dist/src/perf-runtime.js +1 -0
  281. package/dist/src/perf.js +1 -4
  282. package/dist/src/physical-device-control.js +1 -1
  283. package/dist/src/physical-device-facade.js +1 -0
  284. package/dist/src/platform-request-scope.js +1 -0
  285. package/dist/src/platform-runtime-android-adb-host.js +1 -0
  286. package/dist/src/platform-runtime-android-mechanics.js +1 -0
  287. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  288. package/dist/src/platform-runtime-app-log-process.js +1 -1
  289. package/dist/src/platform-runtime-host.js +1 -1
  290. package/dist/src/platform-runtime-managed-owner.js +1 -0
  291. package/dist/src/platform-runtime-network-web-transport.js +1 -1
  292. package/dist/src/platform-runtime-open-target.js +1 -1
  293. package/dist/src/platform-runtime-operation-host.js +4 -4
  294. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  295. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  296. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
  297. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
  298. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  299. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
  300. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  301. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  302. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
  303. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
  304. package/dist/src/platform-runtime-unavailable.js +1 -0
  305. package/dist/src/platform-runtime.js +1 -1
  306. package/dist/src/platform-runtime2.js +1 -1
  307. package/dist/src/plist.js +1 -1
  308. package/dist/src/png-worker-contract.js +1 -1
  309. package/dist/src/prepare-kind.js +1 -0
  310. package/dist/src/process-exit.js +1 -1
  311. package/dist/src/process.js +1 -0
  312. package/dist/src/provider-device-runtime.js +1 -0
  313. package/dist/src/provider-session-ownership.js +2 -0
  314. package/dist/src/provider-webdriver.js +1 -1
  315. package/dist/src/provider.js +1 -1
  316. package/dist/src/providers.js +1 -0
  317. package/dist/src/proxy.js +2 -2
  318. package/dist/src/react-native-overlay.js +1 -0
  319. package/dist/src/react-native.js +1 -1
  320. package/dist/src/record-runtime.js +1 -1
  321. package/dist/src/record-trace.js +1 -1
  322. package/dist/src/rect-center.js +1 -0
  323. package/dist/src/register-builtins.js +1 -0
  324. package/dist/src/registry.js +40 -28
  325. package/dist/src/remote-config2.js +1 -1
  326. package/dist/src/replay-divergence.js +2 -0
  327. package/dist/src/replay.js +2 -2
  328. package/dist/src/reporting.js +8 -7
  329. package/dist/src/request-admission.js +1 -0
  330. package/dist/src/request-cancel.js +1 -0
  331. package/dist/src/request-cancellation.js +1 -0
  332. package/dist/src/request-progress-protocol.js +1 -0
  333. package/dist/src/request-providers.js +1 -0
  334. package/dist/src/request-runtime-binding.js +1 -0
  335. package/dist/src/request.js +1 -0
  336. package/dist/src/result-serialization.js +1 -0
  337. package/dist/src/retry.js +1 -0
  338. package/dist/src/rolldown-runtime.js +1 -1
  339. package/dist/src/runner-cache-metadata.js +2 -0
  340. package/dist/src/runner-client.js +1 -1
  341. package/dist/src/runner-disposal.js +1 -1
  342. package/dist/src/runner-operations-facade.js +1 -0
  343. package/dist/src/runner-owner-facade.js +1 -0
  344. package/dist/src/runner-owner-state.js +1 -0
  345. package/dist/src/runner-presentation.js +1 -0
  346. package/dist/src/runner.js +1 -0
  347. package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
  348. package/dist/src/runtime.js +3 -3
  349. package/dist/src/runtime2.js +4 -4
  350. package/dist/src/runtime3.js +1 -1
  351. package/dist/src/runtime4.js +5 -3
  352. package/dist/src/runtime5.js +1 -1
  353. package/dist/src/runtime6.js +1 -1
  354. package/dist/src/runtime7.js +1 -1
  355. package/dist/src/runtime8.js +1 -1
  356. package/dist/src/runtime9.js +1 -1
  357. package/dist/src/scoped-provider.js +1 -1
  358. package/dist/src/screen-recording-completion.js +1 -0
  359. package/dist/src/screen-recording-live-handle.js +1 -0
  360. package/dist/src/screen-recording-options.js +1 -0
  361. package/dist/src/screen-recording-resource-recovery.js +1 -0
  362. package/dist/src/screen-recording-runtime.js +1 -0
  363. package/dist/src/screenshot-density.js +1 -1
  364. package/dist/src/screenshot-result.js +1 -6
  365. package/dist/src/screenshot-runtime.js +1 -0
  366. package/dist/src/screenshot.js +1 -1
  367. package/dist/src/screenshot2.js +1 -0
  368. package/dist/src/screenshot3.js +5 -0
  369. package/dist/src/script.js +1 -0
  370. package/dist/src/scroll-command.js +1 -0
  371. package/dist/src/scroll-gesture.js +1 -0
  372. package/dist/src/scroll-indicator.js +1 -0
  373. package/dist/src/sdk-batch-runner.d.ts +23 -6
  374. package/dist/src/sdk-batch-runner.js +2 -3
  375. package/dist/src/sdk-batch.js +2 -0
  376. package/dist/src/sdk-contracts.d.ts +170 -41
  377. package/dist/src/sdk-contracts.js +2 -2
  378. package/dist/src/sdk-device.js +1 -1
  379. package/dist/src/sdk-finders.d.ts +1 -1
  380. package/dist/src/sdk-finders.js +1 -1
  381. package/dist/src/sdk-io.js +1 -1
  382. package/dist/src/sdk-remote-config.d.ts +1 -1
  383. package/dist/src/sdk-remote-config.js +1 -1
  384. package/dist/src/sdk-selectors.d.ts +524 -140
  385. package/dist/src/sdk-selectors.js +1 -1
  386. package/dist/src/selection.js +1 -0
  387. package/dist/src/selector-runtime.js +1 -1
  388. package/dist/src/selectors.js +1 -1
  389. package/dist/src/semantic-index.js +1 -0
  390. package/dist/src/server.js +4 -4
  391. package/dist/src/session-allocation.js +1 -0
  392. package/dist/src/session-artifact-paths.js +1 -0
  393. package/dist/src/session-observation.js +1 -0
  394. package/dist/src/session-paths.js +1 -0
  395. package/dist/src/session-repair-tombstone.js +1 -0
  396. package/dist/src/session-routing.js +1 -0
  397. package/dist/src/session-runtime-admission.js +1 -0
  398. package/dist/src/session-snapshot.js +1 -0
  399. package/dist/src/session-store.js +4 -0
  400. package/dist/src/session-target-evidence.js +1 -1
  401. package/dist/src/session2.js +5 -27
  402. package/dist/src/settings.js +1 -0
  403. package/dist/src/shared.js +2 -2
  404. package/dist/src/simctl-facade.js +1 -0
  405. package/dist/src/simctl.js +1 -1
  406. package/dist/src/simulator-facade.js +1 -0
  407. package/dist/src/simulator.js +1 -1
  408. package/dist/src/snapshot-capture-annotations.js +1 -0
  409. package/dist/src/snapshot-desktop-projection.js +1 -0
  410. package/dist/src/snapshot-diagnostics.js +1 -0
  411. package/dist/src/snapshot-process.js +1 -0
  412. package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
  413. package/dist/src/snapshot-quality-verdict.js +1 -0
  414. package/dist/src/snapshot-runtime-binding.js +1 -0
  415. package/dist/src/snapshot-runtime.js +1 -1
  416. package/dist/src/snapshot-scope.js +1 -1
  417. package/dist/src/snapshot-state.js +1 -0
  418. package/dist/src/snapshot.js +1 -8
  419. package/dist/src/snapshot2.js +1 -1
  420. package/dist/src/snapshot3.js +1 -1
  421. package/dist/src/snapshot4.js +1 -0
  422. package/dist/src/src.js +1 -1
  423. package/dist/src/src2.js +1 -1
  424. package/dist/src/src3.js +1 -2
  425. package/dist/src/src4.js +1 -1
  426. package/dist/src/src5.js +1 -0
  427. package/dist/src/src6.js +1 -0
  428. package/dist/src/src7.js +2 -0
  429. package/dist/src/src8.js +115 -0
  430. package/dist/src/startup-recovery-fence.js +1 -0
  431. package/dist/src/status-markers.js +1 -0
  432. package/dist/src/string-enum.js +1 -1
  433. package/dist/src/success-text.js +1 -0
  434. package/dist/src/surface-snapshot.js +1 -0
  435. package/dist/src/surface-snapshot2.js +1 -0
  436. package/dist/src/takeover.js +5 -0
  437. package/dist/src/tool-provider-facade.js +1 -0
  438. package/dist/src/tool-provider.js +4 -3
  439. package/dist/src/tool-provider2.js +1 -1
  440. package/dist/src/tool-provider3.js +1 -1
  441. package/dist/src/toolchain-probe.js +2 -0
  442. package/dist/src/touch-reference-frame.js +1 -0
  443. package/dist/src/touch-runtime.js +1 -0
  444. package/dist/src/transport.js +3 -0
  445. package/dist/src/tree.js +1 -0
  446. package/dist/src/ttl-memo.js +1 -0
  447. package/dist/src/tv-remote.js +1 -0
  448. package/dist/src/type-text-runtime.js +1 -0
  449. package/dist/src/undici.js +99 -0
  450. package/dist/src/update-check.js +1 -1
  451. package/dist/src/verified-file.js +1 -1
  452. package/dist/src/version.js +1 -1
  453. package/dist/src/video.js +2 -2
  454. package/dist/src/web.js +2 -1
  455. package/dist/src/web2.js +1 -0
  456. package/dist/src/webdriver-ios-snapshot.js +1 -0
  457. package/dist/src/webdriver-source.js +1 -0
  458. package/dist/src/window-state.js +1 -0
  459. package/linux/atspi-dump.py +54 -9
  460. package/package.json +58 -35
  461. package/server.json +9 -3
  462. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +0 -1
  463. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk +0 -0
  464. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +0 -1
  465. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
  466. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -168
  467. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
  468. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
  469. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
  470. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +0 -183
  471. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  472. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
  473. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
  474. package/dist/src/appearance.js +0 -1
  475. package/dist/src/apps.js +0 -5
  476. package/dist/src/audio-probe.js +0 -1
  477. package/dist/src/cli-grammar.js +0 -1
  478. package/dist/src/command-catalog.js +0 -1
  479. package/dist/src/debug-symbols.js +0 -5
  480. package/dist/src/device-input-state.js +0 -2
  481. package/dist/src/device-ready.js +0 -1
  482. package/dist/src/dispatch.js +0 -1
  483. package/dist/src/handler-utils.js +0 -1
  484. package/dist/src/helper-package-install.js +0 -1
  485. package/dist/src/host-process.js +0 -3
  486. package/dist/src/ime-lifecycle.js +0 -2
  487. package/dist/src/ime-recovery-marker.js +0 -1
  488. package/dist/src/input-actions3.js +0 -1
  489. package/dist/src/install-artifact.js +0 -1
  490. package/dist/src/install-artifact2.js +0 -1
  491. package/dist/src/interaction-common.js +0 -1
  492. package/dist/src/interaction-runtime.js +0 -1
  493. package/dist/src/interaction-snapshot.js +0 -1
  494. package/dist/src/manifest.js +0 -1
  495. package/dist/src/method-scope.js +0 -1
  496. package/dist/src/png-resize.js +0 -1
  497. package/dist/src/process-lock.js +0 -1
  498. package/dist/src/runner-lease.js +0 -1
  499. package/dist/src/runner-sequence.js +0 -1
  500. package/dist/src/script-source-bundle.js +0 -16
  501. package/dist/src/sdk-android-adb.d.ts +0 -245
  502. package/dist/src/sdk-android-adb.js +0 -4
  503. package/dist/src/sdk.js +0 -1
  504. package/dist/src/setting-state.js +0 -1
  505. package/dist/src/shell-quote.js +0 -1
  506. package/dist/src/snapshot-session.js +0 -1
  507. package/dist/src/timing-safe-equal.js +0 -1
  508. package/dist/src/unsupported-interactor.js +0 -1
  509. package/dist/src/verdict.js +0 -1
  510. /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
@@ -0,0 +1,138 @@
1
+ #import "SnapshotBridgeCapture.h"
2
+
3
+ static NSString *const attributesKey = @"UIAccessibilitySnapshotKeyAttributes";
4
+ static NSString *const childrenKey = @"UIAccessibilitySnapshotKeyChildren";
5
+ static NSString *const childCountKey = @"UIAccessibilitySnapshotKeyChildrenCount";
6
+ static NSString *const elementKey = @"UIAccessibilitySnapshotKeyElement";
7
+ static const NSUInteger maximumRequests = 32;
8
+
9
+ @interface SnapshotTreeCapture : NSObject
10
+ @property(nonatomic, copy) SnapshotElementReader reader;
11
+ @property(nonatomic) NSUInteger acceptedDepth;
12
+ @property(nonatomic) NSUInteger remainingNodes;
13
+ @property(nonatomic) NSUInteger maximumNodes;
14
+ @property(nonatomic) NSUInteger requests;
15
+ @property(nonatomic) NSUInteger rejected;
16
+ @property(nonatomic) BOOL truncated;
17
+ - (nullable NSDictionary *)read:(id)element depth:(NSUInteger)depth error:(NSError **)error;
18
+ - (nullable NSDictionary *)materialize:(NSDictionary *)tree depth:(NSUInteger)depth nativeLevels:(NSUInteger)nativeLevels error:(NSError **)error;
19
+ @end
20
+
21
+ @implementation SnapshotTreeCapture
22
+ - (nullable NSDictionary *)read:(id)element depth:(NSUInteger)depth error:(NSError **)error
23
+ {
24
+ NSUInteger attemptDepth = MIN(depth, self.acceptedDepth);
25
+ for (NSUInteger retries = 0;; retries++) {
26
+ if (self.requests >= maximumRequests) {
27
+ if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:1
28
+ userInfo:@{NSLocalizedDescriptionKey: @"snapshot continuation request budget exhausted"}];
29
+ return nil;
30
+ }
31
+ self.requests++;
32
+ NSError *failure = nil;
33
+ id tree = self.reader(element, attemptDepth, MIN(self.maximumNodes, self.remainingNodes + 1), &failure);
34
+ if (tree) return tree;
35
+ NSNumber *nativeCode = failure.userInfo[@"accessibility-error"];
36
+ BOOL rejected = ([nativeCode isKindOfClass:NSNumber.class] && nativeCode.integerValue == -25201) ||
37
+ ([failure.domain isEqualToString:@"com.apple.dt.xctest.automation-support.error"] && failure.code == 5);
38
+ if (rejected) self.rejected++;
39
+ if (!rejected || attemptDepth <= 1 || retries >= 2) {
40
+ if (error) *error = failure;
41
+ return nil;
42
+ }
43
+ attemptDepth = MAX(1, attemptDepth / 2);
44
+ self.acceptedDepth = attemptDepth;
45
+ }
46
+ }
47
+
48
+ - (nullable NSDictionary *)materialize:(NSDictionary *)tree depth:(NSUInteger)depth nativeLevels:(NSUInteger)nativeLevels error:(NSError **)error
49
+ {
50
+ if (![tree isKindOfClass:NSDictionary.class] ||
51
+ ![tree[attributesKey] isKindOfClass:NSDictionary.class] ||
52
+ ![tree[childrenKey] isKindOfClass:NSArray.class]) {
53
+ if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:2
54
+ userInfo:@{NSLocalizedDescriptionKey: @"malformed snapshot continuation"}];
55
+ return nil;
56
+ }
57
+ if (self.remainingNodes == 0) {
58
+ self.truncated = YES;
59
+ return nil;
60
+ }
61
+ self.remainingNodes--;
62
+ NSArray *children = tree[childrenKey];
63
+ NSNumber *childCount = tree[childCountKey];
64
+ BOOL knownChildCount = [childCount isKindOfClass:NSNumber.class] && childCount.doubleValue >= 0 &&
65
+ childCount.doubleValue == (double)childCount.unsignedIntegerValue;
66
+ if (nativeLevels <= 1 && !knownChildCount && depth <= 1) self.truncated = YES;
67
+ if (depth > 1 && nativeLevels <= 1 && !knownChildCount) {
68
+ if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:6
69
+ userInfo:@{NSLocalizedDescriptionKey: @"snapshot boundary child count unavailable"}];
70
+ return nil;
71
+ }
72
+ BOOL withheld = knownChildCount && childCount.unsignedIntegerValue > children.count;
73
+ if (depth <= 1 || self.remainingNodes == 0) {
74
+ self.truncated |= children.count > 0 || withheld;
75
+ if (children.count == 0) return tree;
76
+ NSMutableDictionary *bounded = [tree mutableCopy];
77
+ bounded[childrenKey] = @[];
78
+ return bounded;
79
+ }
80
+ if (withheld && children.count < self.remainingNodes) {
81
+ id element = tree[elementKey];
82
+ if (!element) {
83
+ if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:3
84
+ userInfo:@{NSLocalizedDescriptionKey: @"snapshot continuation element unavailable"}];
85
+ return nil;
86
+ }
87
+ NSDictionary *continuation = [self read:element depth:depth error:error];
88
+ if (!continuation) return nil;
89
+ nativeLevels = MIN(depth, self.acceptedDepth);
90
+ children = continuation[childrenKey];
91
+ if (![children isKindOfClass:NSArray.class] || children.count < MIN(childCount.unsignedIntegerValue, self.remainingNodes)) {
92
+ if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:4
93
+ userInfo:@{NSLocalizedDescriptionKey: @"snapshot continuation children unavailable"}];
94
+ return nil;
95
+ }
96
+ }
97
+ if (withheld && children.count < childCount.unsignedIntegerValue) self.truncated = YES;
98
+ NSMutableArray *materialized = nil;
99
+ NSUInteger index = 0;
100
+ for (NSDictionary *child in children) {
101
+ if (self.remainingNodes == 0) {
102
+ self.truncated = YES;
103
+ if (!materialized) materialized = [[children subarrayWithRange:NSMakeRange(0, index)] mutableCopy];
104
+ break;
105
+ }
106
+ NSDictionary *node = [self materialize:child depth:depth - 1 nativeLevels:(nativeLevels > 0 ? nativeLevels - 1 : 0) error:error];
107
+ if (!node) return nil;
108
+ if (node != child && !materialized) materialized = [[children subarrayWithRange:NSMakeRange(0, index)] mutableCopy];
109
+ [materialized addObject:node];
110
+ index++;
111
+ }
112
+ if (!materialized && children == tree[childrenKey]) return tree;
113
+ NSMutableDictionary *result = [tree mutableCopy];
114
+ result[childrenKey] = materialized ?: children;
115
+ return result;
116
+ }
117
+ @end
118
+
119
+ NSDictionary *captureSnapshotTree(id element, NSUInteger maxDepth, NSUInteger maxNodes,
120
+ NSUInteger nativeLevelsHint, SnapshotElementReader reader,
121
+ BOOL *truncated, SnapshotCaptureRecovery *recovery, NSError **error)
122
+ {
123
+ SnapshotTreeCapture *capture = [SnapshotTreeCapture new];
124
+ capture.reader = reader;
125
+ capture.acceptedDepth = nativeLevelsHint > 0 ? MIN(maxDepth + 1, nativeLevelsHint) : maxDepth + 1;
126
+ capture.remainingNodes = maxNodes;
127
+ capture.maximumNodes = maxNodes;
128
+ NSDictionary *tree = [capture read:element depth:maxDepth + 1 error:error];
129
+ NSDictionary *result = tree ? [capture materialize:tree depth:maxDepth + 1 nativeLevels:capture.acceptedDepth error:error] : nil;
130
+ *truncated = capture.truncated;
131
+ if (recovery) {
132
+ recovery->requests = capture.requests;
133
+ recovery->rejected = capture.rejected;
134
+ recovery->continuations = capture.requests - capture.rejected - (tree ? 1 : 0);
135
+ recovery->acceptedLevels = tree ? capture.acceptedDepth : 0;
136
+ }
137
+ return result;
138
+ }
@@ -0,0 +1,34 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ extern NSString *const kProtocolVersionKey;
6
+ extern NSString *const kSourceVersionKey;
7
+ extern NSString *const kRequestIdKey;
8
+ extern NSString *const kSourceVersion;
9
+ extern const NSUInteger kProtocolVersion;
10
+ extern const uint32_t kMaximumFrameBytes;
11
+ extern const NSUInteger kMaximumDepth;
12
+ extern const NSUInteger kMaximumNodes;
13
+ extern const NSUInteger kMaximumDurationMs;
14
+
15
+ NSDictionary *failureResponse(NSString *requestId,
16
+ NSString *kind,
17
+ NSString *code,
18
+ NSString *message);
19
+
20
+ @interface BridgeRuntime : NSObject
21
+ - (nullable instancetype)initWithError:(NSString *_Nullable *_Nullable)error;
22
+ - (nullable NSDictionary *)snapshotForProcess:(pid_t)pid
23
+ maxDepth:(NSUInteger)maxDepth
24
+ maxNodes:(NSUInteger)maxNodes
25
+ nativeLevelsHint:(NSUInteger)nativeLevelsHint
26
+ requestId:(NSString *)requestId
27
+ generation:(NSString *)generation
28
+ maxDurationMs:(NSUInteger)maxDurationMs
29
+ error:(NSDictionary *_Nullable *_Nonnull)error;
30
+ @end
31
+
32
+ BridgeRuntime *_Nullable sharedRuntime(NSString *_Nullable *_Nullable error);
33
+
34
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,411 @@
1
+ /*
2
+ * The private Simulator AX reader is adapted from Meta Platforms, Inc. idb v1.5.2
3
+ * SimulatorFrameworkBridge/AccessibilityService.m and AccessibilityRuntime.m.
4
+ * See LICENSE.idb for the upstream notice and license.
5
+ */
6
+
7
+ #import "SnapshotBridgeRuntime.h"
8
+ #import "SnapshotBridgeCapture.h"
9
+
10
+ #import <CoreGraphics/CoreGraphics.h>
11
+ #import <objc/message.h>
12
+ #import <objc/runtime.h>
13
+
14
+ #import <dlfcn.h>
15
+ #import <signal.h>
16
+ #import <unistd.h>
17
+
18
+ NSString *const kProtocolVersionKey = @"protocolVersion";
19
+ NSString *const kSourceVersionKey = @"sourceVersion";
20
+ NSString *const kRequestIdKey = @"requestId";
21
+ NSString *const kSourceVersion = @"agent-device-simulator-ax-v1.5.5";
22
+ const NSUInteger kProtocolVersion = 1;
23
+ const uint32_t kMaximumFrameBytes = 16 * 1024 * 1024;
24
+ const NSUInteger kMaximumDepth = 128;
25
+ const NSUInteger kMaximumNodes = 10000;
26
+ const NSUInteger kMaximumDurationMs = 120000;
27
+
28
+ static NSString *const kAttributeElementType = @"XC_kAXXCAttributeElementType";
29
+ static NSString *const kAttributeElementBaseType = @"XC_kAXXCAttributeElementBaseType";
30
+ static NSString *const kAttributeLabel = @"XC_kAXXCAttributeLabel";
31
+ static NSString *const kAttributeValue = @"XC_kAXXCAttributeValue";
32
+ static NSString *const kAttributeIdentifier = @"XC_kAXXCAttributeIdentifier";
33
+ static NSString *const kAttributeFrame = @"XC_kAXXCAttributeFrame";
34
+ static NSString *const kAttributeAutomationType = @"XC_kAXXCAttributeAutomationType";
35
+ static NSString *const kAttributeChildren = @"XC_kAXXCAttributeChildren";
36
+ static NSString *const kSnapshotAttributes = @"UIAccessibilitySnapshotKeyAttributes";
37
+ static NSString *const kSnapshotChildren = @"UIAccessibilitySnapshotKeyChildren";
38
+ static NSString *const kXctAutomationSupportPath =
39
+ @"/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework/XCTAutomationSupport";
40
+ static NSString *const kAxRuntimePath =
41
+ @"/System/Library/PrivateFrameworks/AXRuntime.framework/AXRuntime";
42
+ static NSString *const kAccessibilityErrorKey = @"accessibility-error";
43
+
44
+ typedef NSDictionary<NSString *, id> *_Nullable (*DefaultSnapshotParametersFn)(void);
45
+ typedef NSArray<NSNumber *> *_Nullable (*AttributeNumbersForNamesFn)(NSArray<NSString *> *names);
46
+ typedef uint32_t (*AXValueGetTypeFn)(const void *value);
47
+ typedef Boolean (*AXValueGetValueFn)(const void *value, uint32_t type, void *out);
48
+ typedef bool (*AutomationEnabledFn)(void);
49
+
50
+ @interface XCTAccessibilityFramework : NSObject
51
+ - (instancetype)initForRemoteAccess;
52
+ - (nullable id)userTestingSnapshotForElement:(id)element
53
+ options:(NSDictionary<NSString *, id> *)options
54
+ error:(NSError **)error;
55
+ @end
56
+
57
+ @interface XCAccessibilityElement : NSObject
58
+ - (nullable void *)AXUIElement;
59
+ @end
60
+
61
+ @protocol XCAccessibilityElementFactory <NSObject>
62
+ + (nullable XCAccessibilityElement *)elementWithProcessIdentifier:(pid_t)pid;
63
+ @end
64
+
65
+ @protocol AXForegroundElement <NSObject>
66
+ + (nullable id<AXForegroundElement>)primaryApp;
67
+ - (pid_t)pid;
68
+ @end
69
+
70
+ static NSNumber *finiteNumber(double value)
71
+ {
72
+ return isfinite(value) ? @(value) : nil;
73
+ }
74
+
75
+ static NSDictionary *_Nullable rectDictionary(CGRect rect)
76
+ {
77
+ NSNumber *x = finiteNumber(rect.origin.x);
78
+ NSNumber *y = finiteNumber(rect.origin.y);
79
+ NSNumber *width = finiteNumber(rect.size.width);
80
+ NSNumber *height = finiteNumber(rect.size.height);
81
+ if (!x || !y || !width || !height) {
82
+ return nil;
83
+ }
84
+ return @{ @"X" : x, @"Y" : y, @"Width" : width, @"Height" : height };
85
+ }
86
+
87
+ @interface SnapshotWatchdogState : NSObject
88
+ @property(atomic) BOOL completed;
89
+ @end
90
+
91
+ @implementation SnapshotWatchdogState
92
+ @end
93
+
94
+ static dispatch_source_t startRequestWatchdog(NSUInteger durationMs, SnapshotWatchdogState *state)
95
+ {
96
+ dispatch_source_t watchdog = dispatch_source_create(
97
+ DISPATCH_SOURCE_TYPE_TIMER,
98
+ 0,
99
+ 0,
100
+ dispatch_get_global_queue(QOS_CLASS_UTILITY, 0));
101
+ dispatch_source_set_timer(
102
+ watchdog,
103
+ dispatch_time(DISPATCH_TIME_NOW, (uint64_t)durationMs * NSEC_PER_MSEC),
104
+ DISPATCH_TIME_FOREVER,
105
+ 0);
106
+ dispatch_source_set_event_handler(watchdog, ^{
107
+ if (!state.completed) kill(getpid(), SIGKILL);
108
+ });
109
+ dispatch_resume(watchdog);
110
+ return watchdog;
111
+ }
112
+
113
+ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogState *state)
114
+ {
115
+ state.completed = YES;
116
+ dispatch_source_cancel(watchdog);
117
+ }
118
+
119
+ @implementation BridgeRuntime {
120
+ XCTAccessibilityFramework *_framework;
121
+ Class<XCAccessibilityElementFactory> _elementClass;
122
+ DefaultSnapshotParametersFn _defaultSnapshotParameters;
123
+ AttributeNumbersForNamesFn _attributeNumbersForNames;
124
+ AXValueGetTypeFn _valueGetType;
125
+ AXValueGetValueFn _valueGetValue;
126
+ AutomationEnabledFn _automationEnabled;
127
+ }
128
+
129
+ - (nullable instancetype)initWithError:(NSString *_Nullable *_Nullable)error
130
+ {
131
+ self = [super init];
132
+ if (!self) return nil;
133
+
134
+ dlopen(kAxRuntimePath.UTF8String, RTLD_NOW);
135
+ dlopen(kXctAutomationSupportPath.UTF8String, RTLD_NOW);
136
+
137
+ Class frameworkClass = objc_lookUpClass("XCTAccessibilityFramework");
138
+ _elementClass = (Class<XCAccessibilityElementFactory>)objc_lookUpClass("XCAccessibilityElement");
139
+ if (!frameworkClass || !_elementClass) {
140
+ if (error) *error = @"XCTAutomationSupport accessibility classes are unavailable";
141
+ return nil;
142
+ }
143
+
144
+ _framework = [(XCTAccessibilityFramework *)[frameworkClass alloc] initForRemoteAccess];
145
+ if (!_framework || ![_framework respondsToSelector:@selector(userTestingSnapshotForElement:options:error:)]) {
146
+ if (error) *error = @"XCTAccessibilityFramework snapshot API is unavailable";
147
+ return nil;
148
+ }
149
+
150
+ _defaultSnapshotParameters = (DefaultSnapshotParametersFn)dlsym(RTLD_DEFAULT, "XCTDefaultSnapshotParameters");
151
+ _attributeNumbersForNames = (AttributeNumbersForNamesFn)dlsym(
152
+ RTLD_DEFAULT, "XCAXAccessibilityAttributesForStringAttributes");
153
+ _valueGetType = (AXValueGetTypeFn)dlsym(RTLD_DEFAULT, "AXValueGetType");
154
+ _valueGetValue = (AXValueGetValueFn)dlsym(RTLD_DEFAULT, "AXValueGetValue");
155
+ _automationEnabled = (AutomationEnabledFn)dlsym(RTLD_DEFAULT, "_AXSAutomationEnabled");
156
+ if (!_defaultSnapshotParameters || !_attributeNumbersForNames || !_valueGetType || !_valueGetValue) {
157
+ if (error) *error = @"AX snapshot conversion functions are unavailable";
158
+ return nil;
159
+ }
160
+ return self;
161
+ }
162
+
163
+ - (BOOL)assertAutomationMode:(BOOL)wanted
164
+ {
165
+ Class settingsClass = NSClassFromString(@"AXSettings");
166
+ SEL sharedInstance = NSSelectorFromString(@"sharedInstance");
167
+ SEL setter = NSSelectorFromString(@"setAutomationEnabled:");
168
+ if (settingsClass && [settingsClass respondsToSelector:sharedInstance]) {
169
+ id settings = ((id (*)(id, SEL))objc_msgSend)(settingsClass, sharedInstance);
170
+ if ([settings respondsToSelector:setter]) {
171
+ ((void (*)(id, SEL, BOOL))objc_msgSend)(settings, setter, wanted);
172
+ }
173
+ }
174
+ return _automationEnabled != NULL && _automationEnabled();
175
+ }
176
+
177
+ - (BOOL)isPrimaryForegroundProcess:(pid_t)pid
178
+ {
179
+ Class<AXForegroundElement> elementClass = (Class<AXForegroundElement>)objc_lookUpClass("AXElement");
180
+ if (![elementClass respondsToSelector:@selector(primaryApp)]) return NO;
181
+ id<AXForegroundElement> application = [elementClass primaryApp];
182
+ return [application respondsToSelector:@selector(pid)] && [application pid] == pid;
183
+ }
184
+
185
+ - (nullable id)jsonValue:(id)value name:(NSString *)name
186
+ {
187
+ if (!value || value == [NSNull null]) return nil;
188
+ if ([value isKindOfClass:NSString.class] || [value isKindOfClass:NSNumber.class]) return value;
189
+
190
+ const void *raw = (__bridge const void *)value;
191
+ if (_valueGetType(raw) == 3) {
192
+ CGRect rect = CGRectZero;
193
+ if (_valueGetValue(raw, 3, &rect)) return rectDictionary(rect);
194
+ }
195
+ if ([name isEqualToString:kAttributeFrame]) return nil;
196
+ return nil;
197
+ }
198
+
199
+ - (nullable NSDictionary *)nodeFromSnapshot:(id)snapshot
200
+ namesByNumber:(NSDictionary<NSNumber *, NSString *> *)namesByNumber
201
+ depth:(NSUInteger)depth
202
+ maxDepth:(NSUInteger)maxDepth
203
+ maxNodes:(NSUInteger)maxNodes
204
+ count:(NSUInteger *)count
205
+ truncated:(BOOL *)truncated
206
+ malformed:(BOOL *)malformed
207
+ {
208
+ if (![snapshot isKindOfClass:NSDictionary.class]) {
209
+ *malformed = YES;
210
+ return nil;
211
+ }
212
+ if (*count >= maxNodes) {
213
+ *truncated = YES;
214
+ return nil;
215
+ }
216
+ (*count)++;
217
+
218
+ NSDictionary *attributes = ((NSDictionary *)snapshot)[kSnapshotAttributes];
219
+ if (![attributes isKindOfClass:NSDictionary.class]) {
220
+ *malformed = YES;
221
+ return nil;
222
+ }
223
+ NSMutableDictionary *node = [NSMutableDictionary dictionary];
224
+ for (NSNumber *number in attributes) {
225
+ NSString *name = namesByNumber[number];
226
+ if (!name || [name isEqualToString:kAttributeChildren]) continue;
227
+ id safe = [self jsonValue:attributes[number] name:name];
228
+ if (safe) node[name] = safe;
229
+ }
230
+
231
+ NSArray *children = ((NSDictionary *)snapshot)[kSnapshotChildren];
232
+ if (![children isKindOfClass:NSArray.class]) {
233
+ *malformed = YES;
234
+ return nil;
235
+ }
236
+ NSMutableArray *builtChildren = [NSMutableArray array];
237
+ if (depth >= maxDepth) {
238
+ if (children.count > 0) *truncated = YES;
239
+ } else {
240
+ for (id child in children) {
241
+ NSDictionary *built = [self nodeFromSnapshot:child
242
+ namesByNumber:namesByNumber
243
+ depth:depth + 1
244
+ maxDepth:maxDepth
245
+ maxNodes:maxNodes
246
+ count:count
247
+ truncated:truncated
248
+ malformed:malformed];
249
+ if (built) [builtChildren addObject:built];
250
+ if (*malformed) return nil;
251
+ if (*truncated) break;
252
+ if (*count >= maxNodes) {
253
+ if (builtChildren.count < children.count) *truncated = YES;
254
+ break;
255
+ }
256
+ }
257
+ }
258
+ node[kAttributeChildren] = builtChildren;
259
+ return node;
260
+ }
261
+
262
+ - (nullable NSDictionary *)snapshotForProcess:(pid_t)pid
263
+ maxDepth:(NSUInteger)maxDepth
264
+ maxNodes:(NSUInteger)maxNodes
265
+ nativeLevelsHint:(NSUInteger)nativeLevelsHint
266
+ requestId:(NSString *)requestId
267
+ generation:(NSString *)generation
268
+ maxDurationMs:(NSUInteger)maxDurationMs
269
+ error:(NSDictionary *_Nullable *_Nonnull)error
270
+ {
271
+ SnapshotWatchdogState *watchdogState = [SnapshotWatchdogState new];
272
+ dispatch_source_t watchdog = startRequestWatchdog(maxDurationMs, watchdogState);
273
+ XCAccessibilityElement *root = [_elementClass elementWithProcessIdentifier:pid];
274
+ if (!root) {
275
+ if (error) *error = failureResponse(requestId, @"application_unavailable", @"application-element-missing", @"application element is unavailable");
276
+ finishRequestWatchdog(watchdog, watchdogState);
277
+ return nil;
278
+ }
279
+ void *raw = [root AXUIElement];
280
+ if (!raw) {
281
+ if (error) *error = failureResponse(requestId, @"application_unavailable", @"application-element-missing", @"application element is unavailable");
282
+ finishRequestWatchdog(watchdog, watchdogState);
283
+ return nil;
284
+ }
285
+
286
+ NSArray<NSString *> *names = @[
287
+ kAttributeElementType,
288
+ kAttributeElementBaseType,
289
+ kAttributeLabel,
290
+ kAttributeValue,
291
+ kAttributeIdentifier,
292
+ kAttributeFrame,
293
+ kAttributeAutomationType,
294
+ kAttributeChildren,
295
+ ];
296
+ NSArray<NSNumber *> *numbers = _attributeNumbersForNames(names);
297
+ if (![numbers isKindOfClass:NSArray.class] || numbers.count != names.count) {
298
+ if (error) *error = failureResponse(requestId, @"reader_unavailable", @"attribute-vocabulary-mismatch", @"AX attribute vocabulary is incompatible");
299
+ finishRequestWatchdog(watchdog, watchdogState);
300
+ return nil;
301
+ }
302
+ NSMutableDictionary<NSNumber *, NSString *> *namesByNumber = [NSMutableDictionary dictionary];
303
+ [numbers enumerateObjectsUsingBlock:^(NSNumber *number, NSUInteger index, BOOL *stop) {
304
+ (void)stop;
305
+ if ([number isKindOfClass:NSNumber.class]) namesByNumber[number] = names[index];
306
+ }];
307
+ NSMutableDictionary *options = [_defaultSnapshotParameters() mutableCopy];
308
+ if (!options) options = [NSMutableDictionary dictionary];
309
+ options[@"attributes"] = numbers;
310
+ options[@"maxDepth"] = @(maxDepth);
311
+ options[@"maxChildren"] = @(maxNodes);
312
+ options[@"maxArrayCount"] = @(maxNodes);
313
+ BOOL automationEnabled = [self assertAutomationMode:YES];
314
+ NSError *runtimeError = nil;
315
+ id snapshot = nil;
316
+ BOOL acquisitionTruncated = NO;
317
+ SnapshotCaptureRecovery recovery = {0, 0, 0, 0};
318
+ @try {
319
+ if (![self isPrimaryForegroundProcess:pid]) {
320
+ if (error) *error = failureResponse(requestId, @"unsupported", @"foreground-owner-unverified", @"target app is not the primary foreground accessibility owner");
321
+ finishRequestWatchdog(watchdog, watchdogState);
322
+ return nil;
323
+ }
324
+ snapshot = captureSnapshotTree((__bridge id)raw, maxDepth, maxNodes, nativeLevelsHint,
325
+ ^id(id element, NSUInteger depth, NSUInteger nodes, NSError **captureError) {
326
+ if (![self isPrimaryForegroundProcess:pid]) {
327
+ if (captureError) *captureError = [NSError errorWithDomain:@"agent-device.snapshot" code:5
328
+ userInfo:@{NSLocalizedDescriptionKey: @"foreground owner changed during continuation"}];
329
+ return nil;
330
+ }
331
+ NSMutableDictionary *bounded = [options mutableCopy];
332
+ bounded[@"maxDepth"] = @(depth);
333
+ bounded[@"maxChildren"] = @(nodes);
334
+ bounded[@"maxArrayCount"] = @(nodes);
335
+ return [_framework userTestingSnapshotForElement:element options:bounded error:captureError];
336
+ }, &acquisitionTruncated, &recovery, &runtimeError);
337
+ if (![self isPrimaryForegroundProcess:pid]) {
338
+ if (error) *error = failureResponse(requestId, @"unsupported", @"foreground-owner-changed", @"foreground accessibility ownership changed during acquisition");
339
+ finishRequestWatchdog(watchdog, watchdogState);
340
+ return nil;
341
+ }
342
+ } @catch (NSException *exception) {
343
+ if (error) *error = failureResponse(requestId, @"reader_unavailable", @"private-api-exception", exception.reason ?: @"AX snapshot raised an exception");
344
+ finishRequestWatchdog(watchdog, watchdogState);
345
+ return nil;
346
+ }
347
+ if (!snapshot && [runtimeError.domain isEqualToString:@"agent-device.snapshot"]) {
348
+ BOOL exhausted = runtimeError.code == 1;
349
+ if (error) *error = failureResponse(requestId, exhausted ? @"reader_unavailable" : @"malformed_tree",
350
+ exhausted ? @"continuation-budget-exhausted" : @"snapshot-tree-malformed", runtimeError.localizedDescription);
351
+ finishRequestWatchdog(watchdog, watchdogState);
352
+ return nil;
353
+ }
354
+ if (!snapshot) {
355
+ NSNumber *axError = runtimeError.userInfo[kAccessibilityErrorKey];
356
+ NSInteger code = [axError respondsToSelector:@selector(integerValue)] ? axError.integerValue : runtimeError.code;
357
+ NSString *kind = code == -25216 ? @"application_not_responding" : @"application_unavailable";
358
+ NSString *message = runtimeError.localizedDescription ?: @"AX snapshot returned no tree";
359
+ if (error) *error = failureResponse(requestId, kind, code == -25216 ? @"application-timeout" : @"application-server-unavailable", message);
360
+ finishRequestWatchdog(watchdog, watchdogState);
361
+ return nil;
362
+ }
363
+ BOOL truncated = NO;
364
+ BOOL malformed = NO;
365
+ NSUInteger count = 0;
366
+ NSDictionary *tree = [self nodeFromSnapshot:snapshot
367
+ namesByNumber:namesByNumber
368
+ depth:0
369
+ maxDepth:maxDepth
370
+ maxNodes:maxNodes
371
+ count:&count
372
+ truncated:&truncated
373
+ malformed:&malformed];
374
+ if (!tree) {
375
+ if (error) *error = failureResponse(requestId, @"malformed_tree", malformed ? @"snapshot-tree-malformed" : @"snapshot-root-invalid", malformed ? @"AX snapshot contained a malformed node" : @"AX snapshot did not contain a materialized root node");
376
+ finishRequestWatchdog(watchdog, watchdogState);
377
+ return nil;
378
+ }
379
+ finishRequestWatchdog(watchdog, watchdogState);
380
+ return @{
381
+ kProtocolVersionKey : @(kProtocolVersion),
382
+ kSourceVersionKey : kSourceVersion,
383
+ kRequestIdKey : requestId ?: @"",
384
+ @"generation" : generation ?: @"",
385
+ @"ok" : @YES,
386
+ @"pid" : @(pid),
387
+ @"tree" : tree,
388
+ @"truncated" : @((BOOL)(truncated || acquisitionTruncated)),
389
+ @"automationEnabled" : @(automationEnabled),
390
+ @"recovery" : @{
391
+ @"requests" : @(recovery.requests),
392
+ @"rejected" : @(recovery.rejected),
393
+ @"continuations" : @(recovery.continuations),
394
+ @"acceptedLevels" : @(recovery.acceptedLevels),
395
+ },
396
+ };
397
+ }
398
+ @end
399
+ BridgeRuntime *sharedRuntime(NSString **error)
400
+ {
401
+ static BridgeRuntime *runtime;
402
+ static dispatch_once_t once;
403
+ static NSString *setupError;
404
+ dispatch_once(&once, ^{
405
+ NSString *localError = nil;
406
+ runtime = [[BridgeRuntime alloc] initWithError:&localError];
407
+ setupError = [localError copy];
408
+ });
409
+ if (!runtime && error) *error = setupError ?: @"AX bridge runtime is unavailable";
410
+ return runtime;
411
+ }
@@ -58,10 +58,62 @@ int main(int argc, const char *argv[]) {
58
58
  #import <UIKit/UIKit.h>
59
59
 
60
60
  @interface AgentDeviceRunnerViewController : UIViewController
61
+ @property(nonatomic, strong) UILabel *alertActionStatus;
62
+ @property(nonatomic, assign) NSUInteger firstAlertActions;
63
+ @property(nonatomic, assign) NSUInteger replacementAlertActions;
64
+ @property(nonatomic, assign) BOOL alertFixtureStarted;
61
65
  @end
62
66
 
63
67
  @implementation AgentDeviceRunnerViewController
64
68
 
69
+ #if TARGET_OS_IOS
70
+ - (void)updateAlertActionStatus {
71
+ self.alertActionStatus.text = [NSString stringWithFormat:@"First actions: %lu; replacement actions: %lu",
72
+ (unsigned long)self.firstAlertActions,
73
+ (unsigned long)self.replacementAlertActions];
74
+ }
75
+
76
+ - (void)presentAlertFixtureReplacement:(BOOL)replacement {
77
+ NSArray<NSString *> *arguments = NSProcessInfo.processInfo.arguments;
78
+ BOOL sameTitle = [arguments containsObject:@"--agent-device-alert-same-title"];
79
+ BOOL sameBody = [arguments containsObject:@"--agent-device-alert-same-body"];
80
+ NSString *title = replacement && !sameTitle ? @"Next confirmation" : @"First confirmation";
81
+ NSString *body = replacement && !sameBody ? @"Second request" : @"First request";
82
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:title
83
+ message:body
84
+ preferredStyle:UIAlertControllerStyleAlert];
85
+ __weak UIAlertController *weakAlert = alert;
86
+ for (NSString *buttonTitle in @[@"Cancel", @"OK"]) {
87
+ UIAlertActionStyle style = [buttonTitle isEqualToString:@"Cancel"]
88
+ ? UIAlertActionStyleCancel : UIAlertActionStyleDefault;
89
+ [alert addAction:[UIAlertAction actionWithTitle:buttonTitle style:style handler:^(UIAlertAction *action) {
90
+ (void)action;
91
+ if (replacement) {
92
+ self.replacementAlertActions += 1;
93
+ } else {
94
+ self.firstAlertActions += 1;
95
+ }
96
+ [self updateAlertActionStatus];
97
+ if (!replacement) {
98
+ [weakAlert dismissViewControllerAnimated:NO completion:^{
99
+ [self presentAlertFixtureReplacement:YES];
100
+ }];
101
+ }
102
+ }]];
103
+ }
104
+ [self presentViewController:alert animated:NO completion:nil];
105
+ }
106
+
107
+ - (void)viewDidAppear:(BOOL)animated {
108
+ [super viewDidAppear:animated];
109
+ if (!self.alertFixtureStarted &&
110
+ [NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-alert-replacement-regression"]) {
111
+ self.alertFixtureStarted = YES;
112
+ [self presentAlertFixtureReplacement:NO];
113
+ }
114
+ }
115
+ #endif
116
+
65
117
  - (void)agentDeviceTextEntryDidChange:(UITextField *)textField {
66
118
  if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-text-entry-disappear-after-input"] &&
67
119
  textField.text.length > 0) {
@@ -88,6 +140,12 @@ int main(int argc, const char *argv[]) {
88
140
 
89
141
  // Keep the fixture behind a launch argument so normal runner snapshots remain unchanged.
90
142
  #if TARGET_OS_IOS
143
+ if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-alert-replacement-regression"]) {
144
+ self.alertActionStatus = label;
145
+ label.accessibilityIdentifier = @"agent-device-alert-actions";
146
+ [self updateAlertActionStatus];
147
+ }
148
+
91
149
  if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-text-entry-regression"]) {
92
150
  UITextField *textField = [[UITextField alloc] init];
93
151
  textField.accessibilityIdentifier = @"agent-device-hardware-keyboard-input";