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
@@ -1 +1 @@
1
- const e=`--agent-device-run-metro-companion`,t=`--agent-device-run-react-devtools-companion`,n=1e3,r=`AGENT_DEVICE_COMPANION_TUNNEL_SERVER_BASE_URL`,i=`AGENT_DEVICE_COMPANION_TUNNEL_BEARER_TOKEN`,a=`AGENT_DEVICE_COMPANION_TUNNEL_LOCAL_BASE_URL`,o=`AGENT_DEVICE_COMPANION_TUNNEL_LAUNCH_URL`,s=`AGENT_DEVICE_COMPANION_TUNNEL_STATE_PATH`,c=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_TENANT_ID`,l=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_RUN_ID`,u=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_LEASE_ID`,d=`AGENT_DEVICE_COMPANION_TUNNEL_REGISTER_PATH`,f=`AGENT_DEVICE_COMPANION_TUNNEL_UNREGISTER_PATH`,p=`AGENT_DEVICE_COMPANION_TUNNEL_DEVICE_PORT`,m=`AGENT_DEVICE_COMPANION_TUNNEL_SESSION`;var h=class extends Error{name=`MissingCompanionEnvError`};function g(e){let t=e.length;for(;t>0&&e.charCodeAt(t-1)===47;)--t;return t===e.length?e:e.slice(0,t)}function _(e,t,n=`index.bundle`){let r=new URL(`${g(e)}/${n}`);return r.searchParams.set(`platform`,t),r.searchParams.set(`dev`,`true`),r.searchParams.set(`minify`,`false`),r.toString()}export{h as _,p as a,d as c,c as d,r as f,e as g,f as h,i,u as l,s as m,g as n,o,m as p,n as r,a as s,_ as t,l as u,t as v};
1
+ const e=`--agent-device-run-metro-companion`,t=`--agent-device-run-react-devtools-companion`,n=1e3,r=`AGENT_DEVICE_COMPANION_TUNNEL_SERVER_BASE_URL`,i=`AGENT_DEVICE_COMPANION_TUNNEL_BEARER_TOKEN`,a=`AGENT_DEVICE_COMPANION_TUNNEL_LOCAL_BASE_URL`,o=`AGENT_DEVICE_COMPANION_TUNNEL_LAUNCH_URL`,s=`AGENT_DEVICE_COMPANION_TUNNEL_STATE_PATH`,c=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_TENANT_ID`,l=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_RUN_ID`,u=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_LEASE_ID`,d=`AGENT_DEVICE_COMPANION_TUNNEL_REGISTER_PATH`,f=`AGENT_DEVICE_COMPANION_TUNNEL_UNREGISTER_PATH`,p=`AGENT_DEVICE_COMPANION_TUNNEL_DEVICE_PORT`,m=`AGENT_DEVICE_COMPANION_TUNNEL_SESSION`;var h=class extends Error{name=`MissingCompanionEnvError`};function g(e){let t=e.length;for(;t>0&&e.charCodeAt(t-1)===47;)--t;return t===e.length?e:e.slice(0,t)}export{t as _,o as a,u as c,r as d,m as f,h as g,e as h,p as i,l,f as m,n,a as o,s as p,i as r,d as s,g as t,c as u};
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n,y as r}from"./sdk-contracts.js";import{A as i}from"./sdk-android-adb.js";var a=e({Deadline:()=>c,isEnvTruthy:()=>o,retryWithPolicy:()=>l});function o(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const s={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var c=class e{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(t,n=Date.now()){return new e(n,t)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return this.remainingMs(e)<=0}};async function l(e,n={},i={}){let a={maxAttempts:n.maxAttempts??s.maxAttempts,baseDelayMs:n.baseDelayMs??s.baseDelayMs,maxDelayMs:n.maxDelayMs??s.maxDelayMs,jitter:n.jitter??s.jitter,shouldRetry:n.shouldRetry},o;for(let t=1;t<=a.maxAttempts;t+=1){if(i.signal?.aborted)throw r();if(i.deadline?.isExpired()&&t>1)break;try{let n=await e({attempt:t,maxAttempts:a.maxAttempts,deadline:i.deadline});return i.onEvent?.({phase:i.phase,event:`succeeded`,attempt:t,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs()}),f({phase:i.phase,event:`succeeded`,attempt:t,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs()}),n}catch(e){o=e;let n=i.classifyReason?.(e),r={phase:i.phase,event:`attempt_failed`,attempt:t,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs(),reason:n};if(i.onEvent?.(r),f(r),t>=a.maxAttempts||a.shouldRetry&&!a.shouldRetry(e,t))break;let s=u(a.baseDelayMs,a.maxDelayMs,a.jitter,t),c=i.deadline?Math.min(s,i.deadline.remainingMs()):s;if(c<=0)break;let l={phase:i.phase,event:`retry_scheduled`,attempt:t,maxAttempts:a.maxAttempts,delayMs:c,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs(),reason:n};i.onEvent?.(l),f(l),await d(c,i.signal)}}let c={phase:i.phase,event:`exhausted`,attempt:a.maxAttempts,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs(),reason:i.classifyReason?.(o)};throw i.onEvent?.(c),f(c),o||new t(`COMMAND_FAILED`,`retry failed`)}function u(e,t,n,r){let i=Math.min(t,e*2**(r-1)),a=i*n;return Math.max(0,i+(Math.random()*2-1)*a)}function d(e,t){return new Promise(n=>{if(t?.aborted){n();return}let r=!1,i=()=>{r||(r=!0,t&&t.removeEventListener(`abort`,o),n())},a=setTimeout(i,e);function o(){clearTimeout(a),i()}t&&t.addEventListener(`abort`,o,{once:!0})})}function f(e){i({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}const p=new Set([`IOS_BOOT_TIMEOUT`,`IOS_RUNNER_CONNECT_TIMEOUT`,`IOS_TOOL_MISSING`,`ANDROID_BOOT_TIMEOUT`,`ADB_TRANSPORT_UNAVAILABLE`,`CI_RESOURCE_STARVATION_SUSPECTED`]);function m(e){return p.has(e.toUpperCase())}function h(e){let t=e.error?n(e.error):null,r=e.context?.platform,i=e.context?.phase;if(t?.code===`TOOL_MISSING`)return r===`android`?`ADB_TRANSPORT_UNAVAILABLE`:`IOS_TOOL_MISSING`;let a=t?.details??{},o=typeof a.message==`string`?a.message:void 0,s=typeof a.stdout==`string`?a.stdout:void 0,c=typeof a.stderr==`string`?a.stderr:void 0,l=a.boot&&typeof a.boot==`object`?a.boot:null,u=a.bootstatus&&typeof a.bootstatus==`object`?a.bootstatus:null,d=[e.message,t?.message,e.stdout,e.stderr,o,s,c,typeof l?.stdout==`string`?l.stdout:void 0,typeof l?.stderr==`string`?l.stderr:void 0,typeof u?.stdout==`string`?u.stdout:void 0,typeof u?.stderr==`string`?u.stderr:void 0].filter(Boolean).join(`
2
- `).toLowerCase();return r===`ios`&&d.includes(`0xe8008012`)?`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:r===`ios`&&(d.includes(`provisioning profile`)||d.includes(`embedded profile`))?`BOOT_COMMAND_FAILED`:r===`ios`&&(d.includes(`runner did not accept connection`)||i===`connect`&&(d.includes(`timed out`)||d.includes(`timeout`)||d.includes(`econnrefused`)||d.includes(`connection refused`)||d.includes(`fetch failed`)||d.includes(`socket hang up`)))?`IOS_RUNNER_CONNECT_TIMEOUT`:r===`ios`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`IOS_BOOT_TIMEOUT`:r===`android`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`ANDROID_BOOT_TIMEOUT`:d.includes(`resource temporarily unavailable`)||d.includes(`killed: 9`)||d.includes(`cannot allocate memory`)||d.includes(`system is low on memory`)?`CI_RESOURCE_STARVATION_SUSPECTED`:r===`android`&&(d.includes(`device not found`)||d.includes(`no devices`)||d.includes(`device offline`)||d.includes(`offline`)||d.includes(`unauthorized`)||d.includes(`not authorized`)||d.includes(`unable to locate device`)||d.includes(`invalid device`))?`ADB_TRANSPORT_UNAVAILABLE`:t?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function g(e){switch(e){case`IOS_BOOT_TIMEOUT`:return`Retry simulator boot and inspect simctl bootstatus logs; in CI reduce parallel jobs or use a larger runner.`;case`IOS_RUNNER_CONNECT_TIMEOUT`:return`Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.`;case`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:return`The XCTest runner cannot be installed on this device: its provisioning profile does not cover it. Register the device with the signing team (Xcode > Settings > Accounts, or add its UDID to the provisioning profile) and retry. Retrying without that will keep failing.`;case`ANDROID_BOOT_TIMEOUT`:return`Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.`;case`ADB_TRANSPORT_UNAVAILABLE`:return`Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.`;case`CI_RESOURCE_STARVATION_SUSPECTED`:return`CI machine may be resource constrained; reduce parallel jobs or use a larger runner.`;case`IOS_TOOL_MISSING`:return`Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.`;case`BOOT_COMMAND_FAILED`:return`Inspect command stderr/stdout for the failing boot phase and retry after environment validation.`;default:return`Retry once and inspect verbose logs for the failing phase.`}}export{o as a,c as i,h as n,l as o,m as r,a as s,g as t};
1
+ import{w as e}from"./sdk-contracts.js";function t(t){let n=t.error?e(t.error):null,r=t.context?.platform,i=t.context?.phase;if(n?.code===`TOOL_MISSING`)return r===`android`?`ADB_TRANSPORT_UNAVAILABLE`:`IOS_TOOL_MISSING`;let a=n?.details??{},o=typeof a.message==`string`?a.message:void 0,s=typeof a.stdout==`string`?a.stdout:void 0,c=typeof a.stderr==`string`?a.stderr:void 0,l=a.boot&&typeof a.boot==`object`?a.boot:null,u=a.bootstatus&&typeof a.bootstatus==`object`?a.bootstatus:null,d=[t.message,n?.message,t.stdout,t.stderr,o,s,c,typeof l?.stdout==`string`?l.stdout:void 0,typeof l?.stderr==`string`?l.stderr:void 0,typeof u?.stdout==`string`?u.stdout:void 0,typeof u?.stderr==`string`?u.stderr:void 0].filter(Boolean).join(`
2
+ `).toLowerCase();return r===`ios`&&d.includes(`0xe8008012`)?`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:r===`ios`&&(d.includes(`provisioning profile`)||d.includes(`embedded profile`))?`BOOT_COMMAND_FAILED`:r===`ios`&&(d.includes(`runner did not accept connection`)||i===`connect`&&(d.includes(`timed out`)||d.includes(`timeout`)||d.includes(`econnrefused`)||d.includes(`connection refused`)||d.includes(`fetch failed`)||d.includes(`socket hang up`)))?`IOS_RUNNER_CONNECT_TIMEOUT`:r===`ios`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`IOS_BOOT_TIMEOUT`:r===`android`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`ANDROID_BOOT_TIMEOUT`:d.includes(`resource temporarily unavailable`)||d.includes(`killed: 9`)||d.includes(`cannot allocate memory`)||d.includes(`system is low on memory`)?`CI_RESOURCE_STARVATION_SUSPECTED`:r===`android`&&(d.includes(`device not found`)||d.includes(`no devices`)||d.includes(`device offline`)||d.includes(`offline`)||d.includes(`unauthorized`)||d.includes(`not authorized`)||d.includes(`unable to locate device`)||d.includes(`invalid device`))?`ADB_TRANSPORT_UNAVAILABLE`:n?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function n(e){switch(e){case`IOS_BOOT_TIMEOUT`:return`Retry simulator boot and inspect simctl bootstatus logs; in CI reduce parallel jobs or use a larger runner.`;case`IOS_RUNNER_CONNECT_TIMEOUT`:return`Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.`;case`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`:return`Close the owning agent-device session or stop its daemon with retained-runner cleanup before retrying.`;case`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:return`The XCTest runner cannot be installed on this device: its provisioning profile does not cover it. Register the device with the signing team (Xcode > Settings > Accounts, or add its UDID to the provisioning profile) and retry. Retrying without that will keep failing.`;case`ANDROID_BOOT_TIMEOUT`:return`Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.`;case`ADB_TRANSPORT_UNAVAILABLE`:return`Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.`;case`CI_RESOURCE_STARVATION_SUSPECTED`:return`CI machine may be resource constrained; reduce parallel jobs or use a larger runner.`;case`IOS_TOOL_MISSING`:return`Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.`;case`BOOT_COMMAND_FAILED`:return`Inspect command stderr/stdout for the failing boot phase and retry after environment validation.`;default:return`Retry once and inspect verbose logs for the failing phase.`}}export{t as n,n as t};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import t from"node:path";import{createReadStream as n,createWriteStream as r,promises as i}from"node:fs";import{pipeline as a}from"node:stream/promises";import{Transform as o}from"node:stream";import{createGunzip as s}from"node:zlib";import*as c from"tar-stream";import*as l from"yauzl";const u=2*1024*1024*1024;var d=class{maxBytes;maxEntries;maxDepth;#e=0;#t=0;constructor(e={}){this.maxBytes=v(e.maxBytes??4294967296,`maxBytes`),this.maxEntries=v(e.maxEntries??1e5,`maxEntries`),this.maxDepth=v(e.maxDepth??3,`maxDepth`)}get bytes(){return this.#e}get entries(){return this.#t}preflightArchive(e){let t=v(e.depth,`depth`),n=v(e.entryCount,`entryCount`),r=v(e.declaredBytes,`declaredBytes`);if(t<1||t>this.maxDepth)throw _(`ARCHIVE_NESTING_LIMIT`,`Archive nesting depth exceeds the limit`);if(n>this.maxEntries-this.#t)throw _(`ARCHIVE_ENTRY_LIMIT`,`Archive contains too many entries`);if(r>this.maxBytes-this.#e)throw _(`ARCHIVE_EXPANDED_BYTES_LIMIT`,`Archive expands beyond the byte limit`);return new f(e=>this.#n(e),()=>this.#r(),e.entryCount,e.declaredBytes)}#n(e){let t=v(e,`bytes`);if(t>this.maxBytes-this.#e)throw _(`ARCHIVE_EXPANDED_BYTES_LIMIT`,`Archive expands beyond the byte limit`);this.#e+=t}#r(){if(this.#t>=this.maxEntries)throw _(`ARCHIVE_ENTRY_LIMIT`,`Archive contains too many entries`);this.#t+=1}},f=class{#e;#t;#n;#r;#i=0;#a=0;constructor(e,t,n,r){this.#e=e,this.#t=t,this.#n=n,this.#r=r}chargeBytes(e){let t=v(e,`bytes`);if(t>this.#r-this.#a)throw _(`ARCHIVE_MANIFEST_MISMATCH`,`Archive contents changed after inspection`);this.#e(t),this.#a+=t}commitEntry(){if(this.#i>=this.#n)throw _(`ARCHIVE_MANIFEST_MISMATCH`,`Archive contents changed after inspection`);this.#t(),this.#i+=1}finish(){if(this.#i!==this.#n||this.#a!==this.#r)throw _(`ARCHIVE_MANIFEST_MISMATCH`,`Archive contents changed after inspection`)}};function p(e,t,n){return e.preflightArchive({depth:t,entryCount:n.length,declaredBytes:n.reduce((e,t)=>e+t.size,0)})}function m(e,t){return e.name===t.name&&e.kind===t.kind&&e.size===t.size&&e.mode===t.mode}function h(e){if(!e||e.includes(`\0`)||e.includes(`\\`)||t.posix.isAbsolute(e)||/^[a-zA-Z]:/.test(e)||e.startsWith(`//`))throw _(`ARCHIVE_UNSAFE_PATH`,`Archive contains an unsafe entry path`);let n=t.posix.normalize(e).replace(/^(\.\/)+/,``).replace(/\/$/,``);if(!n||n===`.`||n===`..`||n.startsWith(`../`))throw _(`ARCHIVE_UNSAFE_PATH`,`Archive contains an unsafe entry path`);return n}function g(e,n){let r=h(n),i=t.resolve(e),a=t.resolve(i,...r.split(`/`));if(!a.startsWith(`${i}${t.sep}`))throw _(`ARCHIVE_UNSAFE_PATH`,`Archive entry escapes the extraction root`);return a}function _(t,n,r){return new e(`INVALID_ARGS`,n,{reason:t},r)}function v(e,t){if(!Number.isSafeInteger(e)||e<0)throw RangeError(`${t} must be a non-negative safe integer`);return e}async function y(e){e.signal?.throwIfAborted();let t=e.budget??new d,n=e.depth??1,r=await b(e,t,n);await e.validateManifest?.(r);let i=p(t,n,r),a=c.extract(),o=x(e.archivePath,e.gzip,a,e.signal);try{for await(let t of a){e.signal?.throwIfAborted();let n=w(t.header);if(!n){await E(t);continue}let a=r.shift();if(!a||!m(a,n))throw _(`ARCHIVE_MANIFEST_MISMATCH`,`Archive contents changed after inspection`);await T(t,a,e.outputRoot,i),i.commitEntry()}await o}catch(e){throw a.destroy(),await o.catch(()=>{}),e}if(r.length!==0)throw _(`ARCHIVE_MANIFEST_MISMATCH`,`Archive contents changed after inspection`);i.finish()}async function b(e,t,n){let r=[],i=0,a=c.extract(),o=x(e.archivePath,e.gzip,a,e.signal);try{for await(let o of a){e.signal?.throwIfAborted();let a=w(o.header);if(!a){await E(o);continue}i+=a.size,t.preflightArchive({depth:n,entryCount:r.length+1,declaredBytes:i}),r.push(a),await E(o)}await o}catch(e){throw a.destroy(),await o.catch(()=>{}),e}return r}function x(e,t,r,i){return t?a(n(e),s(),r,{signal:i}):a(n(e),r,{signal:i})}function S(e){if(e===`directory`)return`directory`;if(e===`file`||e===`contiguous-file`||e==null)return`file`;throw e===`link`||e===`symlink`?_(`ARCHIVE_UNSAFE_ENTRY`,`Uploaded app bundle archive cannot contain symlinks or hard links`):_(`ARCHIVE_UNSAFE_ENTRY`,`Archive contains a link or special entry`)}function C(e,t){return(e??(t===`directory`?493:420))&511}function w(e){if(D(e.name,e.type))return;let t=h(e.name),n=S(e.type),r=n===`directory`?0:e.size??0;if(!Number.isSafeInteger(r)||r<0)throw _(`ARCHIVE_INVALID_ENTRY`,`Archive entry has an invalid size`);return{name:t,kind:n,size:r,mode:C(e.mode,n)}}async function T(e,n,o,s){let c=g(o,n.name);if(n.kind===`directory`){await i.mkdir(c,{recursive:!0,mode:n.mode}),await E(e);return}await i.mkdir(t.dirname(c),{recursive:!0}),await a(e,async function*(e){for await(let t of e)s.chargeBytes(Buffer.byteLength(t)),yield t},r(c,{flags:`wx`,mode:n.mode}))}async function E(e){for await(let t of e);}function D(e,t){return t===`directory`&&(e===`.`||e===`./`||e===``)}async function O(e){e.signal?.throwIfAborted();let n=e.budget??new d,o=e.depth??1,s=[],c=0;await k(e.archivePath,e.signal,e=>{n.preflightArchive({depth:o,entryCount:s.length+1,declaredBytes:c});let t=M(e);c+=t.size,n.preflightArchive({depth:o,entryCount:s.length+1,declaredBytes:c}),s.push(t)}),await e.validateManifest?.(s);let l=p(n,o,s),u=await k(e.archivePath,e.signal,(e,t)=>{t>=s.length&&F()});u.length!==s.length&&F();let f=await A(e.archivePath);try{for(let n=0;n<u.length;n+=1){e.signal?.throwIfAborted();let o=u[n],c=s[n];(!o||!c||!m(M(o),c))&&F();let d=g(e.outputRoot,c.name);c.kind===`directory`?await i.mkdir(d,{recursive:!0,mode:c.mode}):(await i.mkdir(t.dirname(d),{recursive:!0}),await a(await j(f,o),async function*(e){for await(let t of e)l.chargeBytes(Buffer.byteLength(t)),yield t},r(d,{flags:`wx`,mode:c.mode}),{signal:e.signal})),l.commitEntry()}l.finish()}finally{f.close()}}async function k(e,t,n){let r=await A(e);return await new Promise((e,i)=>{let a=[],o=()=>{r.off(`entry`,s),r.off(`end`,c),r.off(`error`,l),t?.removeEventListener(`abort`,u)},s=e=>{try{n?.(e,a.length),a.push(e),r.readEntry()}catch(e){o(),i(e)}},c=()=>{o(),e(a)},l=e=>{o(),i(e)},u=()=>{o(),r.close(),i(t?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r.on(`entry`,s),r.once(`end`,c),r.once(`error`,l),t?.addEventListener(`abort`,u,{once:!0}),t?.aborted)return u();r.readEntry()}).finally(()=>r.close())}function A(e){return new Promise((t,n)=>{l.open(e,{lazyEntries:!0,autoClose:!1,validateEntrySizes:!0,strictFileNames:!0},(e,r)=>e?n(e):t(r))})}function j(e,t){return new Promise((n,r)=>{e.openReadStream(t,(e,t)=>e?r(e):n(t))})}function M(e){N(e);let t=h(e.fileName),n=e.externalFileAttributes>>>16&65535,r=P(e.fileName,n),i=r?493:420;return{name:t,kind:r?`directory`:`file`,size:r?0:e.uncompressedSize,mode:n&511||i}}function N(e){if(e.isEncrypted())throw _(`ARCHIVE_UNSAFE_ENTRY`,`Encrypted archive entries are not supported`);let t=e.externalFileAttributes>>>16&61440;if(t!==0&&t!==16384&&t!==32768)throw _(`ARCHIVE_UNSAFE_ENTRY`,`Archive contains a link or special entry`)}function P(e,t){return e.endsWith(`/`)||(t&61440)==16384}function F(){throw _(`ARCHIVE_MANIFEST_MISMATCH`,`Archive contents changed after inspection`)}async function I(e){e.signal?.throwIfAborted();let n=t.resolve(e.archivePath),r=t.resolve(e.outputRoot);if(n===r||n.startsWith(`${r}${t.sep}`))throw RangeError(`archivePath must be outside outputRoot`);await i.mkdir(r,{recursive:!1});try{e.type===`zip`?await O({...e,archivePath:n,outputRoot:r}):await y({...e,archivePath:n,outputRoot:r,gzip:e.type===`tgz`})}catch(e){throw await i.rm(r,{recursive:!0,force:!0}),e}}function L(e){let t=e.toLowerCase();if(t.endsWith(`.tar.gz`)||t.endsWith(`.tgz`))return`tgz`;if(t.endsWith(`.tar`))return`tar`;if(t.endsWith(`.zip`)||t.endsWith(`.ipa`))return`zip`}function R(e){if(!Number.isSafeInteger(e.maxBytes)||e.maxBytes<0)throw RangeError(`maxBytes must be a non-negative safe integer`);let t=0,n=new o({transform(n,r,i){let a=t+n.byteLength;if(!Number.isSafeInteger(a)||a>e.maxBytes){i(e.createLimitError());return}t=a,i(null,n)}});return Object.defineProperty(n,"bytesSeen",{enumerable:!0,get:()=>t}),n}export{u as a,d as i,L as n,I as r,R as t};
1
+ import{Transform as e}from"node:stream";function t(t){if(!Number.isSafeInteger(t.maxBytes)||t.maxBytes<0)throw RangeError(`maxBytes must be a non-negative safe integer`);let n=0,r=new e({transform(e,r,i){let a=n+e.byteLength;if(!Number.isSafeInteger(a)||a>t.maxBytes){i(t.createLimitError());return}n=a,i(null,e)}});return Object.defineProperty(r,"bytesSeen",{enumerable:!0,get:()=>n}),r}export{t};
@@ -0,0 +1 @@
1
+ const e={support:`supported`},t={support:`unsupported`},n={lease:e,inventory:{support:`partial`,note:`Inventory exposes only the leased cloud device, not the provider catalog.`},install:{support:`partial`,note:`Requires provider-specific upload or a path visible to the remote Appium server.`},snapshot:{support:`partial`,note:`Uses Appium page source XML, not agent-device native snapshot backends.`},screenshot:e,tap:e,doubleTap:e,longPress:e,swipe:e,scroll:{support:`partial`,note:`Implemented as viewport-relative W3C pointer gestures.`},fill:e,type:e,back:e,home:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},orientation:{support:`partial`,note:`Uses the WebDriver rotation/orientation endpoints; four-way rotation collapses to portrait/landscape on drivers that only accept the two-way endpoint. Rotates the current display, so an activity that does not pin its orientation may need rotating again once it is foreground.`},appSwitcher:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},tvRemote:t,"clipboard.read":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},"clipboard.write":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},settings:t,alert:t,pinch:t,rotateGesture:t,transformGesture:t,logs:t,record:t,artifacts:t,portReverse:t,nativeSnapshotBackend:{support:`unsupported`,note:`Cloud WebDriver cannot upload or run agent-device native runner/helper backends.`}};function r(e){return{provider:e.provider,platform:e.platform,snapshotBackend:e.platform===`ios`?`xctest`:`android`,snapshotSource:`appium-page-source`,operations:o(n,e.overrides)}}function i(e,t){return e.operations[t].support!==`unsupported`}function a(e,t){let n=e.operations[t],r=n.note?` ${n.note}`:``;return`${e.provider} WebDriver runtime does not support ${t}.${r}`}function o(e,t){let n={...e};for(let[r,i]of Object.entries(t??{}))n[r]=typeof i==`string`?{...e[r],support:i}:{...e[r],...i};return n}export{r as n,a as r,i as t};
@@ -0,0 +1 @@
1
+ import{C as e}from"./sdk-contracts.js";const t={min:.01,max:1},n={flagKey:`screenshotMaxSize`,cliToken:`--max-size`,envVar:`AGENT_DEVICE_SCREENSHOT_MAX_SIZE`,publicOptionKey:`maxSize`,migration:{screenshot:`screenshot --max-size was removed; use --scale <0.01-1> (or AGENT_DEVICE_SCREENSHOT_SCALE) to downscale proportionally`,record:`record --max-size was removed; recordings capture at native resolution`}};function r(e,t){return t&&Object.hasOwn(t,n.flagKey)?n.migration[e]:void 0}function i(t,r){if(Object.hasOwn(r,n.publicOptionKey)||Object.hasOwn(r,n.flagKey))throw new e(`INVALID_ARGS`,n.migration[t])}const a={selectorInvalid:`CROP_SELECTOR_INVALID`,targetNotFound:`CROP_TARGET_NOT_FOUND`,targetAmbiguous:`CROP_TARGET_AMBIGUOUS`,captureUnreadable:`CROP_CAPTURE_UNREADABLE`,captureIncomplete:`CROP_CAPTURE_INCOMPLETE`,emptyIntersection:`CROP_EMPTY_INTERSECTION`,partialIntersection:`CROP_PARTIAL_INTERSECTION`,targetNotAccepted:`CROP_TARGET_NOT_ACCEPTED`,frameMismatch:`CROP_FRAME_MISMATCH`,pendingPixelIdentityEvidence:`PENDING_PIXEL_IDENTITY_EVIDENCE`},o=[`out`,`overlayRefs`,`screenshotCropOn`,`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],s=[{key:`screenshotCropOn`,names:[`--crop-on`],type:`string`,usageLabel:`--crop-on <selector-expression>`,usageDescription:`Screenshot: crop the capture to the frame of the selector resolved on the same screen`,projectConfig:!1,recorded:!0},{key:`screenshotPixelDensity`,names:[`--pixel-density`],type:`int`,min:1,usageLabel:`--pixel-density <n>`,usageDescription:`Screenshot: output PNG pixel density in pixels per logical point (currently supported on iOS simulators)`,projectConfig:!0,recorded:!0},{key:`screenshotFullscreen`,names:[`--fullscreen`,`--full`,`-f`],type:`boolean`,usageLabel:`--fullscreen, --full, -f`,usageDescription:`Screenshot: on web capture the full page; on macOS app sessions capture the full desktop instead of the app window`,projectConfig:!0,recorded:!0},{key:`screenshotScale`,names:[`--scale`],type:`number`,min:t.min,max:t.max,usageLabel:`--scale <0.01-1>`,usageDescription:`Screenshot: resize both dimensions by this factor (or use AGENT_DEVICE_SCREENSHOT_SCALE)`,projectConfig:!0,recorded:!0},{key:`screenshotNoStabilize`,names:[`--no-stabilize`],type:`boolean`,usageLabel:`--no-stabilize`,usageDescription:`Screenshot: skip Android demo-mode/status-bar stabilization and settle delay for low-latency capture loops`,projectConfig:!0,recorded:!0},{key:`screenshotNormalizeStatusBar`,names:[`--normalize-status-bar`],type:`boolean`,usageLabel:`--normalize-status-bar`,usageDescription:`Screenshot: on iOS simulators temporarily normalize status-bar chrome for deterministic screenshot diffs`,projectConfig:!0,recorded:!0}],c=[{tokens:[`--fullscreen`,`--full`,`-f`],key:`screenshotFullscreen`},{tokens:[`--no-stabilize`],key:`screenshotNoStabilize`},{tokens:[`--normalize-status-bar`],key:`screenshotNormalizeStatusBar`}],l=[{token:`--pixel-density`,key:`screenshotPixelDensity`,label:`screenshot --pixel-density`}],u=[{token:`--scale`,key:`screenshotScale`,label:`screenshot --scale`,min:t.min,max:t.max}],d=[{token:`--crop-on`,key:`screenshotCropOn`,label:`screenshot --crop-on`}];function f(e){return v({overlayRefs:e?.overlayRefs,cropOn:e?.screenshotCropOn,pixelDensity:e?.screenshotPixelDensity,fullscreen:e?.screenshotFullscreen,scale:e?.screenshotScale,stabilize:!e?.screenshotNoStabilize&&void 0,normalizeStatusBar:e?.screenshotNormalizeStatusBar})}function p(e={}){return v({overlayRefs:e.overlayRefs,screenshotCropOn:e.screenshotCropOn??e.cropOn,screenshotPixelDensity:e.screenshotPixelDensity??e.pixelDensity,screenshotFullscreen:e.screenshotFullscreen??e.fullscreen,screenshotScale:e.screenshotScale,screenshotNoStabilize:e.screenshotNoStabilize??(e.stabilize===!1||void 0),screenshotNormalizeStatusBar:e.screenshotNormalizeStatusBar??e.normalizeStatusBar})}function m(e={}){return p({...e,screenshotScale:e.screenshotScale??e.scale})}function h(n){let{min:r,max:i}=t;if(n.scale!==void 0&&(!Number.isFinite(n.scale)||n.scale<r||n.scale>i))throw new e(`INVALID_ARGS`,`screenshot scale must be between ${r} and ${i}`)}function g(e,t){typeof t?.screenshotPixelDensity==`number`&&e.push(`--pixel-density`,String(t.screenshotPixelDensity)),t?.screenshotFullscreen&&e.push(`--fullscreen`),typeof t?.screenshotScale==`number`&&e.push(`--scale`,String(t.screenshotScale)),t?.screenshotNoStabilize&&e.push(`--no-stabilize`),t?.screenshotNormalizeStatusBar&&e.push(`--normalize-status-bar`)}function _(t){let{args:r,flags:i,index:a}=t,o=r[a];if(o===n.cliToken)throw new e(`INVALID_ARGS`,n.migration.screenshot);return y(o,i,a)??b({args:r,index:a,flags:i,token:o})??x({args:r,index:a,flags:i,token:o})??S({args:r,index:a,flags:i,token:o})??{handled:!1}}function v(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function y(e,t,n){let r=c.find(t=>t.tokens.some(t=>t===e));if(r)return t[r.key]=!0,{handled:!0,nextIndex:n}}function b(t){let n=l.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isInteger(r)||r<1)throw new e(`INVALID_ARGS`,`${n.label} requires a positive integer`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function x(t){let n=u.find(e=>e.token===t.token);if(!n)return;let r=Number(t.args[t.index+1]);if(!Number.isFinite(r)||r<n.min||r>n.max)throw new e(`INVALID_ARGS`,`${n.label} requires a number from ${n.min} to ${n.max}`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}function S(t){let n=d.find(e=>e.token===t.token);if(!n)return;let r=t.args[t.index+1];if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`${n.label} requires a selector expression`);return t.flags[n.key]=r,{handled:!0,nextIndex:t.index+1}}export{s as a,r as c,f as d,i as f,t as i,p as l,o as n,g as o,h as p,a as r,_ as s,n as t,m as u};
@@ -0,0 +1 @@
1
+ import{h as e}from"./sdk-batch.js";const t=s(`public`),n=s(`internal`),r=s(`local-cli`),i={help:`help`};function a(){return[...Object.values(t),...Object.values(r)].sort()}function o(e){return Object.values(i).includes(e)||Object.values(n).includes(e)?!0:a().includes(e)}function s(t){let n={};for(let[r,i]of e(t))n[r]=i;return n}export{a as i,t as n,o as r,n as t};
@@ -0,0 +1 @@
1
+ import{i as e,r as t}from"./observability.js";const n=new Map([{alias:`long-press`,command:`longpress`},{alias:`tap`,command:`press`},{alias:`launch`,command:`open`},{alias:`relaunch`,command:`open`,impliedFlags:[`relaunch`]}].map(e=>[e.alias,e])),r=new Map([[t,e],[`rotate`,`rotate was renamed to orientation; for the two-finger gesture use: gesture rotate`]]);function i(e){return n.get(e.toLowerCase())?.command??e}function a(e){return r.get(e.toLowerCase())}function o(e){return n.get(e.toLowerCase())}export{i as n,a as r,o as t};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{_ as t}from"./location-coordinates.js";import{i as n}from"./command-catalog.js";import{S as r,d as i,l as a}from"./registry.js";import{n as o,t as s}from"./path-resolution.js";import{D as c,T as l}from"./sdk-android-adb.js";import{r as u}from"./command-schema.js";import d from"node:path";import f from"node:fs";const p=new Set([`config`,`remoteConfig`,`help`,`version`,`batchSteps`,`githubActionsArtifact`]),m=new Set([`appsFilter`,`iosSimulatorDeviceSet`]),h=x(),g=new Map(h.map(e=>[e.key,e]));function _(e){return g.get(e)}function v(e){return h.filter(t=>t.configurable&&t.supportsCommand(e))}function y(e,t){return _(e)?.supportsCommand(t)??!1}function b(e,t,n,r){return c(w(e),t,n,r)}function x(){let e=new Map;for(let t of r()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of i)t.set(e,new Set([`*`]));for(let e of n()){let n=u(e);for(let r of[...n.allowedFlags??[],...n.supportedFlags??[]]){let n=t.get(r);n&&n.has(`*`)||(n?n.add(e):t.set(r,new Set([e])))}}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,configurable:!p.has(e),env:{names:m.has(e)?[]:[l(e)]},supportsCommand(n){let r=t.get(e);return r?r.has(`*`)?!0:n?r.has(n):!1:!1}})).sort((e,t)=>S(e.key,t.key))}function S(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===r?e<t?-1:+(e>t):n<r?-1:1}function C(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}function w(e){let t=e.flagDefinitions.find(e=>e.setValue===void 0);if(t)return t;let n=C(e);if(n.type===`enum`){let t=n.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>e!==void 0);return{...n,setValue:void 0,enumValues:t}}return n}function T(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}function E(e){let t=e.env??process.env;return T(T({},j(O(e.cwd,e.cliFlags.config,t))),F(t,e.command))}const D=new Set(`json.platform.target.device.udid.serial.session.sessionLock.activity.launchArgs.launchUrl.remote.deviceHub.testIme.appsFilter.clean.force.stale.relaunch.shutdown.surface.headless.restart.noRecord.record.recordAs.snapshotInteractiveOnly.snapshotDiff.snapshotDepth.snapshotScope.snapshotRaw.snapshotCustomActions.snapshotForceFull.screenshotPixelDensity.screenshotFullscreen.screenshotScale.screenshotNoStabilize.screenshotNormalizeStatusBar.overlayRefs.networkInclude.baseline.threshold.count.pointerCount.fps.quality.hideTouches.recordingScope.intervalMs.delayMs.durationMs.holdMs.jitterPx.pixels.doubleTap.verify.settle.settleQuietMs.clickButton.backMode.pauseMs.pattern.kind.perfTemplate.responseLevel.verbose.cost.timeoutMs.retries.failFast.recordVideo.replayUpdate.replayMaestro.replayFrom.replayPlanDigest.replayKeepSession.findFirst.findLast.batchOnError.batchMaxSteps.retainPaths.retentionMs.shardAll.shardSplit.noLogin`.split(`.`));function O(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:A(r,e,n),required:!0,source:`explicit`}]:[{path:k(n),required:!1,source:`user`},{path:d.resolve(e,`agent-device.json`),required:!1,source:`project`}]}function k(e){return d.join(s(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return o(e,{cwd:t,env:n})}function j(e){let t={};for(let n of e)T(t,M(n));return t}function M(t){let{path:n,required:r}=t;if(!f.existsSync(n)){if(r)throw new e(`INVALID_ARGS`,`Config file not found: ${n}`);return{}}let i;try{i=f.readFileSync(n,`utf8`)}catch(t){throw new e(`INVALID_ARGS`,`Failed to read config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}let a;try{a=JSON.parse(i)}catch(t){throw new e(`INVALID_ARGS`,`Invalid JSON in config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}if(!a||typeof a!=`object`||Array.isArray(a))throw new e(`INVALID_ARGS`,`Config file must contain a JSON object: ${n}`);return N(a,{source:t.source,label:`${t.source===`project`?`project `:``}config file ${n}`})}function N(n,r){let i={};for(let[o,s]of Object.entries(n)){let n=o,c=_(n);if(!c)throw o===t.flagKey?new e(`INVALID_ARGS`,`Config key "${o}" in ${r.label} was removed; use "screenshotScale" (0.01-1) to downscale screenshots. Recordings capture at native resolution.`):new e(`INVALID_ARGS`,`Unknown config key "${o}" in ${r.label}.`);if(!c.configurable)throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. This key is not supported in config files.`);if(r.source===`project`&&!D.has(n))throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. Move it to ~/.agent-device/config.json, pass it with --config or AGENT_DEVICE_CONFIG, or provide it through CLI flags/environment variables.`);if(n===`installSource`){i.installSource=a(s,r.label);continue}i[n]=b(c,s,r.label,o)}return i}const P=new Set([`screenshot`,`record`]);function F(n,r){let i=n[t.envVar];if(r!==null&&P.has(r)&&typeof i==`string`&&i.trim().length>0)throw new e(`INVALID_ARGS`,`${t.envVar} was removed. ${t.migration[r===`record`?`record`:`screenshot`]}`);let a={};for(let e of v(r)){if(e.key===`installSource`)continue;let t=e.env.names.map(e=>({name:e,value:n[e]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(a[e.key]=b(e,t.value,`environment variable ${t.name}`,t.name))}return a}export{T as n,y as r,E as t};
1
+ import{C as e}from"./sdk-contracts.js";import{t}from"./capture.js";import{O as n,c as r,k as i,p as a}from"./registry.js";import{i as o}from"./catalog.js";import{a as s,s as c}from"./sdk-remote-config.js";import{n as l,t as u}from"./path-resolution.js";import"./file.js";import{r as d}from"./command-schema.js";import f from"node:path";import p from"node:fs";const m=new Set([`config`,`remoteConfig`,`help`,`version`,`batchSteps`,`githubActionsArtifact`]),h=new Set([`appsFilter`,`iosSimulatorDeviceSet`]),g=S(),_=new Map(g.map(e=>[e.key,e]));function v(e){return _.get(e)}function y(e){return g.filter(t=>t.configurable&&t.supportsCommand(e))}function b(e,t){return v(e)?.supportsCommand(t)??!1}function x(e,t,n,r){return c(T(e),t,n,r)}function S(){let e=new Map;for(let t of n()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of a)t.set(e,new Set([`*`]));for(let e of o()){let n=d(e);for(let r of[...n.allowedFlags??[],...n.supportedFlags??[]]){let n=t.get(r);n&&n.has(`*`)||(n?n.add(e):t.set(r,new Set([e])))}}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,configurable:!m.has(e),env:{names:h.has(e)?[]:[s(e)]},supportsCommand(n){let r=t.get(e);return r?r.has(`*`)?!0:n?r.has(n):!1:!1}})).sort((e,t)=>C(e.key,t.key))}function C(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===r?e<t?-1:+(e>t):n<r?-1:1}function w(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}function T(e){let t=e.flagDefinitions.find(e=>e.setValue===void 0);if(t)return t;let n=w(e);if(n.type===`enum`){let t=n.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>e!==void 0);return{...n,setValue:void 0,enumValues:t}}return n}function E(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}function D(e){let t=e.env??process.env;return E(E({},M(k(e.cwd,e.cliFlags.config,t))),I(t,e.command))}const O=i();function k(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:j(r,e,n),required:!0,source:`explicit`}]:[{path:A(n),required:!1,source:`user`},{path:f.resolve(e,`agent-device.json`),required:!1,source:`project`}]}function A(e){return f.join(u(`~`,{env:e}),`.agent-device`,`config.json`)}function j(e,t,n){return l(e,{cwd:t,env:n})}function M(e){let t={};for(let n of e)E(t,N(n));return t}function N(t){let{path:n,required:r}=t;if(!p.existsSync(n)){if(r)throw new e(`INVALID_ARGS`,`Config file not found: ${n}`);return{}}let i;try{i=p.readFileSync(n,`utf8`)}catch(t){throw new e(`INVALID_ARGS`,`Failed to read config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}let a;try{a=JSON.parse(i)}catch(t){throw new e(`INVALID_ARGS`,`Invalid JSON in config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}if(!a||typeof a!=`object`||Array.isArray(a))throw new e(`INVALID_ARGS`,`Config file must contain a JSON object: ${n}`);return P(a,{source:t.source,label:`${t.source===`project`?`project `:``}config file ${n}`})}function P(n,i){let a={};for(let[o,s]of Object.entries(n)){let n=o,c=v(n);if(!c)throw o===t.flagKey?new e(`INVALID_ARGS`,`Config key "${o}" in ${i.label} was removed; use "screenshotScale" (0.01-1) to downscale screenshots. Recordings capture at native resolution.`):new e(`INVALID_ARGS`,`Unknown config key "${o}" in ${i.label}.`);if(!c.configurable)throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${i.label}. This key is not supported in config files.`);if(i.source===`project`&&!O.has(n))throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${i.label}. Move it to ~/.agent-device/config.json, pass it with --config or AGENT_DEVICE_CONFIG, or provide it through CLI flags/environment variables.`);if(n===`installSource`){a.installSource=r(s,i.label);continue}a[n]=x(c,s,i.label,o)}return a}const F=new Set([`screenshot`,`record`]);function I(n,r){let i=n[t.envVar];if(r!==null&&F.has(r)&&typeof i==`string`&&i.trim().length>0)throw new e(`INVALID_ARGS`,`${t.envVar} was removed. ${t.migration[r===`record`?`record`:`screenshot`]}`);let a={};for(let e of y(r)){if(e.key===`installSource`)continue;let t=e.env.names.map(e=>({name:e,value:n[e]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(a[e.key]=x(e,t.value,`environment variable ${t.name}`,t.name))}return a}export{E as n,b as r,D as t};
@@ -1,8 +1,8 @@
1
- import{n as e}from"./rolldown-runtime.js";import{rr as t}from"./sdk-batch-runner.js";import{i as n}from"./command-catalog.js";import{S as r,d as i,m as a}from"./registry.js";import{n as o}from"./version.js";import{i as s,r as c}from"./command-schema.js";const l=[`Flows: launchApp; runFlow file/inline with platform, visibility, and limited boolean conditions; onFlowStart/onFlowComplete; repeat.times and retry.`,`Interactions: tapOn, doubleTapOn, longPressOn, inputText, eraseText, openLink, hideKeyboard, basic pressKey, and back; targets support index, childOf, label, points, and optional.`,`Assertions and navigation: assertVisible, assertNotVisible, extendedWaitUntil, scroll, scrollUntilVisible, absolute/percentage/target swipe, takeScreenshot, waitForAnimationToEnd, and stopApp.`,`Scripts: ordered runScript file/env scripts with http.post, json, and output variables.`],u=[`Runtime: iOS and Android only; launchApp.clearState supports Android and iOS simulators, launch arguments are Apple-only, and standalone device utility/state commands are unsupported.`,`Expressions: when.true supports boolean literals and maestro.platform comparisons; repeat.while, evalScript, and broader JavaScript expressions are unsupported.`,`Environment: flow env is the default, AD_VAR_* overrides it, and CLI -e KEY=VALUE wins over both.`,`Failure diagnostics: resolved targets and runFlow paths are rendered, while inputText payloads remain hidden; do not place secrets in diagnostic identifiers.`,`Trust: runScript executes trusted scripts, may make http.post network requests, and is not a security sandbox; output keys cannot contain a dot.`,`Errors and tracking: unsupported commands and fields fail with source context when available; open a focused issue only when implementation work is planned.`];function d(){return[`Supported subset:`,...l.map(e=>` - ${e}`),``,`Boundaries:`,...u.map(e=>` - ${e}`)].join(`
2
- `)}function f(e){let t=e.endsWith(`?`),n=t?e.slice(0,-1):e;return t?`[${n}]`:`<${n}>`}function p(e){return r().filter(t=>t.key===e)}function m(e,t){if(t.usageOverride)return t.usageOverride;let n=(t.positionalArgs??[]).map(f),r=(t.allowedFlags??[]).flatMap(e=>p(e).map(e=>e.usageLabel??e.names[0])).map(e=>`[${e}]`);return[e,...n,...r].join(` `)}function h(){return`agent-device <command> [args] [--json]
1
+ import{r as e}from"./rolldown-runtime.js";import{O as t,f as n,p as r,y as i}from"./registry.js";import{fr as a}from"./sdk-batch.js";import{i as o}from"./catalog.js";import{r as s}from"./version.js";import{i as c,r as l}from"./command-schema.js";import{n as u}from"./cli-command-aliases.js";const d=[`Flows: launchApp; runFlow file/inline with platform, visibility, and limited boolean conditions; onFlowStart/onFlowComplete; repeat.times and retry.`,`Interactions: tapOn, doubleTapOn, longPressOn, inputText on the focused element, eraseText, openLink, hideKeyboard, basic pressKey, and back; selector targets poll until available and support recursive index, childOf, above, below, leftOf, rightOf, containsChild, containsDescendants, points, and optional; outer command labels are metadata, not target selectors.`,'Assertions and navigation: assertVisible, assertNotVisible, assertTrue (literal values and ${VAR} lookups only; "", "false", "0", "null", and "undefined" are falsy, everything else is truthy), extendedWaitUntil, scroll, scrollUntilVisible, absolute/percentage/target swipe, takeScreenshot, waitForAnimationToEnd, clearState, and stopApp.',`Scripts: ordered runScript file/env scripts with http.post, json, and output variables.`],f=[`Runtime: iOS and Android only; launchApp.clearState and standalone clearState support Android and iOS simulators, launch arguments are Apple-only, and other standalone device utility/state commands are unsupported.`,"Expressions: when.true supports boolean literals and maestro.platform comparisons; assertTrue supports literal values and ${VAR} lookups only; repeat.while, evalScript, and broader JavaScript expressions are unsupported.",`Environment: flow env is the default, AD_VAR_* overrides it, and CLI -e KEY=VALUE wins over both.`,`Failure diagnostics: resolved targets and runFlow paths are rendered, while inputText payloads remain hidden; do not place secrets in diagnostic identifiers.`,`Trust: runScript executes trusted scripts, may make http.post network requests, and is not a security sandbox; output keys cannot contain a dot.`,`Errors and tracking: unsupported commands and fields fail with source context when available; open a focused issue only when implementation work is planned.`];function p(){return[`Supported subset:`,...d.map(e=>` - ${e}`),``,`Boundaries:`,...f.map(e=>` - ${e}`)].join(`
2
+ `)}function m(e){let t=e.endsWith(`?`),n=t?e.slice(0,-1):e;return t?`[${n}]`:`<${n}>`}function h(e){return t().filter(t=>t.key===e)}function g(e){if(!e.usageHidden)return e.usageLabel??e.names[0]}function _(e){return(e??[]).flatMap(e=>h(e).map(g).filter(e=>e!==void 0).map(e=>`[${e}]`))}function v(e,t){return[t.usageOverride??[e,...(t.positionalArgs??[]).map(m)].join(` `),..._(t.usageFlags??t.allowedFlags)].join(` `)}function y(){return`agent-device <command> [args] [--json]
3
3
 
4
4
  Automates iOS, Android, macOS, TV, and web apps for AI agents.
5
- All ${n().length} commands: agent-device help commands
5
+ All ${o().length} commands: agent-device help commands
6
6
 
7
7
  Start:
8
8
  When starting a task with a known app, first run:
@@ -18,14 +18,14 @@ Loop:
18
18
  scroll <direction|top|bottom> [amount] --settle; back --settle
19
19
  acts, waits for quiet, and prints the UI diff. Continue from that diff.
20
20
  Run snapshot -i only when the diff lacks the next target or did not settle.
21
- Verify a named expectation with the diff, wait text "...", wait <selector>,
21
+ Verify a named expectation with the diff, wait text "...", wait <selector>, wait absent <selector>,
22
22
  is, get, or find. A bare screenshot is not verification.
23
23
  End with: agent-device close
24
24
 
25
25
  Targets:
26
26
  Copy refs exactly: @e12, @e12~s4. Keep @ and any ~sN pin; refs go stale
27
27
  after mutations. A literal @handle is label="@handle", not a bare ref.
28
- Prefer refs, then id/label/role selectors. Selector keys: ${t.join(` `)}.
28
+ Prefer refs, then id/label/role selectors. Selector keys: ${a.join(` `)}.
29
29
  Coordinates are last resort: after snapshot -i shows no semantic target, or a
30
30
  sparse/AX-unavailable warning says its refs and selectors are invalid.
31
31
  Then screenshot, press <x> <y>, and re-snapshot on the changed screen.
@@ -49,14 +49,16 @@ Guides (agent-device help <topic>):
49
49
  manual-qa / dogfood / validate / debugging / scripting / gestures
50
50
  react-native / react-devtools / cdp / tv / web / macos / remote
51
51
  physical-device / ios-system-ui / maestro
52
- `}var g=e({buildCommandUsageText:()=>N,buildUsageText:()=>E,helpTopicIds:()=>P});const _=[`Default config files: ~/.agent-device/config.json, ./agent-device.json (project-safe defaults only).`,`Use --config <path> or AGENT_DEVICE_CONFIG for explicit connection/provider defaults; project config cannot select endpoints or credentials.`],v=[{label:`AGENT_DEVICE_SESSION`,description:`Explicit session name`},{label:`AGENT_DEVICE_PLATFORM`,description:`Default platform binding`},{label:`AGENT_DEVICE_SCREENSHOT_SCALE`,description:`Default screenshot scale factor`},{label:`AGENT_DEVICE_SESSION_LOCK`,description:`Bound-session conflict mode`},{label:`AGENT_DEVICE_DAEMON_BASE_URL`,description:`Connect to remote daemon`},{label:`AGENT_DEVICE_DAEMON_AUTH_TOKEN`,description:`Remote daemon service/API token`},{label:`AGENT_DEVICE_CLOUD_BASE_URL`,description:`Bridge/control-plane API origin for cloud auth and /api-keys`}],y=[`agent-device open Settings --platform ios`,`agent-device open https://example.com --platform web`,`agent-device snapshot -i`,`agent-device fill @e3 "test@example.com"`,`agent-device replay ./session.ad`,`agent-device test ./suite --platform android`],b=`Wait failure contract:
53
- Read the verdict from error.details.reason in --json, not the message text.
52
+ `}var b=e({buildCommandUsageText:()=>L,buildUsageText:()=>A,helpTopicIds:()=>z,resolveHelpTargetUsageText:()=>R});const x=[`Default config files: ~/.agent-device/config.json, ./agent-device.json (project-safe defaults only).`,`Use --config <path> or AGENT_DEVICE_CONFIG for explicit connection/provider defaults; project config cannot select endpoints or credentials.`],S=[{label:`AGENT_DEVICE_SESSION`,description:`Explicit session name`},{label:`AGENT_DEVICE_PLATFORM`,description:`Default platform binding`},{label:`AGENT_DEVICE_SCREENSHOT_SCALE`,description:`Default screenshot scale factor`},{label:`AGENT_DEVICE_SESSION_LOCK`,description:`Bound-session conflict mode`},{label:`AGENT_DEVICE_DAEMON_BASE_URL`,description:`Connect to remote daemon`},{label:`AGENT_DEVICE_DAEMON_AUTH_TOKEN`,description:`Remote daemon service/API token`},{label:`AGENT_DEVICE_CLOUD_BASE_URL`,description:`Bridge/control-plane API origin for cloud auth and /api-keys`}],C=[`agent-device open Settings --platform ios`,`agent-device open https://example.com --platform web`,`agent-device snapshot -i`,`agent-device fill @e3 "test@example.com"`,`agent-device replay ./session.ad`,`agent-device wait absent 'label="Loading..."' 3000`,`agent-device test ./suite --platform android`],w=`Wait failure contract:
53
+ Read error.details.reason in --json, not the message text.
54
54
  wait_target_absent: a readable capture ran and found no match.
55
+ wait_target_present: wait absent timed out with matches; details include matches and firstMatch.
56
+ predicate_failed: wait absent had no valid capture; final observation/diagnostic is preserved.
55
57
  wait_capture_stalled: no readable capture finished before the deadline -- retriable.
56
58
  wait_deadline_exceeded: a later capture used the remaining budget after an earlier readable one.
57
59
  wait_landmark_identity_mismatch: a replay destination guard found the selector but not the recorded identity.
58
60
  wait_stable_timeout: wait stable never saw a stable UI -- not an absence verdict.
59
- `,x={commands:{summary:`Full command catalog, global flags, configuration, and environment`,body:`agent-device help commands`},"manual-qa":{summary:`Follow manual test scripts with exact interactions and verification`,body:`agent-device help manual-qa
61
+ `,T={commands:{summary:`Full command catalog, global flags, configuration, and environment`,body:`agent-device help commands`},"manual-qa":{summary:`Follow manual test scripts with exact interactions and verification`,body:`agent-device help manual-qa
60
62
 
61
63
  Use this when asked to follow a manual QA script, test case, checklist, acceptance flow, or user-provided instructions.
62
64
 
@@ -70,7 +72,7 @@ Loop:
70
72
  3. Run press/fill/click/longpress <ref-or-selector> --settle for each mutating step.
71
73
  4. Treat a settled:true diff as the next observation. Do not add wait stable or another snapshot when the diff already shows the next target or expected result.
72
74
  5. If --settle prints not settled, follow its hint before the next ref-based action.
73
- 6. Verify named expectations with wait text/selector, get, is, find, or the settled diff. A bare screenshot/snapshot is not verification for a named expectation.
75
+ 6. Verify named expectations with wait text/selector/absent, get, is, find, or the settled diff. A bare screenshot/snapshot is not verification for a named expectation.
74
76
  7. Close the session when the script ends.
75
77
 
76
78
  Command shapes:
@@ -78,56 +80,56 @@ Command shapes:
78
80
  agent-device open https://example.com/deep-link
79
81
  agent-device snapshot -i
80
82
  agent-device press @e12 --settle
81
- agent-device press 'label="Follow"'
83
+ agent-device press 'label="Follow"' --settle
82
84
  agent-device fill @e13 "qa@example.com" --settle
83
85
  agent-device wait text "Order placed" 3000
86
+ agent-device wait absent 'label="Loading..."' 3000
84
87
  agent-device close
85
88
  --relaunch forces fresh app state; a deep link/URL open does not need it. Labels with an apostrophe or quote (label="Don't leave") are shell-quoting hazards: prefer the @ref from the latest snapshot/settle output over quoting the literal label.
86
89
 
87
90
  Targets:
88
- Prefer refs from the latest snapshot -i or settled diff. Use durable selectors when the label/id is known: label="Search", id="submit", role=button label="Follow".
91
+ Prefer refs from the latest snapshot -i or settled diff. Use durable selectors when the label/id is known: label="Search", id="submit", role=button label="Follow". If label text matches both a field and its caption, target the field with label="Email" editable=true.
89
92
  For text fields, use fill <target> <text> --settle to replace the field value; use type only to append to an already-focused field.
90
93
  Do not use placeholders such as @ref, @eN, <button>, or <selector> in a final command plan. If the ref is unknown, first run snapshot -i.
91
94
  Coordinates are fallback-only after refs/selectors fail or accessibility omits the target; use screenshot or snapshot -i --json to choose a visible center point.
92
95
 
93
96
  Recovery:
94
97
  Network/typeahead result missing: wait text "Expected result" or wait <selector>.
98
+ A target that should be gone/disappear: use wait absent <selector>; wait exists ... is rejected in favor of the plain selector wait.
95
99
  Keyboard visible over the next target: the on-screen keyboard usually does not block presses, so press the target directly instead of dismissing. If the press fails or reports no visible effect, scroll the target into view or use keyboard enter when submission is wanted.
96
100
  Sparse or recovered accessibility snapshot: use screenshot as visual truth, leave the bad screen if needed, then retry snapshot -i.
97
101
  Non-hittable success hint: verify with the settled diff or snapshot; retarget by a better ref/selector if the UI did not change.
98
102
 
99
- ${b}`},maestro:{summary:`Supported Maestro YAML commands, grammar, and runtime boundaries`,body:`agent-device help maestro
103
+ ${w}`},maestro:{summary:`Supported Maestro YAML commands, grammar, and runtime boundaries`,body:`agent-device help maestro
100
104
 
101
105
  Run Maestro compatibility flows with replay <flow.yaml> --maestro or test <path> --maestro. Bind an iOS or Android target with --platform or an existing session.
102
106
 
103
- ${d()}
107
+ ${p()}
104
108
 
105
109
  Unsupported syntax fails loudly rather than being skipped. Architecture, performance tradeoffs, and declared conformance divergences: https://github.com/callstack/agent-device/blob/main/docs/adr/0015-direct-maestro-engine.md
106
110
  Focused compatibility request: https://github.com/callstack/agent-device/issues/new`},workflow:{summary:`Normal agent-device bootstrap, exploration, and validation loop`,body:`agent-device help workflow
107
111
 
108
- Command shapes, refs, selectors, waits, recovery, and platform limits for the default open -> snapshot -i -> settle -> verify -> close loop.
112
+ Command shapes, refs, selectors, waits, recovery, and platform limits for open -> snapshot -i -> settle -> verify -> close loop.
109
113
 
110
114
  Command shape:
111
- Command lines only -- no prose, numbering, fences, pipes, or grep/head/tail/jq on agent-device output; raw output carries the refs/hints the next step needs. Subcommand first, then positionals, then flags: agent-device open com.example.app --session checkout --platform android --relaunch
115
+ Command lines only -- no prose, numbering, fences, pipes, or grep/head/tail/jq; raw output carries refs/hints for the next step. Order: subcommand, positionals, flags: agent-device open com.example.app --session checkout --platform android --relaunch
112
116
  Chain confident consecutive steps with &&: press 'label="Search"' --settle && fill 'label="Search"' "query" --settle. Fall back to one command at a time when a step is uncertain (ambiguous match, network-backed result, unseen screen).
113
117
  Refs look like @e12; use the exact ref from the latest snapshot -i, never a placeholder (@ref, @eN, @Label_Name). Pin with ~s<n> (press @e12~s4); iOS rejects a stale pinned ref -- refresh with snapshot -i or use a selector.
114
- close = agent-device close. App back is back; system back is back --system. Taps are press/click. type never takes --settle: run type, then diff snapshot to verify. Known flow: batch ./steps.json (help scripting).
118
+ close = agent-device close. App back is back; system back is back --system. Taps are press/click. type never takes --settle: run type, then diff snapshot to verify. Known flow: batch --steps-file ./steps.json (help batch).
115
119
  Gestures: scroll/swipe for lists/flicks; gesture pan|fling|pinch|rotate|transform|drag for multi-touch. Shapes and platform quirks: help gestures.
116
120
 
117
121
  Bootstrap:
118
- agent-device devices --platform ios
119
- agent-device open MyApp --platform ios --device "iPhone 17 Pro"
120
- Known app: open <app> --foreground -> snapshot. Bare form needs one running app on one iOS sim; capture failure keeps session open.
122
+ open --foreground -> snapshot. Selection: explicit --device/--udid/--serial, then session, booted/bootable local, or provider; --platform/--target only filter. Ambiguous/empty fails with bounded retry selectors; no provider fallback.
121
123
  Install arguments are app/package id then artifact path: agent-device install com.example.app ./dist/app.apk --platform android, then open <id> --relaunch for fresh state. Use reinstall only when explicitly requested.
122
124
  Unknown app id: devices, then apps, then open <discovered-app-id>. Never open artifact paths or invent package ids; ask if lookup misses the target.
123
125
  Apple CI: prepare ios-runner after boot/install, before replay/test (help prepare). Remote/cloud: connect -> open -> commands -> close -> disconnect (help remote). Reusable scripts, secret-safe fills, replay repair: help scripting.
124
126
 
125
127
  Snapshots and refs:
126
- snapshot reads visible state; snapshot -i gets current interactive refs only -- the fast path before an interaction. Default text is agent-facing and token-efficient; --raw/--json only for the full provider tree.
127
- Legend: @e12 [button] label="Add to cart" enabled hittable -> press @e12. [off-screen below] -> scroll down (a hint, not a ref).
128
+ snapshot reads visible state; snapshot -i gets current interactive refs only -- fast path before interaction. Default text is token-efficient; --raw/--json for full provider tree.
129
+ Legend: @e12 [button] label="Add to cart" enabled hittable -> press @e12. [off-screen below] -> scroll down --until (a hint, not a ref).
128
130
  Refs stay valid until you press/click/fill/type/scroll/back/wait-for-async-UI, or otherwise change app state; open/--relaunch clears the stored snapshot outright.
129
- Prefer --settle and continue from its settled diff when it shows the next target; refresh with snapshot -i only when you did not settle, settle reported not settled, or its output lacks what you need. A known selector/label after a mutation is often enough, since interaction commands refresh state internally.
130
- Truncated preview: snapshot -s @e12 (the current concrete ref), not get text. Missing target in a list: scroll down/up (not bottom/top unless the task wants the edge), then snapshot -i. TV/D-pad focus: help tv.
131
+ Prefer --settle and its diff when it shows next target; refresh with snapshot -i only when you did not settle, it reported not settled, or output lacks what you need. A known selector/label after a mutation is often enough, since interaction commands refresh state internally.
132
+ Truncated preview: snapshot -s @e12 (the current concrete ref), not get text. Missing target: scroll <dir> --until <selector>. TV/D-pad focus: help tv.
131
133
 
132
134
  Selectors:
133
135
  id="field-email", label="Allow", role=button label="Search" -- not bare role keys (button="Search"); no CSS selectors/--selector/--text/raw x-y when refs/selectors exist.
@@ -136,7 +138,7 @@ Selectors:
136
138
 
137
139
  Text entry:
138
140
  fill replaces; type appends to an already-focused field: fill 'id="field-email"' "qa@example.com"; type "Handle with care" --delay-ms 80
139
- Empty replacement is not a clear-field command (do not plan fill <target> ""); use a visible clear/reset control, or report the gap.
141
+ fill <target> "" clears the field (replace with nothing); the empty argument must be present -- fill <target> alone is a missing argument.
140
142
  Plain fill/type first; if an iOS debounced/search-as-you-type field drops characters, retry with --delay-ms before clipboard paste.
141
143
  The keyboard usually does not block interactions -- press the next target directly. keyboard dismiss taps its own dismiss key when one exists, else UNSUPPORTED_OPERATION. Android: try dismiss before back. iOS: when both fail, do not tap a static text/heading hoping it is safe; prefer type "\\n" to submit.
142
144
  iOS paste-prompt limits and Android IME/handwriting capture quirks: help debugging.
@@ -145,8 +147,8 @@ Session ordering:
145
147
  Stateful commands (open/press/fill/type/scroll/back/alert/replay/batch/close) run serially within one session. Parallelize only read-only commands, or separate sessions/devices.
146
148
 
147
149
  Read-only and waits:
148
- ${b}
149
- snapshot/get/is/find answer read-only questions; snapshot -i only when refs are needed. --settle confirms local UI quieted; for results that arrive later (network/debounce), follow with wait text "Expected result" or wait <selector> instead of polling.
150
+ ${w}
151
+ snapshot/get/is/find answer read-only questions; snapshot -i is for refs. --settle confirms local UI quieted; delayed results use wait text "Expected result" or wait <selector> instead of polling; strict disappearance uses wait absent <selector>.
150
152
  wait stable [quietMs] [timeoutMs] (defaults 500/10000) is the fallback for open/relaunch/navigation, or an intentionally-unsettled mutation -- not after a --settle whose diff already shows the change. Ambiguous find: add --first or --last.
151
153
 
152
154
  Navigation:
@@ -161,7 +163,7 @@ Validation and evidence:
161
163
 
162
164
  React Native: help react-native for Metro/Re.Pack reload, DevTools, RN overlays. JS-only change: metro reload, find "Home"; open --relaunch for native reset.
163
165
 
164
- Lifecycle facts (trust these instead of probing): open without --relaunch is idempotent-foreground; --relaunch restarts it. close keeps a healthy iOS runner warm by default; runners and daemons both self-idle after 5 minutes, and a stale lease reclaims automatically -- a live owner still rejects with "already owned by another agent-device daemon". Env vars: help physical-device.
166
+ Lifecycle facts (trust these instead of probing): open without --relaunch is idempotent-foreground; --relaunch restarts it. close keeps a healthy iOS runner warm by default; runners and daemons both self-idle after 5 minutes, and a stale lease reclaims automatically. The device claim taken by open also reclaims another worktree's retained warm runner; "already owned by another agent-device daemon" = owner outside claim arbitration. Env vars: help physical-device.
165
167
 
166
168
  Escalate:
167
169
  help manual-qa scripted manual QA
@@ -182,6 +184,7 @@ Use this for reusable .ad script authoring (save-script), scripted destination g
182
184
 
183
185
  Script paths are the caller's:
184
186
  replay <path> and test <path-or-glob> resolve and read on the machine running the command, then send the script content (Maestro runFlow includes too) with the request. The same flows therefore run against a local daemon and against a remote one (AGENT_DEVICE_DAEMON_BASE_URL) with no copy step, and a missing script fails immediately, naming the path you typed. --save-script writes on the DAEMON host and is rejected against a remote daemon.
187
+ test --json marks a failed test with infrastructure: true only when the owning runtime classified a device, runner, boot, or transport failure. It remains a failed test; consumers may use the tag to distinguish "the oracle did not run" from a behavioral replay divergence without weakening either gate.
185
188
 
186
189
  Reusable open-to-destination scripts:
187
190
  Arm recording on the first open, perform the full journey, verify the destination with a selector-targeted wait, then publish without closing:
@@ -189,7 +192,7 @@ Reusable open-to-destination scripts:
189
192
  agent-device press 'id="continue"' --settle
190
193
  agent-device wait 'role="heading" label="Screen X"'
191
194
  agent-device session save-script
192
- session save-script [path] [--force] publishes the sole recorded open through the destination guard, omits close, and leaves the session active. The guard is a selector wait on a labeled/id-bearing landmark: its identity is captured while armed and re-verified after the wait resolves at replay time, so a reshuffled screen with the same label elsewhere fails closed instead of false-passing. A duration wait, wait stable, wait @ref, or a selector wait on an unlabeled element is not a destination guard. A second successful open aborts publication; start a fresh session to author again.
195
+ session save-script [path] [--force] publishes the sole recorded open through the destination guard, omits close, and leaves the session active. The guard is a selector wait on a labeled/id-bearing landmark: its identity is captured while armed and re-verified after the wait resolves at replay time, so a reshuffled screen with the same label elsewhere fails closed instead of false-passing. A duration wait, wait stable, wait absent, wait @ref, or a selector wait on an unlabeled element is not a destination guard. A second successful open aborts publication; start a fresh session to author again.
193
196
  Unparameterized fill/type inputs are literal .ad script content. For a sensitive fill, arm recording first, keep the live value in an env var, and name its replay placeholder explicitly:
194
197
  export AD_VAR_PASSWORD='<secret>'
195
198
  agent-device fill 'id="password"' "$AD_VAR_PASSWORD" --record-as PASSWORD
@@ -202,7 +205,8 @@ Replay divergence and repair:
202
205
 
203
206
  Batch:
204
207
  agent-device batch --steps '[{"command":"open","input":{"app":"settings"}},{"command":"wait","input":{"kind":"duration","durationMs":100}}]'
205
- Step keys are command, input, and optional runtime; put command arguments inside input using the same fields as the MCP/Node command. Legacy positionals/flags steps still work with a deprecation warning. Never use args, step positionals, or flags in new batch JSON.
208
+ agent-device batch --steps-file ./steps.json --json
209
+ Step keys are command, input, and optional runtime -- that is the whole accepted shape. input holds the command's structured fields, not its terminal spelling: a CLI positional becomes a named field (target, text, direction) and a flag becomes a camelCase key (--settle -> "settle":true). Accepted commands, that mapping, and runnable press/fill/snapshot steps: help batch.
206
210
  Maestro full-suite validation on connected devices uses one test command with a comma-separated --device list and --shard-all (--shard-split only to split suite entries across devices):
207
211
  agent-device test ./e2e/maestro --maestro --device udid1,emulator-5554 --shard-all 2
208
212
 
@@ -218,10 +222,12 @@ Shapes:
218
222
  agent-device swipe 320 500 40 500 --count 8 --pause-ms 30 --pattern ping-pong
219
223
  agent-device gesture pan 200 420 0 -80 500
220
224
  agent-device gesture pan 200 420 80 -40 700 --pointer-count 2
225
+ agent-device scroll down --until 'id=submit'
221
226
  agent-device gesture fling right 200 420 180
222
227
  agent-device gesture pinch 0.5 200 400
223
228
  agent-device gesture rotate 35 200 420
224
229
  agent-device gesture transform 200 420 80 -40 2 35 700
230
+ scroll <dir> --until <selector> repeats scroll-and-check passes until that element is on screen, then stops: one request instead of a scroll-then-snapshot loop, and it stops on the target rather than overshooting it. It reports the passes it spent, fails when the content runs out first, and is refused on top/bottom, which already stop themselves.
225
231
  longpress accepts coordinates, @refs, or selectors; prefer @ref/selector, coordinates only as a fallback. Duration and gesture scale/center are positional. gesture pan is one finger by default; add --pointer-count 2 for a parallel two-finger pan. Keep count/pause/pattern on one swipe: --count (cap 200), --pause-ms (cap 10000ms), --pattern ping-pong; the combined swipe/pause schedule is capped at 60000ms.
226
232
  For repeated iOS smoke checks: press <x> <y> --count <n> --jitter-px <n> for tap series, swipe <x1> <y1> <x2> <y2> --count <n> for drag series.
227
233
 
@@ -382,9 +388,8 @@ Diagnostics and traces:
382
388
  agent-device perf trace stop --kind perfetto
383
389
  Treat native perf output as the agent evidence: for example, state=stopped, outPath=/tmp/app.perfetto-trace, sizeBytes=5392410, method=adb-shell-perfetto. The 5.3 MB raw trace stays in the artifact.
384
390
  CPU reports return at most ten top functions in structured data and print five in default CLI output.
385
- Prefer explicit perf frames, perf memory, perf cpu, or perf trace forms. Bare perf, perf sample, perf metrics, and metrics are deprecated compatibility forms until the next major release.
386
- On Android, those deprecated aggregate forms retain the released dumpsys cpuinfo point sample for compatibility; new profiling workflows should use perf cpu profile.
387
- Startup duration belongs to the open command's startup result; read it there instead of using aggregate perf.
391
+ Use explicit perf frames, perf memory, perf cpu, or perf trace forms. Aggregate perf was removed in 0.21: bare perf, perf sample, perf metrics, and metrics fail with exact replacements.
392
+ Startup duration belongs to the open command's startup result; read it there.
388
393
 
389
394
  Memory diagnostics:
390
395
  Use perf memory when the symptom is leak/growth/OOM suspicion and you need agent-readable evidence.
@@ -457,6 +462,8 @@ Rules:
457
462
  For cross-platform validation with explicit device selectors, use separate sessions/devices and restart react-devtools between platforms.
458
463
  Remote Android and iOS bridge runs normally through agent-device react-devtools; the CLI keeps the needed local service tunnel alive until agent-device react-devtools stop or disconnect. Expo support depends on the SDK's bundled React Native runtime.
459
464
  Remote iOS apps attempt the legacy React DevTools websocket during JavaScript startup. If the app was already open before react-devtools start, run open <bundle-id> --platform ios --relaunch, then wait --connected.
465
+ React Native 0.87+ needs agent-react-devtools installed as a dev dependency of the app project, then a one-time npx agent-react-devtools init there and a rebundle, before wait --connected can succeed. The npm exec package this wrapper runs is temporary and does not install it into the app. Run npx agent-react-devtools uninit when the task is done unless the user wants to keep the setup.
466
+ Verify an attached app with status or wait --connected before trusting any result. With 0 connected apps, count, errors, and get tree return empty results that look like a clean pass.
460
467
 
461
468
  Example:
462
469
  agent-device react-devtools status
@@ -473,6 +480,11 @@ Example:
473
480
  agent-device react-devtools profile report @c5
474
481
  agent-device network dump --include headers
475
482
 
483
+ Device busy and ownership:
484
+ DEVICE_IN_USE has two flavors. "already in use by session X" is this daemon: reuse it with --session X, or run close --session X first. "owned by session X in workspace Y" is another worktree's daemon holding the host-global device claim: it is never retriable — run the error's exact recovery command instead of retrying.
485
+ Inspect ownership without any daemon: agent-device device status (add --stale for proven-dead owners; settle and release those with agent-device device release --stale). devices marks rows that are claimed, so pick an unclaimed device instead of contending.
486
+ A live foreign owner is released only by closing its session from its own workspace or stopping its daemon: agent-device daemon stop --state-dir <owner state dir> (the error names the state dir). Never recover by hunting PIDs with ps/kill. boot/install/shutdown take the same claims as open and refuse foreign-claimed devices identically.
487
+
476
488
  Use snapshot, screenshot, logs, network, perf frames, and perf memory for device/app runtime evidence. Use react-devtools when component internals or React rendering behavior matters.`},cdp:{summary:`React Native CDP targets, JS heap snapshots, and leak triage`,body:`agent-device help cdp
477
489
 
478
490
  Use this when a React Native or Expo app exposes a CDP target through Metro and
@@ -606,7 +618,7 @@ For simulator/emulator flows, use help manual-qa for routine QA or help workflow
606
618
  Discovery:
607
619
  agent-device devices --platform ios
608
620
  agent-device devices --platform android
609
- Use --device <name-or-udid> only when multiple devices are present.
621
+ With multiple devices present, select one: --device <name>, or --udid <udid> (iOS) / --serial <serial> (Android) when names collide.
610
622
 
611
623
  iOS physical-device prerequisites:
612
624
  Xcode, xcrun xcdevice, and xcrun xctrace must be available from the selected Xcode.
@@ -633,7 +645,7 @@ Runner and daemon lifecycle (applies to simulators too):
633
645
  open without --relaunch is idempotent-foreground for an already-running app (it brings the process forward; it does not restart it). open --relaunch restarts the app; on iOS simulators this collapses to one simctl launch --terminate-running-process call instead of a separate terminate-then-launch.
634
646
  close keeps a healthy iOS simulator XCTest runner warm by default so the next open on that device skips the runner build, unless --shutdown was requested, the session was recording, the session held a device lease, or the device used a scoped (non-default) simulator set. A retained runner auto-stops after an idle window (default 5 minutes); set AGENT_DEVICE_IOS_RUNNER_IDLE_STOP_MS to override, or 0 to disable idle stop and retain until daemon exit.
635
647
  Each AGENT_DEVICE_STATE_DIR runs its own daemon. It self-exits after an idle window (default 5 minutes, matching the runner idle-stop default) once it has no open sessions, no in-flight requests, and no active recording; set AGENT_DEVICE_DAEMON_IDLE_TIMEOUT_MS to override, or 0 to disable idle reap.
636
- A stale iOS runner lease — its owner process dead, or its AGENT_DEVICE_STATE_DIR deleted — is reclaimed automatically instead of failing with "is already owned by another agent-device daemon"; a genuinely live owner whose state dir still exists still rejects with that error.
648
+ A stale iOS runner lease — its owner process dead, or its AGENT_DEVICE_STATE_DIR deleted — is reclaimed automatically instead of failing with "is already owned by another agent-device daemon". A live owner's runner is also reclaimed when the requesting daemon holds the host-global device claim for that device: claims are exclusive, so holding one proves the runner's owner released the device and merely kept the runner warm. The error remains only for owners outside claim arbitration (a pre-claims build, or daemons pointed at different claim stores).
637
649
 
638
650
  For iOS SpringBoard, widget, or other system-UI surfaces, read agent-device help ios-system-ui.`},"ios-system-ui":{summary:`iOS SpringBoard, widget, and system-surface workflow`,body:`agent-device help ios-system-ui
639
651
 
@@ -677,9 +689,9 @@ Providers:
677
689
  After direct-provider connect:
678
690
  Read the printed Device, App, Next, and workflow-note lines. They are also available as verification/device/app/liveSession/nextSteps/notes in --json output.
679
691
  BrowserStack and AWS Device Farm create the hosted session on open. open needs the installed package or bundle identifier, not the app artifact name or ARN.
680
- A new Limrun instance has no user app. Run install <package-or-bundle-id> <app-path-or-url> first; install allocates the instance, then open launches the installed id.
692
+ Before provider allocation, apps lists compatible uploaded app assets without creating an instance when the selected provider exposes a catalog. open <exact-asset-name> creates the instance with that asset, resolves its installed app id, and launches it. install remains available when the app comes from a fresh local path or URL.
681
693
  AWS Device Farm cannot install after allocation. If connect reports no attached app, run its printed reconnect command, which includes --session <name> --force, before open.
682
- Do not run devices or apps as a pre-open catalog probe for direct providers; those commands can allocate the deferred provider session and only inspect that live device.
694
+ Do not run devices as a pre-open catalog probe for direct providers; it can allocate the deferred provider session. Limrun is the exception for apps: before allocation it lists uploaded assets for the selected platform.
683
695
 
684
696
  Device cloud interfaces:
685
697
  CLI is the canonical bootstrap path: connect limrun/browserstack/aws-device-farm, then use normal open/snapshot/click/close/artifacts/disconnect commands.
@@ -699,6 +711,13 @@ Direct proxy flow for a remote Mac/simulator:
699
711
  agent-device close
700
712
  agent-device disconnect
701
713
 
714
+ Human takeover of a leased remote device:
715
+ Run agent-device takeover using the active remote connection and session. It pauses state-changing agent commands until Ctrl+C while snapshots and other read-only diagnostics remain available. Tenant requests can control only their admitted lease device. Local takeover without a remote device lease is not supported.
716
+ agent-device takeover --session remote-session
717
+ agent-device takeover status
718
+ agent-device takeover release <hold-id>
719
+ An HTTP-mode daemon also accepts authenticated GET/PUT/DELETE requests at /admin/human-control/holds on its loopback listener. Host administrators supply the exact lease backend/provider/device key and use the local daemon token, not a tenant credential. This host-admin route is intentionally not forwarded by agent-device proxy. Holds do not survive daemon restart; re-establish them after reconnecting.
720
+
702
721
  Cloud profile flow:
703
722
  agent-device connect
704
723
  agent-device open com.example.app
@@ -729,7 +748,8 @@ Limrun direct-device flow:
729
748
  agent-device connect limrun --platform android
730
749
 
731
750
  Limrun creates remote iOS simulators and Android emulators only. Do not pass local device selectors such as --udid, --serial, or --device.
732
- agent-device open com.example.app
751
+ agent-device apps
752
+ agent-device open Example.apk
733
753
  agent-device snapshot -i
734
754
  agent-device close
735
755
  agent-device disconnect
@@ -763,6 +783,7 @@ Rules:
763
783
  disconnect releases local connection state; close releases the active session and device lease.
764
784
  A busy direct-proxy device error means another agent owns the device until it closes or its inactivity lease expires.
765
785
  Keep the proxy token secret. Anyone with the token can control the proxied daemon.
786
+ A daemon with AGENT_DEVICE_HTTP_AUTH_HOOK configured treats HTTP requests as remote: host-path install sources are rejected, uploaded artifacts remain supported, and Maestro runScript HTTP helpers allow only public network destinations. No-hook local HTTP and socket flows retain their local behavior.
766
787
  If local/proxy iOS reports that the runner is already owned by another agent-device daemon after lease admission, retry after the owning session closes or after lease expiry. If the conflict repeats, clean stale daemon state on the machine with simulator access.
767
788
  Do not use --config as a remote profile flag. --config loads CLI defaults; --remote-config selects remote daemon/profile settings.
768
789
  For self-contained scripts, pass the same --remote-config to every operational command, including disconnect; a preceding connect is optional but not required.
@@ -836,7 +857,7 @@ First-slice loop:
836
857
  agent-device close --platform web
837
858
 
838
859
  Supported in agent-device web sessions:
839
- open <url>, snapshot -i, get text/attrs, is visible/exists/text, find text/selector, click/press @ref or selector, hover @ref or selector, fill/type @ref or selector, wait text/selector, network dump, audio probe, screenshot, record start/stop with WebM output, close, and replay scripts made from those commands.
860
+ open <url>, snapshot -i, get text/attrs, is visible/hidden/exists/absent/focused/text, find text/selector, click/press @ref or selector, hover @ref or selector, fill/type @ref or selector, wait text/selector/absent, network dump, audio probe, screenshot, record start/stop with WebM output, close, and replay scripts made from those commands.
840
861
  hover moves the pointer without pressing so hover-gated UI (row toolbars, menus) appears; use --settle to read what it revealed, then act on the fresh refs. hover @ref hovers the browser element handle directly; pair --settle with a selector or coordinates (web refs carry no geometry, as with click @ref --settle). Web only: touch platforms have no hover state, so hover-gated flows there need a different entry point.
841
862
 
842
863
  Out of scope for agent-device web support:
@@ -899,7 +920,7 @@ Rules:
899
920
  Findings must come from observed runtime behavior, not source reads.
900
921
  After each mutation, use the --settle diff as evidence when available; otherwise re-snapshot.
901
922
  Wait timeouts are integer milliseconds in the trailing positional: agent-device wait 'role=tab' 10000. Do not write duration suffixes such as 10s.
902
- scroll takes direction then amount and does not support a selector or --settle: agent-device scroll down 3.
923
+ scroll takes a selector-less direction+amount form: agent-device scroll down 0.8. One gesture cannot travel further than 0.8 of the viewport axis, so a larger amount saturates rather than covering more ground; to cross several screens use agent-device scroll down --until <selector> or scroll bottom. Use --settle to wait for the UI to go quiet and get the settled diff.
903
924
  Keep commands in the report reproducible; use selectors or refs from fresh snapshots, not guessed coordinates.
904
925
  Prefer refs for exploration and selectors for deterministic replay.
905
926
  Use logs, network, screenshot --overlay-refs, trace, perf frames, perf memory, native profiles, or react-devtools only when they add evidence to a specific issue.
@@ -938,31 +959,33 @@ Evidence:
938
959
 
939
960
  Report:
940
961
  Summarize what changed, exact validation commands, pass/fail observations, artifact paths, and residual risk.
941
- If live validation is blocked, state the blocker, device/session, and exact next command needed.`}};function S(e,t,n){let r=n.endsWith(`?`),i=r?n.slice(0,-1):n,a=/^[a-z-]+(?:\|[a-z-]+)+$/i.test(i),o=a||t.usageOverride!==void 0&&t.usageOverride.startsWith(`${e} ${i}`);return r?a?`[${i}]`:o?i:`[${i}]`:o?i:`<${i}>`}function C(e,t){return t.listUsageOverride?t.listUsageOverride:[e,...(t.positionalArgs??[]).map(n=>S(e,t,n))].join(` `)}function w(){return h()}function T(){return`agent-device help commands
962
+ If live validation is blocked, state the blocker, device/session, and exact next command needed.`}};function E(e,t,n){let r=n.endsWith(`?`),i=r?n.slice(0,-1):n,a=/^[a-z-]+(?:\|[a-z-]+)+$/i.test(i),o=a||t.usageOverride!==void 0&&t.usageOverride.startsWith(`${e} ${i}`);return r?a?`[${i}]`:o?i:`[${i}]`:o?i:`<${i}>`}function D(e,t){return t.listUsageOverride?t.listUsageOverride:[e,...(t.positionalArgs??[]).map(n=>E(e,t,n))].join(` `)}function O(){return y()}function k(){return`agent-device help commands
942
963
 
943
964
  Full command catalog. Use agent-device help <command> for exact flags and behavior.
944
965
 
945
- ${M(n().map(e=>{let t=c(e);return{name:e,schema:t,usage:C(e,t)}}))}
966
+ ${I(o().map(e=>{let t=l(e);return{name:e,schema:t,usage:D(e,t)}}))}
967
+
968
+ ${N(`Device Selection (shared by device commands; help <command> lists each command's flags):`,j(n))}
946
969
 
947
- ${k(`Global Flags:`,D(i))}
970
+ ${N(`Global Flags:`,j(r))}
948
971
 
949
- ${j(`Configuration:`,_)}
972
+ ${F(`Configuration:`,x)}
950
973
 
951
- ${A(`Environment:`,v)}
974
+ ${P(`Environment:`,S)}
952
975
 
953
- ${j(`Examples:`,y)}
954
- `}function E(){return w()}function D(e){return r().filter(t=>e.has(t.key)&&t.usageLabel!==void 0&&t.usageDescription!==void 0)}function O(e,t){return t?e.map(e=>{let n=t[e.key];return n===void 0?e:{...e,usageDescription:n}}):e}function k(e,t){return A(e,t.map(e=>({label:e.usageLabel??``,description:e.usageDescription??``})))}function A(e,t){if(t.length===0)return`${e}\n (none)`;let n=Math.max(...t.map(e=>Math.min(e.label.length,26)))+2,r=[e];for(let e of t){let t=e.label.length<=26?e.label.padEnd(n):`${e.label} `;r.push(` ${t}${e.description}`)}return r.join(`
955
- `)}function j(e,t){return t.length===0?`${e}\n (none)`:[e,...t.map(e=>` ${e}`)].join(`
956
- `)}function M(e){return A(`Commands:`,e.map(e=>({label:e.usage,description:e.schema.text.summary})))}function N(e){let t=F(e);if(t)return t;let n=s(e);if(!n)return null;let r=m(e,n),i=O(D(new Set(n.allowedFlags??[])),n.flagDescriptionOverrides),o=[];i.length>0&&o.push(k(`Command flags:`,i));let c=o.length>0?`\n\n${o.join(`
976
+ ${F(`Examples:`,C)}
977
+ `}function A(){return O()}function j(e){return t().filter(t=>e.has(t.key)&&t.usageLabel!==void 0&&t.usageDescription!==void 0)}function M(e,t){return t?e.map(e=>{let n=t[e.key];return n===void 0?e:{...e,usageDescription:n}}):e}function N(e,t){return P(e,t.map(e=>({label:e.usageLabel??``,description:e.usageDescription??``})))}function P(e,t){if(t.length===0)return`${e}\n (none)`;let n=Math.max(...t.map(e=>Math.min(e.label.length,26)))+2,r=[e];for(let e of t){let t=e.label.length<=26?e.label.padEnd(n):`${e.label} `;r.push(` ${t}${e.description}`)}return r.join(`
978
+ `)}function F(e,t){return t.length===0?`${e}\n (none)`:[e,...t.map(e=>` ${e}`)].join(`
979
+ `)}function I(e){return P(`Commands:`,e.map(e=>({label:e.usage,description:e.schema.text.summary})))}function L(e){let t=B(e);if(t)return t;let n=c(e);if(!n)return null;let r=v(e,n),a=M(j(new Set(n.allowedFlags??[])),n.flagDescriptionOverrides),o=[];a.length>0&&o.push(N(`Command flags:`,a));let s=o.length>0?`\n\n${o.join(`
957
980
 
958
981
  `)}`:``;return`Usage:
959
982
  agent-device ${r}
960
983
 
961
- ${a(n.text)}${c}
962
- `}function P(){return Object.keys(x)}function F(e){let t=x[e];return t?`${I(e,e===`commands`?T():t.body)}
984
+ ${i(n.text)}${s}
985
+ `}function R(e){return L(u(e))}function z(){return Object.keys(T)}function B(e){let t=T[e];return t?`${V(e,e===`commands`?k():t.body)}
963
986
 
964
987
  Related:
965
988
  agent-device help <command> command-specific flags
966
989
  agent-device help manual-qa routine QA loop
967
990
  agent-device help workflow full automation reference
968
- `:null}function I(e,t){let n=`agent-device help ${e}`;return t.startsWith(n)?`agent-device ${o()} — ${e}${t.slice(n.length)}`:t}export{P as i,E as n,g as r,N as t};
991
+ `:null}function V(e,t){let n=`agent-device help ${e}`;return t.startsWith(n)?`agent-device ${s()} — ${e}${t.slice(n.length)}`:t}export{R as i,b as n,z as r,A as t};
@@ -1 +1 @@
1
- import{t as e}from"./registry.js";const t=e();function n(e){return t[e.name]?.({input:e.input??{},result:e.result})}export{n as t};
1
+ import{t as e}from"./registry.js";const t=e();async function n(e){return await t[e.name]?.({input:e.input??{},result:e.result,progress:e.progress})}export{n as t};
@@ -1 +1 @@
1
- import{t as e}from"./cli-output.js";import{t}from"./cli-grammar.js";import{n}from"./command-surface.js";async function r(e){return(await i(e)).result}async function i(r){let i=t(r.command,r.positionals,r.flags),a=await n(r.client,r.command,i);return{result:a,cliOutput:e({name:r.command,input:i,result:a})}}export{i as n,r as t};
1
+ import{l as e,n as t}from"./registry.js";import{t as n}from"./cli-output.js";import{n as r}from"./command-surface.js";const i=t();function a(t,n,r){let a=i[t];if(!a)throw Error(`Missing CLI reader for command: ${t}`);return{...a(n,r),...e(t,r)}}async function o(e){return(await s(e)).result}async function s(e){let t=a(e.command,e.positionals,e.flags),i=await r(e.client,e.command,t);return{result:i,cliOutput:await n({name:e.command,input:t,result:i,progress:e.commandProgress})}}export{s as n,o as t};