agent-device 0.20.9 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/README.md +2 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.apk → agent-device-android-ime-helper-0.21.0.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.manifest.json → agent-device-android-ime-helper-0.21.0.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.manifest.json → agent-device-android-snapshot-helper-0.21.0.manifest.json} +6 -6
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +35 -33
  9. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +6 -1
  10. package/apple/snapshot-bridge/LICENSE.idb +23 -0
  11. package/apple/snapshot-bridge/README.md +49 -0
  12. package/apple/snapshot-bridge/SnapshotBridge.m +280 -0
  13. package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +33 -0
  14. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +382 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +2 -2
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +21 -12
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -88
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +110 -107
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +6 -14
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +85 -114
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -6
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +72 -175
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +10 -11
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +78 -64
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +17 -9
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +47 -13
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +232 -438
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +98 -0
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +229 -168
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +110 -0
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +147 -25
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +21 -18
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +24 -307
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +19 -0
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +49 -16
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +2 -11
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +4 -19
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -20
  51. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
  52. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +42 -81
  53. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +35 -82
  54. package/dist/apple/snapshot-presentation/Package.swift +21 -0
  55. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
  56. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
  57. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
  58. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
  59. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
  60. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
  61. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
  62. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
  63. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
  64. package/dist/src/adapter.js +1 -0
  65. package/dist/src/adb-executor.js +2 -0
  66. package/dist/src/adb-failure.js +1 -0
  67. package/dist/src/adb-host.js +1 -0
  68. package/dist/src/adb.js +1 -0
  69. package/dist/src/agent-browser-lifecycle.js +1 -0
  70. package/dist/src/agent-browser-process-record.js +1 -0
  71. package/dist/src/agent-browser-provider.js +1 -0
  72. package/dist/src/agent-browser-tool.js +1 -1
  73. package/dist/src/agent-device-client.js +2 -2
  74. package/dist/src/ai-sdk.d.ts +61 -0
  75. package/dist/src/ai-sdk.js +1 -0
  76. package/dist/src/alert-contract.js +1 -0
  77. package/dist/src/alert-runtime.js +1 -0
  78. package/dist/src/android-adb.d.ts +27 -19
  79. package/dist/src/android-adb.js +1 -1
  80. package/dist/src/android-input-ownership.js +1 -0
  81. package/dist/src/android-system-chrome.js +1 -0
  82. package/dist/src/android.js +1 -1
  83. package/dist/src/api.js +11 -0
  84. package/dist/src/app-catalog.js +1 -0
  85. package/dist/src/app-deployment-resolution.js +2 -0
  86. package/dist/src/app-helpers.js +1 -1
  87. package/dist/src/app-inventory-contract.js +1 -0
  88. package/dist/src/app-inventory.js +1 -0
  89. package/dist/src/app-launch.js +2 -0
  90. package/dist/src/app-lifecycle-facade.js +1 -0
  91. package/dist/src/app-lifecycle.js +3 -6
  92. package/dist/src/app-lifecycle2.js +2 -2
  93. package/dist/src/app-lifecycle3.js +1 -0
  94. package/dist/src/app-log-files.js +1 -1
  95. package/dist/src/app-log-reconnect.js +1 -1
  96. package/dist/src/app-log-runtime.js +1 -4
  97. package/dist/src/app-log-runtime2.js +4 -0
  98. package/dist/src/app-parsers.js +4 -0
  99. package/dist/src/app-resolution-cache.js +1 -0
  100. package/dist/src/app-resolution-facade.js +1 -0
  101. package/dist/src/app-resolution.js +2 -2
  102. package/dist/src/app-state.js +1 -2
  103. package/dist/src/application-lifecycle-interaction.js +1 -0
  104. package/dist/src/application-lifecycle-runtime.js +1 -0
  105. package/dist/src/apps-simctl.js +1 -0
  106. package/dist/src/archive.js +4 -0
  107. package/dist/src/artifact-download.js +1 -0
  108. package/dist/src/artifacts.d.ts +6 -2
  109. package/dist/src/artifacts.js +1 -1
  110. package/dist/src/async-lifecycle.js +1 -0
  111. package/dist/src/audio-probe-result.js +1 -0
  112. package/dist/src/audio-probe-runtime.js +1 -0
  113. package/dist/src/audio-probe-support.js +1 -0
  114. package/dist/src/auth-session.js +1 -1
  115. package/dist/src/auth.js +1 -1
  116. package/dist/src/back-mode.js +1 -0
  117. package/dist/src/{url.js → base-url.js} +1 -1
  118. package/dist/src/boot-diagnostics.js +2 -2
  119. package/dist/src/byte-limit-stream.js +1 -1
  120. package/dist/src/capabilities.js +1 -0
  121. package/dist/src/capture.js +1 -0
  122. package/dist/src/catalog.js +1 -0
  123. package/dist/src/cli-command-aliases.js +1 -0
  124. package/dist/src/cli-config.js +1 -1
  125. package/dist/src/cli-help.js +77 -51
  126. package/dist/src/cli-output.js +1 -1
  127. package/dist/src/cli-runner.js +1 -1
  128. package/dist/src/cli.js +5 -7
  129. package/dist/src/click-button.js +1 -0
  130. package/dist/src/client-metro-companion.js +1 -0
  131. package/dist/src/client-metro.js +1 -1
  132. package/dist/src/client-types.d.ts +1606 -0
  133. package/dist/src/clipboard.js +1 -0
  134. package/dist/src/code-signature-cache.js +1 -0
  135. package/dist/src/code-signature.js +1 -0
  136. package/dist/src/color.js +1 -0
  137. package/dist/src/command-metadata.js +1 -1
  138. package/dist/src/command-schema.js +3 -3
  139. package/dist/src/command-surface.js +1 -1
  140. package/dist/src/command-tools.js +2 -0
  141. package/dist/src/command.js +1 -0
  142. package/dist/src/{selector-vocabulary.js → compatibility-policy.js} +1 -1
  143. package/dist/src/config.js +1 -1
  144. package/dist/src/config2.js +1 -0
  145. package/dist/src/connection-runtime.js +1 -1
  146. package/dist/src/connection.js +5 -5
  147. package/dist/src/contracts.d.ts +1 -1
  148. package/dist/src/contracts.js +1 -1
  149. package/dist/src/daemon-client-lifecycle.js +1 -0
  150. package/dist/src/daemon-process.js +1 -0
  151. package/dist/src/daemon-registration.js +1 -0
  152. package/dist/src/daemon-shutdown-report.js +1 -1
  153. package/dist/src/daemon.js +2 -2
  154. package/dist/src/debug-symbols-facade.js +5 -0
  155. package/dist/src/deploy-result-target.js +1 -0
  156. package/dist/src/device-claim-inspection.js +1 -1
  157. package/dist/src/device-claim-rule.js +1 -0
  158. package/dist/src/device-input-state.d.ts +190 -3
  159. package/dist/src/device-inventory-context.js +1 -0
  160. package/dist/src/device-isolation.js +1 -0
  161. package/dist/src/device-release.js +1 -0
  162. package/dist/src/device-rotation.js +1 -0
  163. package/dist/src/device-selection-resolver.js +1 -0
  164. package/dist/src/device-session.js +1 -0
  165. package/dist/src/device.js +1 -1
  166. package/dist/src/device2.js +3 -2
  167. package/dist/src/diagnostics.js +3 -0
  168. package/dist/src/diagnostics2.js +1 -0
  169. package/dist/src/dispatch-resolve.js +1 -0
  170. package/dist/src/doctor-facade.js +1 -0
  171. package/dist/src/doctor-output.js +1 -0
  172. package/dist/src/doctor.js +1 -0
  173. package/dist/src/doctor2.js +1 -0
  174. package/dist/src/doctor3.js +1 -0
  175. package/dist/src/durable-resource.js +1 -0
  176. package/dist/src/entities.js +1 -1
  177. package/dist/src/error.js +2 -0
  178. package/dist/src/exec.js +1 -0
  179. package/dist/src/file.js +1 -0
  180. package/dist/src/find.js +1 -1
  181. package/dist/src/finders.js +1 -1
  182. package/dist/src/format.js +2 -0
  183. package/dist/src/generic-settle.js +1 -1
  184. package/dist/src/generic.js +1 -1
  185. package/dist/src/gesture-admission.js +1 -0
  186. package/dist/src/gesture-plan-types.js +1 -0
  187. package/dist/src/gesture-plan.js +1 -0
  188. package/dist/src/gesture-runtime.js +1 -0
  189. package/dist/src/harmonyos.js +1 -1
  190. package/dist/src/hdc.js +1 -1
  191. package/dist/src/helper.js +2 -2
  192. package/dist/src/host-file.js +1 -0
  193. package/dist/src/human-control-contract.js +1 -0
  194. package/dist/src/human-control.js +1 -0
  195. package/dist/src/index.d.ts +2 -1578
  196. package/dist/src/index.js +1 -1
  197. package/dist/src/input-actions.js +1 -4
  198. package/dist/src/input-actions2.js +2 -1
  199. package/dist/src/install-artifact-facade.js +1 -0
  200. package/dist/src/install-source-network-transport.js +1 -0
  201. package/dist/src/install-source.d.ts +3 -10
  202. package/dist/src/install-source2.js +1 -1
  203. package/dist/src/interaction-positionals.js +1 -0
  204. package/dist/src/interaction-ref-policy.js +1 -0
  205. package/dist/src/interaction.js +1 -1
  206. package/dist/src/interaction2.js +1 -1
  207. package/dist/src/interactor-operation-catalog.js +1 -0
  208. package/dist/src/interactor-types.js +1 -0
  209. package/dist/src/interactor.js +6 -2
  210. package/dist/src/interactor2.js +1 -1
  211. package/dist/src/interactors.js +1 -1
  212. package/dist/src/internal/bin.d.ts +1 -1
  213. package/dist/src/internal/bin.js +1 -2
  214. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  215. package/dist/src/internal/companion-tunnel.js +1 -1
  216. package/dist/src/internal/daemon.d.ts +1 -1
  217. package/dist/src/internal/daemon.js +2 -4
  218. package/dist/src/internal/png-worker.d.ts +4 -4
  219. package/dist/src/internal/png-worker.js +1 -1
  220. package/dist/src/internal/run-script-http-child.d.ts +4 -0
  221. package/dist/src/internal/run-script-http-child.js +1 -0
  222. package/dist/src/internal/update-check-entry.d.ts +1 -1
  223. package/dist/src/inventory.js +4 -4
  224. package/dist/src/inventory2.js +1 -1
  225. package/dist/src/inventory3.js +1 -1
  226. package/dist/src/inventory5.js +1 -1
  227. package/dist/src/inventory6.js +1 -1
  228. package/dist/src/ios-client.js +16 -0
  229. package/dist/src/ios-snapshot-acquisition.js +1 -0
  230. package/dist/src/ios-snapshot-adapter.js +1 -0
  231. package/dist/src/ios-snapshot-planning.js +1 -0
  232. package/dist/src/ios-snapshot-runtime.js +1 -0
  233. package/dist/src/json.js +1 -0
  234. package/dist/src/keyboard-actions.js +1 -0
  235. package/dist/src/launch-console.js +1 -0
  236. package/dist/src/lease-context.js +1 -1
  237. package/dist/src/lease-scope.js +1 -0
  238. package/dist/src/lease.js +1 -1
  239. package/dist/src/limrun-runtime-dependencies.js +1 -1
  240. package/dist/src/limrun.d.ts +1618 -7
  241. package/dist/src/limrun.js +1 -1
  242. package/dist/src/linux.js +1 -1
  243. package/dist/src/local-interactor-operation-set.js +1 -0
  244. package/dist/src/location-coordinates.js +1 -1
  245. package/dist/src/logcat.js +1 -1
  246. package/dist/src/macos-facade.js +1 -0
  247. package/dist/src/managed-device-scope.js +1 -0
  248. package/dist/src/mechanics.js +19 -0
  249. package/dist/src/metro.d.ts +4 -2
  250. package/dist/src/metro.js +1 -1
  251. package/dist/src/metro2.js +1 -1
  252. package/dist/src/mobile-snapshot-semantics.js +1 -0
  253. package/dist/src/multitouch-support.js +1 -0
  254. package/dist/src/numeric.js +1 -0
  255. package/dist/src/observability.js +1 -1
  256. package/dist/src/observation.js +2 -0
  257. package/dist/src/output-path.js +1 -1
  258. package/dist/src/owner-identity.js +3 -1
  259. package/dist/src/parameterized-recorded-fill.js +1 -0
  260. package/dist/src/parser.js +1 -1
  261. package/dist/src/perf-facade.js +2 -0
  262. package/dist/src/perf-runtime-operation-builder.js +1 -0
  263. package/dist/src/perf-runtime-plan.js +1 -0
  264. package/dist/src/perf-runtime.js +1 -0
  265. package/dist/src/perf.js +1 -4
  266. package/dist/src/physical-device-control.js +1 -1
  267. package/dist/src/physical-device-facade.js +1 -0
  268. package/dist/src/platform-request-scope.js +1 -0
  269. package/dist/src/platform-runtime-android-adb-host.js +1 -0
  270. package/dist/src/platform-runtime-android-mechanics.js +1 -0
  271. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  272. package/dist/src/platform-runtime-app-log-process.js +1 -1
  273. package/dist/src/platform-runtime-apple-resources.js +1 -0
  274. package/dist/src/platform-runtime-host.js +1 -1
  275. package/dist/src/platform-runtime-managed-owner.js +1 -0
  276. package/dist/src/platform-runtime-network-web-transport.js +1 -1
  277. package/dist/src/platform-runtime-open-target.js +1 -1
  278. package/dist/src/platform-runtime-operation-host.js +4 -4
  279. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  280. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  281. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
  282. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
  283. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  284. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
  285. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  286. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  287. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
  288. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
  289. package/dist/src/platform-runtime-unavailable.js +1 -0
  290. package/dist/src/platform-runtime.js +1 -1
  291. package/dist/src/platform-runtime2.js +1 -1
  292. package/dist/src/plist.js +1 -1
  293. package/dist/src/png-worker-contract.js +1 -1
  294. package/dist/src/prepare-kind.js +1 -15
  295. package/dist/src/process-exit.js +1 -1
  296. package/dist/src/process.js +1 -0
  297. package/dist/src/provider-device-runtime.js +1 -0
  298. package/dist/src/provider-session-ownership.js +2 -0
  299. package/dist/src/provider-webdriver.js +1 -1
  300. package/dist/src/provider.js +1 -1
  301. package/dist/src/providers.js +1 -0
  302. package/dist/src/proxy.js +2 -2
  303. package/dist/src/react-native-overlay.js +1 -0
  304. package/dist/src/react-native.js +1 -1
  305. package/dist/src/record-runtime.js +1 -1
  306. package/dist/src/record-trace.js +1 -1
  307. package/dist/src/rect-center.js +1 -0
  308. package/dist/src/register-builtins.js +1 -0
  309. package/dist/src/registry.js +39 -28
  310. package/dist/src/remote-config2.js +1 -1
  311. package/dist/src/replay-divergence.js +2 -0
  312. package/dist/src/replay.js +2 -2
  313. package/dist/src/reporting.js +8 -8
  314. package/dist/src/request-admission.js +1 -0
  315. package/dist/src/request-cancel.js +1 -0
  316. package/dist/src/request-cancellation.js +1 -0
  317. package/dist/src/request-progress-protocol.js +1 -0
  318. package/dist/src/request-providers.js +1 -0
  319. package/dist/src/request-runtime-binding.js +1 -0
  320. package/dist/src/request.js +1 -0
  321. package/dist/src/result-serialization.js +1 -0
  322. package/dist/src/retry.js +1 -0
  323. package/dist/src/rolldown-runtime.js +1 -1
  324. package/dist/src/runner-cache-metadata.js +2 -0
  325. package/dist/src/runner-client.js +1 -1
  326. package/dist/src/runner-disposal.js +1 -1
  327. package/dist/src/runner-operations-facade.js +1 -0
  328. package/dist/src/runner-owner-facade.js +1 -0
  329. package/dist/src/runner-owner-state.js +1 -0
  330. package/dist/src/runner-presentation.js +1 -0
  331. package/dist/src/runner-selector-query.js +1 -0
  332. package/dist/src/runner.js +1 -0
  333. package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
  334. package/dist/src/runtime.js +3 -3
  335. package/dist/src/runtime2.js +4 -4
  336. package/dist/src/runtime3.js +1 -1
  337. package/dist/src/runtime4.js +4 -3
  338. package/dist/src/runtime5.js +1 -1
  339. package/dist/src/runtime6.js +1 -1
  340. package/dist/src/runtime7.js +1 -1
  341. package/dist/src/runtime8.js +1 -1
  342. package/dist/src/runtime9.js +1 -1
  343. package/dist/src/scoped-provider.js +1 -1
  344. package/dist/src/screen-recording-completion.js +1 -0
  345. package/dist/src/screen-recording-live-handle.js +1 -0
  346. package/dist/src/screen-recording-options.js +1 -0
  347. package/dist/src/screen-recording-resource-recovery.js +1 -0
  348. package/dist/src/screen-recording-runtime.js +1 -0
  349. package/dist/src/screenshot-density.js +1 -1
  350. package/dist/src/screenshot-result.js +1 -6
  351. package/dist/src/screenshot-runtime.js +1 -0
  352. package/dist/src/screenshot.js +1 -1
  353. package/dist/src/screenshot2.js +1 -0
  354. package/dist/src/screenshot3.js +5 -0
  355. package/dist/src/script.js +1 -0
  356. package/dist/src/scroll-command.js +1 -0
  357. package/dist/src/scroll-gesture.js +1 -0
  358. package/dist/src/scroll-indicator.js +1 -0
  359. package/dist/src/sdk-batch-runner.d.ts +23 -6
  360. package/dist/src/sdk-batch-runner.js +2 -3
  361. package/dist/src/sdk-batch.js +2 -0
  362. package/dist/src/sdk-contracts.d.ts +222 -99
  363. package/dist/src/sdk-contracts.js +2 -2
  364. package/dist/src/sdk-device.js +1 -1
  365. package/dist/src/sdk-finders.d.ts +1 -1
  366. package/dist/src/sdk-finders.js +1 -1
  367. package/dist/src/sdk-io.js +1 -1
  368. package/dist/src/sdk-remote-config.d.ts +1 -1
  369. package/dist/src/sdk-remote-config.js +1 -1
  370. package/dist/src/sdk-selectors.d.ts +539 -199
  371. package/dist/src/sdk-selectors.js +1 -1
  372. package/dist/src/selection.js +1 -0
  373. package/dist/src/selector-runtime.js +1 -1
  374. package/dist/src/selectors.js +1 -1
  375. package/dist/src/semantic-index.js +1 -0
  376. package/dist/src/server.js +10 -3
  377. package/dist/src/session-allocation.js +1 -0
  378. package/dist/src/session-artifact-paths.js +1 -0
  379. package/dist/src/session-paths.js +1 -0
  380. package/dist/src/session-repair-tombstone.js +1 -0
  381. package/dist/src/session-routing.js +1 -0
  382. package/dist/src/session-runtime-admission.js +1 -0
  383. package/dist/src/session-snapshot.js +1 -0
  384. package/dist/src/session-store.js +4 -0
  385. package/dist/src/session-target-evidence.js +1 -1
  386. package/dist/src/session2.js +5 -28
  387. package/dist/src/settings.js +1 -0
  388. package/dist/src/shared.js +2 -2
  389. package/dist/src/simctl-facade.js +1 -0
  390. package/dist/src/simctl.js +1 -1
  391. package/dist/src/simulator-facade.js +1 -0
  392. package/dist/src/simulator.js +1 -1
  393. package/dist/src/snapshot-capture-annotations.js +1 -0
  394. package/dist/src/snapshot-desktop-projection.js +1 -0
  395. package/dist/src/snapshot-diagnostics.js +1 -0
  396. package/dist/src/snapshot-process.js +1 -0
  397. package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
  398. package/dist/src/snapshot-quality-verdict.js +1 -0
  399. package/dist/src/snapshot-runtime-binding.js +1 -0
  400. package/dist/src/snapshot-runtime.js +1 -1
  401. package/dist/src/snapshot-scope.js +1 -0
  402. package/dist/src/snapshot-state.js +1 -0
  403. package/dist/src/snapshot.js +1 -8
  404. package/dist/src/snapshot2.js +1 -1
  405. package/dist/src/snapshot3.js +1 -1
  406. package/dist/src/snapshot4.js +1 -0
  407. package/dist/src/src.js +1 -1
  408. package/dist/src/src2.js +1 -1
  409. package/dist/src/src3.js +1 -2
  410. package/dist/src/src4.js +1 -0
  411. package/dist/src/src5.js +1 -0
  412. package/dist/src/src6.js +1 -0
  413. package/dist/src/src7.js +2 -0
  414. package/dist/src/src8.js +115 -0
  415. package/dist/src/startup-recovery-fence.js +1 -0
  416. package/dist/src/status-markers.js +1 -0
  417. package/dist/src/string-enum.js +1 -1
  418. package/dist/src/success-text.js +1 -0
  419. package/dist/src/surface-snapshot.js +1 -0
  420. package/dist/src/surface-snapshot2.js +1 -0
  421. package/dist/src/takeover.js +5 -0
  422. package/dist/src/tool-provider-facade.js +1 -0
  423. package/dist/src/tool-provider.js +4 -3
  424. package/dist/src/tool-provider2.js +1 -1
  425. package/dist/src/tool-provider3.js +1 -0
  426. package/dist/src/toolchain-probe.js +2 -0
  427. package/dist/src/touch-runtime.js +1 -0
  428. package/dist/src/transport.js +3 -0
  429. package/dist/src/tree.js +1 -0
  430. package/dist/src/ttl-memo.js +1 -0
  431. package/dist/src/tv-remote.js +1 -0
  432. package/dist/src/type-text-runtime.js +1 -0
  433. package/dist/src/undici.js +99 -0
  434. package/dist/src/update-check.js +1 -1
  435. package/dist/src/verified-file.js +1 -1
  436. package/dist/src/version.js +1 -1
  437. package/dist/src/video.js +2 -2
  438. package/dist/src/web.js +2 -1
  439. package/dist/src/web2.js +1 -0
  440. package/dist/src/webdriver-ios-snapshot.js +1 -0
  441. package/dist/src/webdriver-source.js +1 -0
  442. package/linux/atspi-dump.py +54 -9
  443. package/package.json +73 -38
  444. package/server.json +9 -3
  445. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +0 -1
  446. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk +0 -0
  447. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +0 -1
  448. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
  449. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -75
  450. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
  451. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
  452. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
  453. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
  454. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
  455. package/dist/src/appearance.js +0 -1
  456. package/dist/src/apps.js +0 -5
  457. package/dist/src/audio-probe.js +0 -1
  458. package/dist/src/cancel.js +0 -1
  459. package/dist/src/cli-grammar.js +0 -1
  460. package/dist/src/command-catalog.js +0 -1
  461. package/dist/src/debug-symbols.js +0 -5
  462. package/dist/src/device-input-state.js +0 -2
  463. package/dist/src/device-ready.js +0 -1
  464. package/dist/src/dispatch.js +0 -1
  465. package/dist/src/handler-utils.js +0 -1
  466. package/dist/src/helper-package-install.js +0 -1
  467. package/dist/src/host-process.js +0 -3
  468. package/dist/src/ime-lifecycle.js +0 -2
  469. package/dist/src/ime-recovery-marker.js +0 -1
  470. package/dist/src/input-actions3.js +0 -1
  471. package/dist/src/install-artifact.js +0 -1
  472. package/dist/src/install-artifact2.js +0 -1
  473. package/dist/src/interaction-common.js +0 -1
  474. package/dist/src/interaction-runtime.js +0 -1
  475. package/dist/src/interaction-snapshot.js +0 -1
  476. package/dist/src/manifest.js +0 -1
  477. package/dist/src/method-scope.js +0 -1
  478. package/dist/src/png-resize.js +0 -1
  479. package/dist/src/process-lock.js +0 -1
  480. package/dist/src/runner-lease.js +0 -1
  481. package/dist/src/runner-sequence.js +0 -1
  482. package/dist/src/screenshot-geometry.js +0 -1
  483. package/dist/src/sdk-android-adb.d.ts +0 -245
  484. package/dist/src/sdk-android-adb.js +0 -4
  485. package/dist/src/sdk.js +0 -1
  486. package/dist/src/setting-state.js +0 -1
  487. package/dist/src/shell-quote.js +0 -1
  488. package/dist/src/snapshot-session.js +0 -1
  489. package/dist/src/timing-safe-equal.js +0 -1
  490. package/dist/src/unsupported-interactor.js +0 -1
  491. package/dist/src/verdict.js +0 -1
  492. /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n}from"./sdk-contracts.js";import{A as r}from"./sdk-android-adb.js";var i=e({Deadline:()=>s,isEnvTruthy:()=>a,retryWithPolicy:()=>c});function a(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const o={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var s=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 c(e,n={},r={}){let i={maxAttempts:n.maxAttempts??o.maxAttempts,baseDelayMs:n.baseDelayMs??o.baseDelayMs,maxDelayMs:n.maxDelayMs??o.maxDelayMs,jitter:n.jitter??o.jitter,shouldRetry:n.shouldRetry},a;for(let n=1;n<=i.maxAttempts;n+=1){if(r.signal?.aborted)throw new t(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});if(r.deadline?.isExpired()&&n>1)break;try{let t=await e({attempt:n,maxAttempts:i.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),d({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),t}catch(e){a=e;let t=r.classifyReason?.(e),o={phase:r.phase,event:`attempt_failed`,attempt:n,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};if(r.onEvent?.(o),d(o),n>=i.maxAttempts||i.shouldRetry&&!i.shouldRetry(e,n))break;let s=l(i.baseDelayMs,i.maxDelayMs,i.jitter,n),c=r.deadline?Math.min(s,r.deadline.remainingMs()):s;if(c<=0)break;let f={phase:r.phase,event:`retry_scheduled`,attempt:n,maxAttempts:i.maxAttempts,delayMs:c,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};r.onEvent?.(f),d(f),await u(c,r.signal)}}let s={phase:r.phase,event:`exhausted`,attempt:i.maxAttempts,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(a)};throw r.onEvent?.(s),d(s),a||new t(`COMMAND_FAILED`,`retry failed`)}function l(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 u(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 d(e){r({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}const f=new Set([`IOS_BOOT_TIMEOUT`,`IOS_RUNNER_CONNECT_TIMEOUT`,`IOS_TOOL_MISSING`,`ANDROID_BOOT_TIMEOUT`,`ADB_TRANSPORT_UNAVAILABLE`,`CI_RESOURCE_STARVATION_SUSPECTED`]);function p(e){return f.has(e.toUpperCase())}function m(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 h(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{a,s as i,m as n,c as o,p as r,i as s,h as t};
1
+ import{b 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{y 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=[`screenshotCropOn`,`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotScale`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],c=[{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`},{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)`},{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`},{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)`},{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`},{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`}],l=[{tokens:[`--fullscreen`,`--full`,`-f`],key:`screenshotFullscreen`},{tokens:[`--no-stabilize`],key:`screenshotNoStabilize`},{tokens:[`--normalize-status-bar`],key:`screenshotNormalizeStatusBar`}],u=[{token:`--pixel-density`,key:`screenshotPixelDensity`,label:`screenshot --pixel-density`}],d=[{token:`--scale`,key:`screenshotScale`,label:`screenshot --scale`,min:t.min,max:t.max}],f=[{token:`--crop-on`,key:`screenshotCropOn`,label:`screenshot --crop-on`}];function p(e){return y({overlayRefs:e?.overlayRefs,cropOn:e?.screenshotCropOn,pixelDensity:e?.screenshotPixelDensity,fullscreen:e?.screenshotFullscreen,scale:e?.screenshotScale,stabilize:!e?.screenshotNoStabilize&&void 0,normalizeStatusBar:e?.screenshotNormalizeStatusBar})}function m(e={}){return y({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 h(e={}){return m({...e,screenshotScale:e.screenshotScale??e.scale})}function g(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 _(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 v(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 b(o,i,a)??x({args:r,index:a,flags:i,token:o})??S({args:r,index:a,flags:i,token:o})??C({args:r,index:a,flags:i,token:o})??{handled:!1}}function y(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function b(e,t,n){let r=l.find(t=>t.tokens.some(t=>t===e));if(r)return t[r.key]=!0,{handled:!0,nextIndex:n}}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.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 S(t){let n=d.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 C(t){let n=f.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{t as a,v as c,h as d,p as f,a as i,r as l,g as m,s as n,c as o,i as p,o 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{D as o,T as s}from"./sdk-android-adb.js";import{n as c,t as l}from"./path-resolution.js";import{r as u}from"./command-schema.js";import d from"node:path";import f from"node:fs";function p(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}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 o(T(e),t,n,r)}function S(){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:!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){let t=e.env??process.env;return p(p({},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(l(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return c(e,{cwd:t,env:n})}function j(e){let t={};for(let n of e)p(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=v(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]=x(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 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{b as n,p as r,E as t};
1
+ import{y as e}from"./sdk-contracts.js";import{t}from"./capture.js";import{D as n,f as r,s as i}from"./registry.js";import{i as a}from"./catalog.js";import{a as o,s}from"./sdk-remote-config.js";import{n as c,t as l}from"./path-resolution.js";import"./file.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 s(w(e),t,n,r)}function x(){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 r)t.set(e,new Set([`*`]));for(let e of a()){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)?[]:[o(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(l(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return c(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 a={};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`){a.installSource=i(s,r.label);continue}a[n]=b(c,s,r.label,o)}return a}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,8 +1,8 @@
1
- import{Yn as e}from"./sdk-batch-runner.js";import{i as t}from"./command-catalog.js";import{S as n,d as r,m as i}from"./registry.js";import{n as a}from"./version.js";import{i as o,r as s}from"./command-schema.js";const c=[`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.`],l=[`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 u(){return[`Supported subset:`,...c.map(e=>` - ${e}`),``,`Boundaries:`,...l.map(e=>` - ${e}`)].join(`
2
- `)}function d(e){let t=e.endsWith(`?`),n=t?e.slice(0,-1):e;return t?`[${n}]`:`<${n}>`}function f(e){return n().filter(t=>t.key===e)}function p(e,t){if(t.usageOverride)return t.usageOverride;let n=(t.positionalArgs??[]).map(d),r=(t.allowedFlags??[]).flatMap(e=>f(e).map(e=>e.usageLabel??e.names[0])).map(e=>`[${e}]`);return[e,...n,...r].join(` `)}function m(){return`agent-device <command> [args] [--json]
1
+ import{r as e}from"./rolldown-runtime.js";import{D as t,d as n,f as r,v 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,t){if(t.usageOverride)return t.usageOverride;let n=(t.positionalArgs??[]).map(m),r=(t.allowedFlags??[]).flatMap(e=>h(e).map(e=>e.usageLabel??e.names[0])).map(e=>`[${e}]`);return[e,...n,...r].join(` `)}function _(){return`agent-device <command> [args] [--json]
3
3
 
4
4
  Automates iOS, Android, macOS, TV, and web apps for AI agents.
5
- All ${t().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:
@@ -14,23 +14,24 @@ Start:
14
14
 
15
15
  Loop:
16
16
  press|click|fill|longpress <target> ... --settle
17
+ hover <target> --settle (web only; reveals hover-gated UI)
17
18
  scroll <direction|top|bottom> [amount] --settle; back --settle
18
19
  acts, waits for quiet, and prints the UI diff. Continue from that diff.
19
20
  Run snapshot -i only when the diff lacks the next target or did not settle.
20
- 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>,
21
22
  is, get, or find. A bare screenshot is not verification.
22
23
  End with: agent-device close
23
24
 
24
25
  Targets:
25
26
  Copy refs exactly: @e12, @e12~s4. Keep @ and any ~sN pin; refs go stale
26
27
  after mutations. A literal @handle is label="@handle", not a bare ref.
27
- Prefer refs, then id/label/role selectors. Selector keys: ${e.join(` `)}.
28
+ Prefer refs, then id/label/role selectors. Selector keys: ${a.join(` `)}.
28
29
  Coordinates are last resort: after snapshot -i shows no semantic target, or a
29
30
  sparse/AX-unavailable warning says its refs and selectors are invalid.
30
31
  Then screenshot, press <x> <y>, and re-snapshot on the changed screen.
31
32
 
32
33
  Rules:
33
- --settle is only for press/click/fill/longpress/scroll/back; never open,
34
+ --settle is only for press/click/fill/longpress/hover/scroll/back; never open,
34
35
  snapshot, or close. type never accepts --settle.
35
36
  fill <target> <text> --settle replaces; type <text> appends after focus.
36
37
  Late network/debounce result: wait text "Expected", not snapshot polling.
@@ -48,14 +49,16 @@ Guides (agent-device help <topic>):
48
49
  manual-qa / dogfood / validate / debugging / scripting / gestures
49
50
  react-native / react-devtools / cdp / tv / web / macos / remote
50
51
  physical-device / ios-system-ui / maestro
51
- `}const h=[`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.`],g=[{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`}],_=[`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`],v=`Wait failure contract:
52
- Read the verdict from error.details.reason in --json, not the message text.
52
+ `}var v=e({buildCommandUsageText:()=>F,buildUsageText:()=>O,helpTopicIds:()=>L,resolveHelpTargetUsageText:()=>I});const y=[`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.`],b=[{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`}],x=[`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`],S=`Wait failure contract:
53
+ Read error.details.reason in --json, not the message text.
53
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.
54
57
  wait_capture_stalled: no readable capture finished before the deadline -- retriable.
55
58
  wait_deadline_exceeded: a later capture used the remaining budget after an earlier readable one.
56
59
  wait_landmark_identity_mismatch: a replay destination guard found the selector but not the recorded identity.
57
60
  wait_stable_timeout: wait stable never saw a stable UI -- not an absence verdict.
58
- `,y={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
+ `,C={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
59
62
 
60
63
  Use this when asked to follow a manual QA script, test case, checklist, acceptance flow, or user-provided instructions.
61
64
 
@@ -69,7 +72,7 @@ Loop:
69
72
  3. Run press/fill/click/longpress <ref-or-selector> --settle for each mutating step.
70
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.
71
74
  5. If --settle prints not settled, follow its hint before the next ref-based action.
72
- 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.
73
76
  7. Close the session when the script ends.
74
77
 
75
78
  Command shapes:
@@ -77,56 +80,56 @@ Command shapes:
77
80
  agent-device open https://example.com/deep-link
78
81
  agent-device snapshot -i
79
82
  agent-device press @e12 --settle
80
- agent-device press 'label="Follow"'
83
+ agent-device press 'label="Follow"' --settle
81
84
  agent-device fill @e13 "qa@example.com" --settle
82
85
  agent-device wait text "Order placed" 3000
86
+ agent-device wait absent 'label="Loading..."' 3000
83
87
  agent-device close
84
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.
85
89
 
86
90
  Targets:
87
- 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.
88
92
  For text fields, use fill <target> <text> --settle to replace the field value; use type only to append to an already-focused field.
89
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.
90
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.
91
95
 
92
96
  Recovery:
93
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.
94
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.
95
100
  Sparse or recovered accessibility snapshot: use screenshot as visual truth, leave the bad screen if needed, then retry snapshot -i.
96
101
  Non-hittable success hint: verify with the settled diff or snapshot; retarget by a better ref/selector if the UI did not change.
97
102
 
98
- ${v}`},maestro:{summary:`Supported Maestro YAML commands, grammar, and runtime boundaries`,body:`agent-device help maestro
103
+ ${S}`},maestro:{summary:`Supported Maestro YAML commands, grammar, and runtime boundaries`,body:`agent-device help maestro
99
104
 
100
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.
101
106
 
102
- ${u()}
107
+ ${p()}
103
108
 
104
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
105
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
106
111
 
107
- 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.
108
113
 
109
114
  Command shape:
110
- 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
111
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).
112
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.
113
- 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).
114
119
  Gestures: scroll/swipe for lists/flicks; gesture pan|fling|pinch|rotate|transform|drag for multi-touch. Shapes and platform quirks: help gestures.
115
120
 
116
121
  Bootstrap:
117
- agent-device devices --platform ios
118
- agent-device open MyApp --platform ios --device "iPhone 17 Pro"
119
- 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.
120
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.
121
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.
122
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.
123
126
 
124
127
  Snapshots and refs:
125
- 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.
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.
126
129
  Legend: @e12 [button] label="Add to cart" enabled hittable -> press @e12. [off-screen below] -> scroll down (a hint, not a ref).
127
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.
128
- 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.
129
- 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 list target: scroll down/up then snapshot -i. TV/D-pad focus: help tv.
130
133
 
131
134
  Selectors:
132
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.
@@ -135,7 +138,7 @@ Selectors:
135
138
 
136
139
  Text entry:
137
140
  fill replaces; type appends to an already-focused field: fill 'id="field-email"' "qa@example.com"; type "Handle with care" --delay-ms 80
138
- 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.
139
142
  Plain fill/type first; if an iOS debounced/search-as-you-type field drops characters, retry with --delay-ms before clipboard paste.
140
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.
141
144
  iOS paste-prompt limits and Android IME/handwriting capture quirks: help debugging.
@@ -144,8 +147,8 @@ Session ordering:
144
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.
145
148
 
146
149
  Read-only and waits:
147
- ${v}
148
- 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
+ ${S}
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>.
149
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.
150
153
 
151
154
  Navigation:
@@ -160,7 +163,7 @@ Validation and evidence:
160
163
 
161
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.
162
165
 
163
- 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.
164
167
 
165
168
  Escalate:
166
169
  help manual-qa scripted manual QA
@@ -179,13 +182,17 @@ Escalate:
179
182
 
180
183
  Use this for reusable .ad script authoring (save-script), scripted destination guards, secret-safe fills, batch multi-step JSON, replay divergence/repair, and evidence recording.
181
184
 
185
+ Script paths are the caller's:
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.
188
+
182
189
  Reusable open-to-destination scripts:
183
190
  Arm recording on the first open, perform the full journey, verify the destination with a selector-targeted wait, then publish without closing:
184
191
  agent-device open com.example.app --relaunch --save-script=screen-x.ad
185
192
  agent-device press 'id="continue"' --settle
186
193
  agent-device wait 'role="heading" label="Screen X"'
187
194
  agent-device session save-script
188
- 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.
189
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:
190
197
  export AD_VAR_PASSWORD='<secret>'
191
198
  agent-device fill 'id="password"' "$AD_VAR_PASSWORD" --record-as PASSWORD
@@ -198,7 +205,8 @@ Replay divergence and repair:
198
205
 
199
206
  Batch:
200
207
  agent-device batch --steps '[{"command":"open","input":{"app":"settings"}},{"command":"wait","input":{"kind":"duration","durationMs":100}}]'
201
- 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.
202
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):
203
211
  agent-device test ./e2e/maestro --maestro --device udid1,emulator-5554 --shard-all 2
204
212
 
@@ -356,6 +364,7 @@ Diagnostics and traces:
356
364
  Open output includes Session state; JSON also includes runnerLogPath and requestLogPath.
357
365
  For open timing under --debug, run open --debug --json and inspect requestLogPath for the open_timing event.
358
366
  Session requests/<request-id>.ndjson holds daemon request diagnostics; session runner.log holds Apple runner/xcodebuild output.
367
+ Against a remote daemon the Diagnostics Log path is always local: the failing request's record is fetched to <state-dir>/remote-diagnostics/, and if it cannot be fetched the line reads "unavailable" with the reason instead of a daemon-host path.
359
368
  daemon.log is global daemon lifecycle evidence, not the primary per-run log.
360
369
  Use trace for low-level session diagnostics around one repro:
361
370
  agent-device trace start ./traces/diagnostics.trace
@@ -377,9 +386,8 @@ Diagnostics and traces:
377
386
  agent-device perf trace stop --kind perfetto
378
387
  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.
379
388
  CPU reports return at most ten top functions in structured data and print five in default CLI output.
380
- 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.
381
- On Android, those deprecated aggregate forms retain the released dumpsys cpuinfo point sample for compatibility; new profiling workflows should use perf cpu profile.
382
- Startup duration belongs to the open command's startup result; read it there instead of using aggregate perf.
389
+ 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.
390
+ Startup duration belongs to the open command's startup result; read it there.
383
391
 
384
392
  Memory diagnostics:
385
393
  Use perf memory when the symptom is leak/growth/OOM suspicion and you need agent-readable evidence.
@@ -468,6 +476,11 @@ Example:
468
476
  agent-device react-devtools profile report @c5
469
477
  agent-device network dump --include headers
470
478
 
479
+ Device busy and ownership:
480
+ 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.
481
+ 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.
482
+ 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.
483
+
471
484
  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
472
485
 
473
486
  Use this when a React Native or Expo app exposes a CDP target through Metro and
@@ -601,7 +614,7 @@ For simulator/emulator flows, use help manual-qa for routine QA or help workflow
601
614
  Discovery:
602
615
  agent-device devices --platform ios
603
616
  agent-device devices --platform android
604
- Use --device <name-or-udid> only when multiple devices are present.
617
+ With multiple devices present, select one: --device <name>, or --udid <udid> (iOS) / --serial <serial> (Android) when names collide.
605
618
 
606
619
  iOS physical-device prerequisites:
607
620
  Xcode, xcrun xcdevice, and xcrun xctrace must be available from the selected Xcode.
@@ -628,7 +641,7 @@ Runner and daemon lifecycle (applies to simulators too):
628
641
  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.
629
642
  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.
630
643
  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.
631
- 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.
644
+ 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).
632
645
 
633
646
  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
634
647
 
@@ -672,9 +685,9 @@ Providers:
672
685
  After direct-provider connect:
673
686
  Read the printed Device, App, Next, and workflow-note lines. They are also available as verification/device/app/liveSession/nextSteps/notes in --json output.
674
687
  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.
675
- 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.
688
+ 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.
676
689
  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.
677
- 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.
690
+ 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.
678
691
 
679
692
  Device cloud interfaces:
680
693
  CLI is the canonical bootstrap path: connect limrun/browserstack/aws-device-farm, then use normal open/snapshot/click/close/artifacts/disconnect commands.
@@ -694,6 +707,13 @@ Direct proxy flow for a remote Mac/simulator:
694
707
  agent-device close
695
708
  agent-device disconnect
696
709
 
710
+ Human takeover of a leased remote device:
711
+ 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.
712
+ agent-device takeover --session remote-session
713
+ agent-device takeover status
714
+ agent-device takeover release <hold-id>
715
+ 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.
716
+
697
717
  Cloud profile flow:
698
718
  agent-device connect
699
719
  agent-device open com.example.app
@@ -724,7 +744,8 @@ Limrun direct-device flow:
724
744
  agent-device connect limrun --platform android
725
745
 
726
746
  Limrun creates remote iOS simulators and Android emulators only. Do not pass local device selectors such as --udid, --serial, or --device.
727
- agent-device open com.example.app
747
+ agent-device apps
748
+ agent-device open Example.apk
728
749
  agent-device snapshot -i
729
750
  agent-device close
730
751
  agent-device disconnect
@@ -758,6 +779,7 @@ Rules:
758
779
  disconnect releases local connection state; close releases the active session and device lease.
759
780
  A busy direct-proxy device error means another agent owns the device until it closes or its inactivity lease expires.
760
781
  Keep the proxy token secret. Anyone with the token can control the proxied daemon.
782
+ 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.
761
783
  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.
762
784
  Do not use --config as a remote profile flag. --config loads CLI defaults; --remote-config selects remote daemon/profile settings.
763
785
  For self-contained scripts, pass the same --remote-config to every operational command, including disconnect; a preceding connect is optional but not required.
@@ -818,6 +840,7 @@ First-slice loop:
818
840
  agent-device is visible 'label="Welcome"' --platform web
819
841
  agent-device find text "Welcome" exists --platform web
820
842
  agent-device click @e12 --platform web
843
+ agent-device hover @e14 --settle --platform web
821
844
  agent-device fill @e13 "qa@example.com" --platform web
822
845
  agent-device wait text "Welcome" 3000 --platform web
823
846
  agent-device record start ./artifacts/web-flow.webm --platform web
@@ -830,7 +853,8 @@ First-slice loop:
830
853
  agent-device close --platform web
831
854
 
832
855
  Supported in agent-device web sessions:
833
- open <url>, snapshot -i, get text/attrs, is visible/exists/text, find text/selector, click/press @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.
856
+ 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.
857
+ 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.
834
858
 
835
859
  Out of scope for agent-device web support:
836
860
  Browser runtime debugging, tabs/windows/devtools control, network routing/interception/HAR, storage/cookie management, arbitrary page scripting, downloads/uploads, multi-page orchestration, and agent-browser-specific diagnostics. Use agent-browser directly for those browser-specific workflows.
@@ -892,7 +916,7 @@ Rules:
892
916
  Findings must come from observed runtime behavior, not source reads.
893
917
  After each mutation, use the --settle diff as evidence when available; otherwise re-snapshot.
894
918
  Wait timeouts are integer milliseconds in the trailing positional: agent-device wait 'role=tab' 10000. Do not write duration suffixes such as 10s.
895
- scroll takes direction then amount and does not support a selector or --settle: agent-device scroll down 3.
919
+ scroll takes a selector-less direction+amount form: agent-device scroll down 3. Use --settle to wait for the UI to go quiet and get the settled diff.
896
920
  Keep commands in the report reproducible; use selectors or refs from fresh snapshots, not guessed coordinates.
897
921
  Prefer refs for exploration and selectors for deterministic replay.
898
922
  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.
@@ -931,31 +955,33 @@ Evidence:
931
955
 
932
956
  Report:
933
957
  Summarize what changed, exact validation commands, pass/fail observations, artifact paths, and residual risk.
934
- If live validation is blocked, state the blocker, device/session, and exact next command needed.`}};function b(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 x(e,t){return t.listUsageOverride?t.listUsageOverride:[e,...(t.positionalArgs??[]).map(n=>b(e,t,n))].join(` `)}function S(){return m()}function C(){return`agent-device help commands
958
+ If live validation is blocked, state the blocker, device/session, and exact next command needed.`}};function w(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 T(e,t){return t.listUsageOverride?t.listUsageOverride:[e,...(t.positionalArgs??[]).map(n=>w(e,t,n))].join(` `)}function E(){return _()}function D(){return`agent-device help commands
935
959
 
936
960
  Full command catalog. Use agent-device help <command> for exact flags and behavior.
937
961
 
938
- ${A(t().map(e=>{let t=s(e);return{name:e,schema:t,usage:x(e,t)}}))}
962
+ ${P(o().map(e=>{let t=l(e);return{name:e,schema:t,usage:T(e,t)}}))}
963
+
964
+ ${j(`Device Selection (shared by device commands; help <command> lists each command's flags):`,k(n))}
939
965
 
940
- ${D(`Global Flags:`,T(r))}
966
+ ${j(`Global Flags:`,k(r))}
941
967
 
942
- ${k(`Configuration:`,h)}
968
+ ${N(`Configuration:`,y)}
943
969
 
944
- ${O(`Environment:`,g)}
970
+ ${M(`Environment:`,b)}
945
971
 
946
- ${k(`Examples:`,_)}
947
- `}function w(){return S()}function T(e){return n().filter(t=>e.has(t.key)&&t.usageLabel!==void 0&&t.usageDescription!==void 0)}function E(e,t){return t?e.map(e=>{let n=t[e.key];return n===void 0?e:{...e,usageDescription:n}}):e}function D(e,t){return O(e,t.map(e=>({label:e.usageLabel??``,description:e.usageDescription??``})))}function O(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(`
948
- `)}function k(e,t){return t.length===0?`${e}\n (none)`:[e,...t.map(e=>` ${e}`)].join(`
949
- `)}function A(e){return O(`Commands:`,e.map(e=>({label:e.usage,description:e.schema.text.summary})))}function j(e){let t=M(e);if(t)return t;let n=o(e);if(!n)return null;let r=p(e,n),a=E(T(new Set(n.allowedFlags??[])),n.flagDescriptionOverrides),s=[];a.length>0&&s.push(D(`Command flags:`,a));let c=s.length>0?`\n\n${s.join(`
972
+ ${N(`Examples:`,x)}
973
+ `}function O(){return E()}function k(e){return t().filter(t=>e.has(t.key)&&t.usageLabel!==void 0&&t.usageDescription!==void 0)}function A(e,t){return t?e.map(e=>{let n=t[e.key];return n===void 0?e:{...e,usageDescription:n}}):e}function j(e,t){return M(e,t.map(e=>({label:e.usageLabel??``,description:e.usageDescription??``})))}function M(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(`
974
+ `)}function N(e,t){return t.length===0?`${e}\n (none)`:[e,...t.map(e=>` ${e}`)].join(`
975
+ `)}function P(e){return M(`Commands:`,e.map(e=>({label:e.usage,description:e.schema.text.summary})))}function F(e){let t=R(e);if(t)return t;let n=c(e);if(!n)return null;let r=g(e,n),a=A(k(new Set(n.allowedFlags??[])),n.flagDescriptionOverrides),o=[];a.length>0&&o.push(j(`Command flags:`,a));let s=o.length>0?`\n\n${o.join(`
950
976
 
951
977
  `)}`:``;return`Usage:
952
978
  agent-device ${r}
953
979
 
954
- ${i(n.text)}${c}
955
- `}function M(e){let t=y[e];return t?`${N(e,e===`commands`?C():t.body)}
980
+ ${i(n.text)}${s}
981
+ `}function I(e){return F(u(e))}function L(){return Object.keys(C)}function R(e){let t=C[e];return t?`${z(e,e===`commands`?D():t.body)}
956
982
 
957
983
  Related:
958
984
  agent-device help <command> command-specific flags
959
985
  agent-device help manual-qa routine QA loop
960
986
  agent-device help workflow full automation reference
961
- `:null}function N(e,t){let n=`agent-device help ${e}`;return t.startsWith(n)?`agent-device ${a()} — ${e}${t.slice(n.length)}`:t}export{j as buildCommandUsageText,w as buildUsageText};
987
+ `:null}function z(e,t){let n=`agent-device help ${e}`;return t.startsWith(n)?`agent-device ${s()} — ${e}${t.slice(n.length)}`:t}export{I as i,v as n,L as r,O 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-grammar.js";import{t}from"./cli-output.js";import{n}from"./command-surface.js";async function r(e){return(await i(e)).result}async function i(r){let i=e(r.command,r.positionals,r.flags),a=await n(r.client,r.command,i);return{result:a,cliOutput:t({name:r.command,input:i,result:a})}}export{i as n,r as t};
1
+ import{c 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};