agent-device 0.21.12 → 0.21.14

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 (317) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.12.apk → agent-device-android-ime-helper-0.21.14.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.14.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.12.manifest.json → agent-device-android-ime-helper-0.21.14.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.14.apk +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.14.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.12.manifest.json → agent-device-android-snapshot-helper-0.21.14.manifest.json} +6 -6
  7. package/apple/macos-helper/Package.swift +4 -0
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +3 -6
  9. package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/ScreenshotResponseTests.swift +15 -0
  10. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +47 -1
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +122 -42
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/Info.plist +23 -0
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +17 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAppScreenCapture.swift +21 -13
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +1 -162
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -9
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -56
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +0 -48
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -50
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +33 -586
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +40 -24
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +2 -3
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +0 -36
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +630 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +34 -2256
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -338
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -12
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+GestureExecution.swift +160 -0
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -24
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +0 -142
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +90 -39
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+MainThreadWork.swift +78 -106
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +23 -2
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +162 -113
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +0 -209
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +86 -10
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollDragExecution.swift +271 -0
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +1 -200
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +20 -227
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +78 -295
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +40 -27
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +0 -78
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +85 -581
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +106 -0
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +142 -0
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +49 -78
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +0 -44
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +73 -114
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +1 -12
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +11 -94
  51. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +2 -10
  52. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
  53. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +0 -35
  54. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +0 -31
  55. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +2 -18
  56. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +34 -52
  57. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -22
  58. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +135 -0
  59. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +22 -6
  60. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +140 -20
  61. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotCoordinateSpace.swift +16 -19
  62. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +21 -9
  63. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +59 -10
  64. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +12 -10
  65. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +13 -8
  66. package/dist/src/absence-observation-errors.js +1 -1
  67. package/dist/src/adapter.js +1 -1
  68. package/dist/src/adb-executor.js +1 -1
  69. package/dist/src/adb-failure.js +1 -1
  70. package/dist/src/adb-transport.js +1 -1
  71. package/dist/src/agent-browser-provider.js +1 -1
  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.js +1 -1
  75. package/dist/src/alert-runtime.js +1 -1
  76. package/dist/src/android-adb.d.ts +1 -1
  77. package/dist/src/app-catalog.js +1 -1
  78. package/dist/src/app-deployment-resolution.js +1 -1
  79. package/dist/src/app-inventory.js +1 -1
  80. package/dist/src/app-launch.js +2 -2
  81. package/dist/src/app-lifecycle.js +1 -1
  82. package/dist/src/app-lifecycle2.js +1 -1
  83. package/dist/src/app-log-files.js +1 -1
  84. package/dist/src/app-log-runtime2.js +3 -3
  85. package/dist/src/app-resolution.js +2 -2
  86. package/dist/src/apple-runner-platform.js +1 -1
  87. package/dist/src/application-lifecycle-interaction.js +1 -1
  88. package/dist/src/archive.js +1 -1
  89. package/dist/src/artifact-download.js +1 -1
  90. package/dist/src/auth-session.js +1 -1
  91. package/dist/src/auth.js +1 -1
  92. package/dist/src/back-mode.js +1 -1
  93. package/dist/src/backend-snapshot-options.js +1 -1
  94. package/dist/src/boot-diagnostics.js +1 -1
  95. package/dist/src/capture-disclosure.js +1 -1
  96. package/dist/src/capture.js +1 -1
  97. package/dist/src/cli-config.js +1 -1
  98. package/dist/src/cli-help.js +8 -7
  99. package/dist/src/cli-runner.js +1 -1
  100. package/dist/src/cli.js +4 -4
  101. package/dist/src/click-button.js +1 -1
  102. package/dist/src/client-metro.js +1 -1
  103. package/dist/src/client-types.d.ts +4 -5
  104. package/dist/src/clipboard-shell-response.js +1 -1
  105. package/dist/src/code-signature.js +1 -1
  106. package/dist/src/command-schema.js +3 -3
  107. package/dist/src/command-tools.js +3 -3
  108. package/dist/src/connection-runtime.js +1 -1
  109. package/dist/src/connection.js +1 -1
  110. package/dist/src/contracts.js +1 -1
  111. package/dist/src/daemon-client-lifecycle.js +1 -1
  112. package/dist/src/daemon-resolution.js +1 -1
  113. package/dist/src/daemon.js +1 -1
  114. package/dist/src/debug-symbols-facade.js +1 -1
  115. package/dist/src/device-claim-rule.js +2 -2
  116. package/dist/src/device-input-state.d.ts +1 -1
  117. package/dist/src/device-inventory-context.js +1 -1
  118. package/dist/src/device-rotation.js +1 -1
  119. package/dist/src/device-selection-resolver.js +1 -1
  120. package/dist/src/device-session.js +1 -1
  121. package/dist/src/device-shell.js +1 -1
  122. package/dist/src/device2.js +1 -1
  123. package/dist/src/devicectl.js +1 -1
  124. package/dist/src/diagnostics.js +1 -1
  125. package/dist/src/dispatch-resolve.js +1 -1
  126. package/dist/src/display-inventory.js +1 -1
  127. package/dist/src/doctor-facade.js +1 -1
  128. package/dist/src/doctor2.js +1 -1
  129. package/dist/src/engine-eval-script.js +1 -1
  130. package/dist/src/error.js +1 -1
  131. package/dist/src/exec.js +1 -1
  132. package/dist/src/file.js +1 -1
  133. package/dist/src/find.js +1 -1
  134. package/dist/src/format.js +1 -1
  135. package/dist/src/gesture-plan-types.d.ts +38 -0
  136. package/dist/src/gesture-plan.js +1 -1
  137. package/dist/src/gesture-runtime.js +1 -1
  138. package/dist/src/harmonyos.js +1 -1
  139. package/dist/src/helper.js +2 -2
  140. package/dist/src/host.js +1 -1
  141. package/dist/src/human-control-contract.js +1 -1
  142. package/dist/src/human-control.js +1 -1
  143. package/dist/src/index.js +1 -1
  144. package/dist/src/input-actions.js +1 -1
  145. package/dist/src/input-actions2.js +1 -1
  146. package/dist/src/install-artifact-facade.js +1 -1
  147. package/dist/src/install-source-network-transport.js +1 -1
  148. package/dist/src/install-source2.js +1 -1
  149. package/dist/src/interaction-positionals.js +1 -1
  150. package/dist/src/interaction-ref-policy.js +1 -1
  151. package/dist/src/interaction2.js +1 -1
  152. package/dist/src/interactor-operation-binding.js +1 -1
  153. package/dist/src/interactor-operation-catalog.js +1 -1
  154. package/dist/src/interactor.js +4 -4
  155. package/dist/src/interactor2.js +1 -1
  156. package/dist/src/interactors.js +1 -1
  157. package/dist/src/internal/bin.js +1 -1
  158. package/dist/src/internal/daemon.js +2 -2
  159. package/dist/src/internal/png-worker.js +1 -1
  160. package/dist/src/internal/run-script-http-child.js +1 -1
  161. package/dist/src/inventory.js +1 -1
  162. package/dist/src/inventory2.js +1 -1
  163. package/dist/src/inventory3.js +1 -1
  164. package/dist/src/inventory5.js +1 -1
  165. package/dist/src/ios-snapshot-acquisition.js +1 -1
  166. package/dist/src/ios-snapshot-runtime.js +1 -1
  167. package/dist/src/lease.js +1 -1
  168. package/dist/src/limrun-download-file.js +1 -1
  169. package/dist/src/limrun-runtime-dependencies.js +1 -1
  170. package/dist/src/limrun.d.ts +435 -4
  171. package/dist/src/linux.js +1 -1
  172. package/dist/src/local-interactor-operation-set.js +1 -1
  173. package/dist/src/location-coordinates.js +1 -1
  174. package/dist/src/managed-device-scope.js +1 -1
  175. package/dist/src/mechanics.js +5 -5
  176. package/dist/src/mobile-snapshot-semantics.js +1 -1
  177. package/dist/src/multitouch-support.js +1 -1
  178. package/dist/src/native-build-cache.js +1 -0
  179. package/dist/src/observation.js +1 -1
  180. package/dist/src/parameterized-recorded-fill.js +1 -1
  181. package/dist/src/perf-facade.js +1 -2
  182. package/dist/src/perf-runtime-operation-builder.js +1 -1
  183. package/dist/src/perf-runtime-plan.js +1 -1
  184. package/dist/src/perf-target.js +2 -0
  185. package/dist/src/perf.js +1 -1
  186. package/dist/src/physical-device-apps.js +1 -0
  187. package/dist/src/physical-device-control.js +1 -1
  188. package/dist/src/platform-request-scope.js +1 -1
  189. package/dist/src/platform-runtime-host.js +1 -1
  190. package/dist/src/platform-runtime-managed-owner.js +1 -1
  191. package/dist/src/platform-runtime-open-target.js +1 -1
  192. package/dist/src/platform-runtime-operation-host.js +2 -2
  193. package/dist/src/platform-runtime-runtime-hints.js +1 -1
  194. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  195. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  196. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
  197. package/dist/src/platform-runtime-unavailable.js +1 -1
  198. package/dist/src/platform-runtime.js +1 -1
  199. package/dist/src/platform-runtime2.js +1 -1
  200. package/dist/src/png-crop-bytes.js +1 -1
  201. package/dist/src/png-size.js +1 -1
  202. package/dist/src/png-worker-client.js +1 -1
  203. package/dist/src/png.js +1 -1
  204. package/dist/src/prepare-kind.js +1 -1
  205. package/dist/src/provider-session-ownership.js +1 -1
  206. package/dist/src/provider-webdriver.js +1 -1
  207. package/dist/src/proxy.js +1 -1
  208. package/dist/src/quality-warnings.js +1 -1
  209. package/dist/src/react-native.js +1 -1
  210. package/dist/src/record-runtime.js +1 -1
  211. package/dist/src/recording.js +1 -1
  212. package/dist/src/register-builtins.js +1 -1
  213. package/dist/src/registry.js +35 -35
  214. package/dist/src/remote-config2.js +1 -1
  215. package/dist/src/replay-divergence.js +1 -1
  216. package/dist/src/replay.js +1 -1
  217. package/dist/src/reporting.js +1 -1
  218. package/dist/src/request-admission.js +1 -1
  219. package/dist/src/request-cancel.js +1 -1
  220. package/dist/src/request-runtime-binding.js +1 -1
  221. package/dist/src/retry.js +1 -1
  222. package/dist/src/runner-cache-metadata.js +1 -1
  223. package/dist/src/runner-client.js +1 -1
  224. package/dist/src/runner-dev-tools-security.js +1 -1
  225. package/dist/src/runner-device-readiness.js +1 -1
  226. package/dist/src/runner-disposal.js +1 -1
  227. package/dist/src/runner-error-classification.js +3 -0
  228. package/dist/src/runner-operations-facade.js +1 -1
  229. package/dist/src/runner-presentation.js +1 -1
  230. package/dist/src/runner.js +1 -1
  231. package/dist/src/runtime-transport-hints.js +1 -1
  232. package/dist/src/runtime.js +3 -3
  233. package/dist/src/runtime10.js +2 -2
  234. package/dist/src/runtime2.js +2 -2
  235. package/dist/src/runtime3.js +1 -1
  236. package/dist/src/runtime4.js +4 -4
  237. package/dist/src/runtime5.js +1 -1
  238. package/dist/src/runtime6.js +1 -1
  239. package/dist/src/runtime7.js +1 -1
  240. package/dist/src/runtime8.js +1 -1
  241. package/dist/src/runtime9.js +1 -1
  242. package/dist/src/screen-recording-admission-ledger.js +1 -1
  243. package/dist/src/screen-recording-completion.js +1 -1
  244. package/dist/src/screen-recording-options.js +1 -1
  245. package/dist/src/screen-recording-resource-recovery.js +1 -1
  246. package/dist/src/screen-recording-transport.js +1 -1
  247. package/dist/src/screenshot-density.js +1 -1
  248. package/dist/src/screenshot-image.js +1 -1
  249. package/dist/src/screenshot-runtime.js +1 -1
  250. package/dist/src/screenshot.js +1 -1
  251. package/dist/src/screenshot3.js +1 -1
  252. package/dist/src/script.js +1 -1
  253. package/dist/src/scroll-command.d.ts +377 -0
  254. package/dist/src/scroll-command.js +1 -1
  255. package/dist/src/scroll-gesture.js +1 -1
  256. package/dist/src/sdk-batch-runner.js +2 -2
  257. package/dist/src/sdk-batch.js +2 -2
  258. package/dist/src/sdk-contracts.d.ts +28 -0
  259. package/dist/src/sdk-contracts.js +1 -1
  260. package/dist/src/sdk-device.js +1 -1
  261. package/dist/src/sdk-io.js +1 -1
  262. package/dist/src/sdk-remote-config.js +1 -1
  263. package/dist/src/sdk-selectors.d.ts +23 -726
  264. package/dist/src/selection.js +0 -0
  265. package/dist/src/selector-runtime.js +1 -1
  266. package/dist/src/semantic-index.js +1 -1
  267. package/dist/src/server.js +1 -1
  268. package/dist/src/session-allocation.js +1 -1
  269. package/dist/src/session-observation.js +1 -1
  270. package/dist/src/session-routing.js +1 -1
  271. package/dist/src/session-runtime-admission.js +1 -1
  272. package/dist/src/session-snapshot.js +1 -1
  273. package/dist/src/session-store.js +2 -2
  274. package/dist/src/session2.js +3 -3
  275. package/dist/src/settings.js +1 -1
  276. package/dist/src/simctl-facade.js +1 -1
  277. package/dist/src/simctl.js +1 -1
  278. package/dist/src/simulator-state.js +1 -1
  279. package/dist/src/simulator.js +1 -1
  280. package/dist/src/snapshot-runtime-binding.js +1 -1
  281. package/dist/src/snapshot-runtime.js +1 -1
  282. package/dist/src/snapshot-state.js +1 -1
  283. package/dist/src/snapshot2.js +1 -1
  284. package/dist/src/snapshot3.js +1 -1
  285. package/dist/src/snapshot4.js +1 -1
  286. package/dist/src/src.js +1 -1
  287. package/dist/src/src7.js +1 -1
  288. package/dist/src/src8.js +2 -2
  289. package/dist/src/string-enum.js +1 -1
  290. package/dist/src/takeover.js +1 -1
  291. package/dist/src/text-entry-focus.js +1 -1
  292. package/dist/src/tool-provider-facade.js +1 -1
  293. package/dist/src/tool-provider.js +2 -2
  294. package/dist/src/tool-provider2.js +1 -1
  295. package/dist/src/touch-runtime.js +1 -1
  296. package/dist/src/transport.js +1 -1
  297. package/dist/src/tree.js +1 -1
  298. package/dist/src/tv-remote.js +1 -1
  299. package/dist/src/type-text-runtime.js +1 -1
  300. package/dist/src/update-check.js +1 -1
  301. package/dist/src/verified-file.js +1 -1
  302. package/dist/src/version.js +1 -1
  303. package/dist/src/video.js +1 -1
  304. package/dist/src/viewport.js +1 -1
  305. package/dist/src/web.js +1 -1
  306. package/dist/src/web2.js +1 -1
  307. package/dist/src/webdriver-source.js +1 -1
  308. package/package.json +3 -2
  309. package/server.json +2 -2
  310. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.12.apk.sha256 +0 -1
  311. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.12.apk +0 -0
  312. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.12.apk.sha256 +0 -1
  313. package/dist/src/app-inventory.d.ts +0 -4
  314. package/dist/src/apps-simctl.js +0 -1
  315. package/dist/src/cloud-artifacts.d.ts +0 -61
  316. package/dist/src/runner-contract.js +0 -3
  317. package/dist/src/snapshot-process.js +0 -1
package/dist/src/proxy.js CHANGED
@@ -1,2 +1,2 @@
1
- import{D as e,L as t}from"./sdk-contracts.js";import{a as n,c as r,d as i,f as a,l as o,m as s,o as c,r as l,s as u,u as d}from"./transport.js";import{i as f,s as p}from"./daemon-client-lifecycle.js";import{r as m}from"./version.js";import{t as h}from"./shared.js";import{n as ee,t as te}from"./color.js";import{randomBytes as ne,randomUUID as g}from"node:crypto";import{Readable as _}from"node:stream";import{pipeline as v}from"node:stream/promises";import y from"node:http";function b(e){let t=S(e);if(!t)return!1;let n=T(t.meta);return C(n)?!1:w(t.source)||w(n?.installSource)}function x(n,r){let i=new e(`INVALID_ARGS`,`Invalid params: an install source of kind "path" names a file on the daemon host and is not accepted through the proxy`,{hint:`Upload the artifact, or use a "url" or "github-actions-artifact" source.`});n.statusCode=400,n.setHeader(`content-type`,`application/json`),n.end(JSON.stringify({jsonrpc:`2.0`,id:r,error:{code:-32602,message:i.message,data:t(i)}}))}function S(e){if(e)try{return T(T(JSON.parse(e))?.params)}catch{return}}function C(e){let t=e?.uploadedArtifactId;return typeof t==`string`&&t.trim().length>0}function w(e){return T(e)?.kind===`path`}function T(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}const E=`${c}/`,D=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`,o],O=[`content-type`,`content-disposition`,`x-request-id`];function k(e){let t=V(e);return y.createServer((e,n)=>{A(e,n,t).catch(e=>{de(n,e)})})}async function A(e,t,n){let r=W(e.url??`/`);if(e.method===`GET`&&r===`/health`){await j(t,n);return}if(!G(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await l(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!ae(e,n.clientToken,i)){ue(t,r,Z(i));return}if(b(i)){x(t,Z(i));return}await N({req:e,res:t,route:r,options:n,rpcBody:i})}async function j(e,t){let n=await M(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(d(`agent-device-proxy`,m(),{upstream:n})))}async function M(e){let t=new URL(s(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:X({headers:{}},e.upstreamToken,`/health`),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),r=await n.text();try{return r?JSON.parse(r):{ok:n.ok,status:n.status}}catch{return{ok:n.ok,status:n.status}}}async function N(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=Y(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=X(t,i.upstreamToken,r),l=ie(t,r,a,i.upstreamToken);await F({req:t,res:n,route:r,response:await i.fetchImpl(o,{method:s,headers:c,signal:P(t,n,i.upstreamTimeoutMs),...l?{body:l,duplex:`half`}:{}}),clientToken:i.clientToken})}function P(t,n,r){let i=new AbortController,a=()=>{n.writableFinished||i.signal.aborted||i.abort(new e(`COMMAND_FAILED`,`Proxy client disconnected before the upstream response ended`))};return t.on(`aborted`,a),n.on(`close`,a),AbortSignal.any([i.signal,AbortSignal.timeout(r)])}async function F(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,I(i,n),L(t,n),J(r)){await R({req:t,res:n,response:i,clientToken:a});return}await B(i,n)}function I(e,t){for(let n of O){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function L(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,le(e))}async function R(e){let{req:t,res:n,response:r,clientToken:i}=e,a=await r.text();n.setHeader(`content-type`,r.headers.get(`content-type`)??`application/json`),n.end(z(a,t,i))}function z(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}if(!r||typeof r!=`object`)return e;let a=r;if(!a.upload||typeof a.upload.url!=`string`)return e;let o=re(a.upload.url,t);if(!o)return e;let s=a.upload.headers&&typeof a.upload.headers==`object`?{...a.upload.headers}:{};return Object.assign(s,i(n)),JSON.stringify({...r,upload:{...a.upload,url:o,headers:s}})}function re(e,t){let n;try{n=new URL(e)}catch{return null}if(!n.pathname.startsWith(`/upload/`))return null;let r=typeof t.headers.host==`string`?t.headers.host:``;if(!r)return null;let i=new URL(t.url??`/`,`http://127.0.0.1`).pathname,a=i.lastIndexOf(`/upload/preflight`),o=a>=0?i.slice(0,a):``,s=t.headers[`x-forwarded-proto`],c=Array.isArray(s)?s[0]:s,l=new URL(`${c||`http`}://${r}`);return l.pathname=`${o}${n.pathname}`,l.search=n.search,l.toString()}async function B(e,t){if(!e.body){t.end();return}await v(_.fromWeb(e.body),t)}function V(e){return{upstreamBaseUrl:H(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:U(e.upstreamToken,`upstreamToken`),clientToken:U(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function H(t,n){try{let e=new URL(t);if(e.protocol!==`http:`&&e.protocol!==`https:`)throw Error(`unsupported protocol`);return e.toString().replace(/\/+$/,``)}catch(r){throw new e(`INVALID_ARGS`,`Invalid ${n}`,{[n]:t},r)}}function U(t,n){let r=t.trim();if(!r)throw new e(`INVALID_ARGS`,`Proxy ${n} is required.`);return r}function W(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(E)?`/${t.slice(E.length)}`:t}function G(e,t){return e===`/rpc`?t===`POST`:q(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)||K(e)?t===`GET`:!1}function K(e){let t=e.split(`/`);return t.length===6&&t[1]===`sessions`&&t[3]===`requests`&&t[5]===`diagnostics`&&t[2]!==``&&t[4]!==``}function q(e,t){return e===`/upload`||J(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function J(e){return e===`/upload/preflight`}function Y(e,t,n){let r=new URL(s(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function X(e,t,n){let a=new Headers;for(let t of D){let n=e.headers[t];typeof n==`string`&&n.trim()&&a.set(t,n)}n===`/rpc`&&!a.has(`content-type`)&&a.set(`content-type`,`application/json`),n===`/rpc`&&a.set(u,r);for(let[e,n]of Object.entries(i(t)))a.set(e,n);return a}function ie(e,t,n,r){if(e.method!==`GET`&&e.method!==`HEAD`)return t===`/rpc`?se(n??``,r):e}function ae(e,t,r){let i=oe(e,r);return i.length>0&&n(i,t)}function oe(e,t){let n=typeof e.headers.authorization==`string`?e.headers.authorization:``;if(n.toLowerCase().startsWith(`bearer `))return n.slice(7);let r=e.headers[`x-agent-device-token`];if(typeof r==`string`)return r;if(t){let e=ce(t);if(e)return e}return``}function se(e,t){let n=JSON.parse(e);return n.params={...n.params??{},token:t},JSON.stringify(n)}function ce(e){try{let t=JSON.parse(e);return typeof t.params?.token==`string`?t.params.token:``}catch{return``}}function Z(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function le(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):g()}function ue(n,r,i){if(n.statusCode=401,n.setHeader(`content-type`,`application/json`),r===`/rpc`){n.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:t(new e(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}n.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function de(e,n){if(e.destroyed)return;if(e.headersSent){e.destroy(n instanceof Error?n:void 0);return}let r=t(n);e.statusCode=r.code===`INVALID_ARGS`?400:500,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}const fe=async({positionals:t,flags:n})=>{if(t.length>0)throw new e(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await pe(n);return await h(n,r,()=>_e(r)),await ve(),!0};async function pe(t){let n=p({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:t.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await f(n),i=me(r.info.httpPort),o=Q(t),s=k({upstreamBaseUrl:i,upstreamToken:r.info.token,clientToken:o});await he(s,t.proxyHost?.trim()||`127.0.0.1`,t.proxyPort??0);let c=s.address();if(!c||typeof c==`string`)throw new e(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let l=`http://${ge(c.address)}:${c.port}`;return{proxyBaseUrl:l,agentDeviceBaseUrl:a(l),token:o,upstreamBaseUrl:i,stateDir:n.paths.baseDir}}function me(t){if(!t)throw new e(`COMMAND_FAILED`,`Local daemon HTTP endpoint is unavailable.`,{hint:`Retry after cleaning daemon state, or run proxy with a fresh --state-dir.`});return`http://127.0.0.1:${t}`}function Q(e){return e.daemonAuthToken?.trim()||ne(32).toString(`hex`)}function he(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function ge(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function _e(e,t={}){let n=t.useColor??ee(),r=$(`✓`,`green`,n),i=$(e.proxyBaseUrl,`cyan`,n),a=$(`<tunnel URL>`,`cyan`,n),o=$(e.token,`yellow`,n);return[`${r} Proxy listening at ${i}`,``,`Provide this to the agent-device instance connecting:`,``,`Daemon base URL: ${a}`,`Daemon auth token: ${o}`].join(`
1
+ import{O as e,R as t}from"./sdk-contracts.js";import{a as n,c as r,d as i,f as a,l as o,m as s,o as c,r as l,s as u,u as d}from"./transport.js";import{i as f,s as p}from"./daemon-client-lifecycle.js";import{a as m}from"./version.js";import{t as h}from"./shared.js";import{n as ee,t as te}from"./color.js";import{randomBytes as ne,randomUUID as g}from"node:crypto";import{Readable as _}from"node:stream";import{pipeline as v}from"node:stream/promises";import y from"node:http";function b(e){let t=S(e);if(!t)return!1;let n=T(t.meta);return C(n)?!1:w(t.source)||w(n?.installSource)}function x(n,r){let i=new e(`INVALID_ARGS`,`Invalid params: an install source of kind "path" names a file on the daemon host and is not accepted through the proxy`,{hint:`Upload the artifact, or use a "url" or "github-actions-artifact" source.`});n.statusCode=400,n.setHeader(`content-type`,`application/json`),n.end(JSON.stringify({jsonrpc:`2.0`,id:r,error:{code:-32602,message:i.message,data:t(i)}}))}function S(e){if(e)try{return T(T(JSON.parse(e))?.params)}catch{return}}function C(e){let t=e?.uploadedArtifactId;return typeof t==`string`&&t.trim().length>0}function w(e){return T(e)?.kind===`path`}function T(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}const E=`${c}/`,D=[`content-type`,`content-range`,`x-artifact-type`,`x-artifact-filename`,`x-artifact-hash`,`x-artifact-hash-algorithm`,o],O=[`content-type`,`content-disposition`,`x-request-id`];function k(e){let t=V(e);return y.createServer((e,n)=>{A(e,n,t).catch(e=>{de(n,e)})})}async function A(e,t,n){let r=W(e.url??`/`);if(e.method===`GET`&&r===`/health`){await j(t,n);return}if(!G(r,e.method)){t.statusCode=404,t.end(`Not found`);return}let i;if(r===`/rpc`&&(i=(await l(e,n.maxRpcBodyBytes,`Proxy request body is too large.`)).toString(`utf8`)),!ae(e,n.clientToken,i)){ue(t,r,Z(i));return}if(b(i)){x(t,Z(i));return}await N({req:e,res:t,route:r,options:n,rpcBody:i})}async function j(e,t){let n=await M(t);e.statusCode=200,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify(d(`agent-device-proxy`,m(),{upstream:n})))}async function M(e){let t=new URL(s(e.upstreamBaseUrl,`health`)),n=await e.fetchImpl(t,{method:`GET`,headers:X({headers:{}},e.upstreamToken,`/health`),signal:AbortSignal.timeout(e.upstreamTimeoutMs)}),r=await n.text();try{return r?JSON.parse(r):{ok:n.ok,status:n.status}}catch{return{ok:n.ok,status:n.status}}}async function N(e){let{req:t,res:n,route:r,options:i,rpcBody:a}=e,o=Y(i.upstreamBaseUrl,r,t.url??`/`),s=t.method??`GET`,c=X(t,i.upstreamToken,r),l=ie(t,r,a,i.upstreamToken);await F({req:t,res:n,route:r,response:await i.fetchImpl(o,{method:s,headers:c,signal:P(t,n,i.upstreamTimeoutMs),...l?{body:l,duplex:`half`}:{}}),clientToken:i.clientToken})}function P(t,n,r){let i=new AbortController,a=()=>{n.writableFinished||i.signal.aborted||i.abort(new e(`COMMAND_FAILED`,`Proxy client disconnected before the upstream response ended`))};return t.on(`aborted`,a),n.on(`close`,a),AbortSignal.any([i.signal,AbortSignal.timeout(r)])}async function F(e){let{req:t,res:n,route:r,response:i,clientToken:a}=e;if(n.statusCode=i.status,I(i,n),L(t,n),J(r)){await R({req:t,res:n,response:i,clientToken:a});return}await B(i,n)}function I(e,t){for(let n of O){let r=e.headers.get(n);r&&t.setHeader(n,r)}}function L(e,t){t.hasHeader(`x-request-id`)||t.setHeader(`x-request-id`,le(e))}async function R(e){let{req:t,res:n,response:r,clientToken:i}=e,a=await r.text();n.setHeader(`content-type`,r.headers.get(`content-type`)??`application/json`),n.end(z(a,t,i))}function z(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}if(!r||typeof r!=`object`)return e;let a=r;if(!a.upload||typeof a.upload.url!=`string`)return e;let o=re(a.upload.url,t);if(!o)return e;let s=a.upload.headers&&typeof a.upload.headers==`object`?{...a.upload.headers}:{};return Object.assign(s,i(n)),JSON.stringify({...r,upload:{...a.upload,url:o,headers:s}})}function re(e,t){let n;try{n=new URL(e)}catch{return null}if(!n.pathname.startsWith(`/upload/`))return null;let r=typeof t.headers.host==`string`?t.headers.host:``;if(!r)return null;let i=new URL(t.url??`/`,`http://127.0.0.1`).pathname,a=i.lastIndexOf(`/upload/preflight`),o=a>=0?i.slice(0,a):``,s=t.headers[`x-forwarded-proto`],c=Array.isArray(s)?s[0]:s,l=new URL(`${c||`http`}://${r}`);return l.pathname=`${o}${n.pathname}`,l.search=n.search,l.toString()}async function B(e,t){if(!e.body){t.end();return}await v(_.fromWeb(e.body),t)}function V(e){return{upstreamBaseUrl:H(e.upstreamBaseUrl,`upstreamBaseUrl`),upstreamToken:U(e.upstreamToken,`upstreamToken`),clientToken:U(e.clientToken,`clientToken`),maxRpcBodyBytes:e.maxRpcBodyBytes??1048576,upstreamTimeoutMs:e.upstreamTimeoutMs??3e5,fetchImpl:e.fetchImpl??fetch}}function H(t,n){try{let e=new URL(t);if(e.protocol!==`http:`&&e.protocol!==`https:`)throw Error(`unsupported protocol`);return e.toString().replace(/\/+$/,``)}catch(r){throw new e(`INVALID_ARGS`,`Invalid ${n}`,{[n]:t},r)}}function U(t,n){let r=t.trim();if(!r)throw new e(`INVALID_ARGS`,`Proxy ${n} is required.`);return r}function W(e){let t=new URL(e,`http://127.0.0.1`).pathname;return t===`/agent-device`?`/`:t.startsWith(E)?`/${t.slice(E.length)}`:t}function G(e,t){return e===`/rpc`?t===`POST`:q(e,t)?!0:e===`/artifacts`||e===`/artifacts/`||e.startsWith(`/artifacts/`)||K(e)?t===`GET`:!1}function K(e){let t=e.split(`/`);return t.length===6&&t[1]===`sessions`&&t[3]===`requests`&&t[5]===`diagnostics`&&t[2]!==``&&t[4]!==``}function q(e,t){return e===`/upload`||J(e)||e===`/upload/finalize`?t===`POST`:e.startsWith(`/upload/direct/`)?t===`PUT`:!1}function J(e){return e===`/upload/preflight`}function Y(e,t,n){let r=new URL(s(e,t)),i=n.indexOf(`?`);return i>=0&&(r.search=n.slice(i)),r}function X(e,t,n){let a=new Headers;for(let t of D){let n=e.headers[t];typeof n==`string`&&n.trim()&&a.set(t,n)}n===`/rpc`&&!a.has(`content-type`)&&a.set(`content-type`,`application/json`),n===`/rpc`&&a.set(u,r);for(let[e,n]of Object.entries(i(t)))a.set(e,n);return a}function ie(e,t,n,r){if(e.method!==`GET`&&e.method!==`HEAD`)return t===`/rpc`?se(n??``,r):e}function ae(e,t,r){let i=oe(e,r);return i.length>0&&n(i,t)}function oe(e,t){let n=typeof e.headers.authorization==`string`?e.headers.authorization:``;if(n.toLowerCase().startsWith(`bearer `))return n.slice(7);let r=e.headers[`x-agent-device-token`];if(typeof r==`string`)return r;if(t){let e=ce(t);if(e)return e}return``}function se(e,t){let n=JSON.parse(e);return n.params={...n.params??{},token:t},JSON.stringify(n)}function ce(e){try{let t=JSON.parse(e);return typeof t.params?.token==`string`?t.params.token:``}catch{return``}}function Z(e){if(!e)return null;try{return JSON.parse(e).id??null}catch{return null}}function le(e){let t=e.headers[`x-request-id`];return typeof t==`string`&&t.trim()?t.trim().slice(0,128):g()}function ue(n,r,i){if(n.statusCode=401,n.setHeader(`content-type`,`application/json`),r===`/rpc`){n.end(JSON.stringify({jsonrpc:`2.0`,id:i,error:{code:-32001,message:`Invalid proxy token`,data:t(new e(`UNAUTHORIZED`,`Invalid proxy token`))}}));return}n.end(JSON.stringify({ok:!1,error:`Invalid proxy token`,code:`UNAUTHORIZED`}))}function de(e,n){if(e.destroyed)return;if(e.headersSent){e.destroy(n instanceof Error?n:void 0);return}let r=t(n);e.statusCode=r.code===`INVALID_ARGS`?400:500,e.setHeader(`content-type`,`application/json`),e.end(JSON.stringify({ok:!1,error:r.message,code:r.code}))}const fe=async({positionals:t,flags:n})=>{if(t.length>0)throw new e(`INVALID_ARGS`,`proxy does not accept positional arguments.`);let r=await pe(n);return await h(n,r,()=>_e(r)),await ve(),!0};async function pe(t){let n=p({session:`default`,command:`proxy`,positionals:[],flags:{stateDir:t.stateDir,daemonBaseUrl:``,daemonTransport:`http`,daemonServerMode:`http`}}),r=await f(n),i=me(r.info.httpPort),o=Q(t),s=k({upstreamBaseUrl:i,upstreamToken:r.info.token,clientToken:o});await he(s,t.proxyHost?.trim()||`127.0.0.1`,t.proxyPort??0);let c=s.address();if(!c||typeof c==`string`)throw new e(`COMMAND_FAILED`,`Proxy did not bind to a TCP address.`);let l=`http://${ge(c.address)}:${c.port}`;return{proxyBaseUrl:l,agentDeviceBaseUrl:a(l),token:o,upstreamBaseUrl:i,stateDir:n.paths.baseDir}}function me(t){if(!t)throw new e(`COMMAND_FAILED`,`Local daemon HTTP endpoint is unavailable.`,{hint:`Retry after cleaning daemon state, or run proxy with a fresh --state-dir.`});return`http://127.0.0.1:${t}`}function Q(e){return e.daemonAuthToken?.trim()||ne(32).toString(`hex`)}function he(e,t,n){return new Promise((r,i)=>{e.once(`error`,i),e.listen(n,t,()=>{e.off(`error`,i),r()})})}function ge(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function _e(e,t={}){let n=t.useColor??ee(),r=$(`✓`,`green`,n),i=$(e.proxyBaseUrl,`cyan`,n),a=$(`<tunnel URL>`,`cyan`,n),o=$(e.token,`yellow`,n);return[`${r} Proxy listening at ${i}`,``,`Provide this to the agent-device instance connecting:`,``,`Daemon base URL: ${a}`,`Daemon auth token: ${o}`].join(`
2
2
  `)}function $(e,t,n){return n?te(e,t,{validateStream:!1}):e}function ve(){return new Promise(()=>{})}export{fe as proxyCommand};
@@ -1 +1 @@
1
- import{D as e}from"./sdk-contracts.js";import{i as t}from"./capture.js";import{n}from"./snapshot-quality-backend-capabilities.js";import{i as r,o as i}from"./png-worker-client.js";import{r as a}from"./png.js";import{promises as o}from"node:fs";const s=new Set([`healthy`,`recovered`,`sparse`]),c=new Set(Object.keys(n)),l=new Set([`ax-rejected`,`sparse-tree`,`budget`,`no-nodes`,`capture-failed`,`presentation-failed`,`deferred`,`requested-backend`]);function u(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.state!=`string`||!s.has(t.state)||typeof t.backend!=`string`||!c.has(t.backend))return;let n=d(t.timing);return{state:t.state,backend:t.backend,reason:typeof t.reason==`string`?t.reason:void 0,reasonCode:typeof t.reasonCode==`string`&&l.has(t.reasonCode)?t.reasonCode:void 0,customActions:f(t.customActions),effectiveDepth:typeof t.effectiveDepth==`number`?t.effectiveDepth:void 0,collapsedLeafIndexes:Array.isArray(t.collapsedLeafIndexes)?t.collapsedLeafIndexes.filter(e=>typeof e==`number`):void 0,...n?{timing:n}:{}}}function d(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.acquisitionMs==`number`&&typeof t.presentationMs==`number`)return{acquisitionMs:t.acquisitionMs,presentationMs:t.presentationMs}}function f(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.read==`number`&&typeof t.candidates==`number`)return{read:t.read,candidates:t.candidates,truncated:typeof t.truncated==`number`?t.truncated:0,blocked:t.blocked===!0}}function p(e){return e?.state===`sparse`}function m(e){return e?.backend===`private-ax`?`private-ax`:void 0}async function h(n,a){let{min:s,max:c}=t;if(!Number.isFinite(a)||a<s||a>c)throw new e(`INVALID_ARGS`,`Screenshot scale must be between ${s} and ${c}`);if(a===1)return;let l=await r(await o.readFile(n),`screenshot`),u=Math.max(1,Math.round(l.width*a)),d=Math.max(1,Math.round(l.height*a));await o.writeFile(n,await i(_(l,u,d)))}async function g(t,n,a){if(!Number.isInteger(n)||n<1||!Number.isInteger(a)||a<1)throw new e(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let s=await r(await o.readFile(t),`screenshot`);(s.width!==n||s.height!==a)&&await o.writeFile(t,await i(_(s,n,a)))}function _(e,t,n){let r=new a.PNG({width:t,height:n});for(let i=0;i<n;i+=1){let a=i*e.height/n,o=(i+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,c=(n+1)*e.width/t,l=0,u=0,d=0,f=0,p=0;for(let t=Math.floor(a);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(t*e.width+r)*4;l+=(e.data[a]??0)*i,u+=(e.data[a+1]??0)*i,d+=(e.data[a+2]??0)*i,f+=(e.data[a+3]??0)*i,p+=i}}let m=(i*r.width+n)*4;r.data[m]=Math.round(l/p),r.data[m+1]=Math.round(u/p),r.data[m+2]=Math.round(d/p),r.data[m+3]=Math.round(f/p)}}return r}function v(e,t){return[...S(e),...y(e),...w(e),...T(e,t)]}function y(e){let t=e.customActions;if(!t)return[];let n=[];return t.blocked?n.push(`Custom actions were not read: an earlier accessibility read is still hung, so this capture skipped the read pass instead of queueing behind it. No element’s actions list is authoritative here. Reads resume once that call returns.`):t.read<t.candidates&&n.push(`Custom actions were read for ${t.read} of ${t.candidates} merged elements, on-screen ones first; the remaining ${t.candidates-t.read} were not read, so an absent actions list on those is not evidence that they have none. Scroll them into view and re-run to read them.`),t.truncated>0&&n.push(`${t.truncated} element(s) published more custom actions than are shown; those lists are clipped to the first 8 names, and long names are shortened.`),n}function b(e){return e===!0?[`This capture was cut at a backend limit, so elements later in the tree — footers, tab bars, items after a long list — may be missing even when they are on screen; their refs and selectors cannot be resolved from this snapshot. Navigate or scroll so fewer elements render and re-run, and use screenshot as visual truth for what is missing.`]:[]}function x(e){return`Detected an overly complex or slow accessibility tree. Fell back to the ${e} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`}function S(e){return e.state===`recovered`?e.reasonCode===`deferred`||e.reasonCode===`requested-backend`?[]:e.reasonCode===`presentation-failed`?[`Agent Device could not safely present the captured accessibility tree and fell back to the ${e.backend} snapshot backend. This is an Agent Device runner bug, not an app accessibility-tree issue. Use screenshot as visual truth and report snapshotQuality.reason with the screenshot.`]:[x(e.backend)]:e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Its refs and selectors are invalid. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`,...C(e)]:[]}function C(e){return e.reasonCode===`sparse-tree`?[`This screen publishes no accessibility content at all; assistive technologies see the same empty tree, so it is worth flagging as an app accessibility bug rather than only an automation limitation.`]:[]}function w(e){return e.effectiveDepth===void 0?[]:[`Some deeper accessibility nodes were omitted; the accessibility backend capped this tree at depth ${e.effectiveDepth}. Navigate so the content you need sits higher in the tree, and use screenshot as visual truth for the rest.`]}function T(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}export{g as a,m as c,_ as i,u as l,v as n,h as o,b as r,p as s,x as t};
1
+ import{O as e}from"./sdk-contracts.js";import{a as t}from"./capture.js";import{n}from"./snapshot-quality-backend-capabilities.js";import{i as r,o as i}from"./png-worker-client.js";import{r as a}from"./png.js";import{promises as o}from"node:fs";const s=new Set([`healthy`,`recovered`,`sparse`]),c=new Set(Object.keys(n)),l=new Set([`ax-rejected`,`sparse-tree`,`budget`,`no-nodes`,`capture-failed`,`presentation-failed`,`deferred`,`requested-backend`]);function u(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.state!=`string`||!s.has(t.state)||typeof t.backend!=`string`||!c.has(t.backend))return;let n=d(t.timing);return{state:t.state,backend:t.backend,reason:typeof t.reason==`string`?t.reason:void 0,reasonCode:typeof t.reasonCode==`string`&&l.has(t.reasonCode)?t.reasonCode:void 0,customActions:f(t.customActions),effectiveDepth:typeof t.effectiveDepth==`number`?t.effectiveDepth:void 0,collapsedLeafIndexes:Array.isArray(t.collapsedLeafIndexes)?t.collapsedLeafIndexes.filter(e=>typeof e==`number`):void 0,...n?{timing:n}:{}}}function d(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.acquisitionMs==`number`&&typeof t.presentationMs==`number`)return{acquisitionMs:t.acquisitionMs,presentationMs:t.presentationMs}}function f(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.read==`number`&&typeof t.candidates==`number`)return{read:t.read,candidates:t.candidates,truncated:typeof t.truncated==`number`?t.truncated:0,blocked:t.blocked===!0}}function p(e){return e?.state===`sparse`}function m(e){return e?.backend===`private-ax`?`private-ax`:void 0}async function h(n,a){let{min:s,max:c}=t;if(!Number.isFinite(a)||a<s||a>c)throw new e(`INVALID_ARGS`,`Screenshot scale must be between ${s} and ${c}`);if(a===1)return;let l=await r(await o.readFile(n),`screenshot`),u=Math.max(1,Math.round(l.width*a)),d=Math.max(1,Math.round(l.height*a));await o.writeFile(n,await i(_(l,u,d)))}async function g(t,n,a){if(!Number.isInteger(n)||n<1||!Number.isInteger(a)||a<1)throw new e(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let s=await r(await o.readFile(t),`screenshot`);(s.width!==n||s.height!==a)&&await o.writeFile(t,await i(_(s,n,a)))}function _(e,t,n){let r=new a.PNG({width:t,height:n});for(let i=0;i<n;i+=1){let a=i*e.height/n,o=(i+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,c=(n+1)*e.width/t,l=0,u=0,d=0,f=0,p=0;for(let t=Math.floor(a);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(t*e.width+r)*4;l+=(e.data[a]??0)*i,u+=(e.data[a+1]??0)*i,d+=(e.data[a+2]??0)*i,f+=(e.data[a+3]??0)*i,p+=i}}let m=(i*r.width+n)*4;r.data[m]=Math.round(l/p),r.data[m+1]=Math.round(u/p),r.data[m+2]=Math.round(d/p),r.data[m+3]=Math.round(f/p)}}return r}function v(e,t){return[...S(e),...y(e),...w(e),...T(e,t)]}function y(e){let t=e.customActions;if(!t)return[];let n=[];return t.blocked?n.push(`Custom actions were not read: an earlier accessibility read is still hung, so this capture skipped the read pass instead of queueing behind it. No element’s actions list is authoritative here. Reads resume once that call returns.`):t.read<t.candidates&&n.push(`Custom actions were read for ${t.read} of ${t.candidates} merged elements, on-screen ones first; the remaining ${t.candidates-t.read} were not read, so an absent actions list on those is not evidence that they have none. Scroll them into view and re-run to read them.`),t.truncated>0&&n.push(`${t.truncated} element(s) published more custom actions than are shown; those lists are clipped to the first 8 names, and long names are shortened.`),n}function b(e){return e===!0?[`This capture was cut at a backend limit, so elements later in the tree — footers, tab bars, items after a long list — may be missing even when they are on screen; their refs and selectors cannot be resolved from this snapshot. Navigate or scroll so fewer elements render and re-run, and use screenshot as visual truth for what is missing.`]:[]}function x(e){return`Detected an overly complex or slow accessibility tree. Fell back to the ${e} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`}function S(e){return e.state===`recovered`?e.reasonCode===`deferred`||e.reasonCode===`requested-backend`?[]:e.reasonCode===`presentation-failed`?[`Agent Device could not safely present the captured accessibility tree and fell back to the ${e.backend} snapshot backend. This is an Agent Device runner bug, not an app accessibility-tree issue. Use screenshot as visual truth and report snapshotQuality.reason with the screenshot.`]:[x(e.backend)]:e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Its refs and selectors are invalid. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`,...C(e)]:[]}function C(e){return e.reasonCode===`sparse-tree`?[`This screen publishes no accessibility content at all; assistive technologies see the same empty tree, so it is worth flagging as an app accessibility bug rather than only an automation limitation.`]:[]}function w(e){return e.effectiveDepth===void 0?[]:[`Some deeper accessibility nodes were omitted; the accessibility backend capped this tree at depth ${e.effectiveDepth}. Navigate so the content you need sits higher in the tree, and use screenshot as visual truth for the rest.`]}function T(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}export{g as a,m as c,_ as i,u as l,v as n,h as o,b as r,p as s,x as t};
@@ -1 +1 @@
1
- import{L as e,o as t,u as n}from"./sdk-contracts.js";import{k as r}from"./sdk-batch-runner.js";import{M as i,d as a,u as o}from"./session-snapshot.js";import{M as s}from"./runtime.js";import{n as c}from"./catalog.js";import{r as l}from"./success-text.js";import{n as u}from"./touch-reference-frame.js";import{s as d}from"./quality-warnings.js";import{o as f}from"./interaction-ref-policy.js";import{captureSnapshotForSession as p}from"./interaction.js";async function m(r){let{req:i,sessionName:o,sessionStore:l}=r;if(i.command!==c.reactNative)return null;let u=h(i.positionals??[]);if(!u.ok)return u.response;let f=l.get(o);if(!f)return n();let m=await a({device:f.device,command:`press`,requiresCapture:!1,inspectFacts:r.inspectFacts,bindDevice:r.bindDevice,unavailableResponse:e=>t(`UNSUPPORTED_OPERATION`,`react-native dismiss-overlay is not supported on this device`,void 0,e.hint?{hint:e.hint}:void 0)});if(!m.ok)return m.response;try{let e=await p(f,i.flags,l,r.contextFromFlags,{interactiveOnly:!0});if(d(e.snapshotQuality))return _(e.snapshotQuality);let t=s(e.nodes),n=t.primaryAction;return n?await v(r,f,e,n,m.runtime):g(t.detected)}catch(t){return{ok:!1,error:e(t)}}}function h(e){return e.length===1&&e[0]===`dismiss-overlay`?{ok:!0}:{ok:!1,response:t(`INVALID_ARGS`,`react-native supports only: dismiss-overlay`)}}function g(e){return e?t(`COMMAND_FAILED`,`React Native overlay detected, but no safe dismiss target was found`,{hint:`Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body.`}):{ok:!0,data:{action:`dismiss-overlay`,detected:!1,dismissed:!1,...l(`No React Native overlay detected`)}}}function _(e){return t(`COMMAND_FAILED`,`React Native overlay state could not be determined because the accessibility tree is unreadable`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth; if an overlay is visible, report it or navigate with coordinates, then retry snapshot or dismiss-overlay on a readable screen.`})}async function v(e,n,a,s,c){let{req:d,sessionStore:p}=e,m=e.contextFromFlags(d.flags,n.appBundleId,n.trace?.outPath),h=o(c,m).tapPoint;if(!h)return t(`UNSUPPORTED_OPERATION`,`react-native dismiss-overlay is not supported on this device`);let g=Date.now();i(n);let _=await h(s.point),v=Date.now(),x=await y(e,n),S=r({...u(a.nodes),..._,action:`dismiss-overlay`,overlayAction:s.action,x:s.point.x,y:s.point.y,ref:s.ref,label:s.label,warning:s.warning,dismissed:!0,verified:x.verified,verificationRequired:!x.verified,verificationWarning:x.verificationWarning,nextCommand:x.nextCommand,...l(b(x))});return f({session:n,sessionStore:p,command:d.command,positionals:d.positionals??[],flags:d.flags,result:S,responseData:S,actionStartedAt:g,actionFinishedAt:v})}async function y(e,t){let{req:n,sessionStore:r}=e,i=await p(t,n.flags,r,e.contextFromFlags,{interactiveOnly:!0});return d(i.snapshotQuality)?{verified:!1,verificationWarning:`React Native overlay dismissal could not be verified because the post-dismiss accessibility tree is unreadable. Use screenshot as visual truth.`,nextCommand:`agent-device screenshot`}:s(i.nodes).detected?{verified:!1,verificationWarning:`React Native overlay is still detected after dismissal. Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body.`,nextCommand:`agent-device screenshot --overlay-refs`}:{verified:!0}}function b(e){return e.verified?`React Native overlay dismiss action sent and verified gone`:`React Native overlay dismiss action sent, but verification still detects an overlay`}export{m as handleReactNativeCommands};
1
+ import{R as e,o as t,u as n}from"./sdk-contracts.js";import{k as r}from"./sdk-batch-runner.js";import{B as i,d as a,u as o}from"./session-snapshot.js";import{P as s}from"./runtime.js";import{n as c}from"./catalog.js";import{r as l}from"./success-text.js";import{n as u}from"./touch-reference-frame.js";import{s as d}from"./quality-warnings.js";import{o as f}from"./interaction-ref-policy.js";import{captureSnapshotForSession as p}from"./interaction.js";async function m(r){let{req:i,sessionName:o,sessionStore:l}=r;if(i.command!==c.reactNative)return null;let u=h(i.positionals??[]);if(!u.ok)return u.response;let f=l.get(o);if(!f)return n();let m=await a({device:f.device,command:`press`,requiresCapture:!1,inspectFacts:r.inspectFacts,bindDevice:r.bindDevice,unavailableResponse:e=>t(`UNSUPPORTED_OPERATION`,`react-native dismiss-overlay is not supported on this device`,void 0,e.hint?{hint:e.hint}:void 0)});if(!m.ok)return m.response;try{let e=await p(f,i.flags,l,r.contextFromFlags,{interactiveOnly:!0});if(d(e.snapshotQuality))return _(e.snapshotQuality);let t=s(e.nodes),n=t.primaryAction;return n?await v(r,f,e,n,m.runtime):g(t.detected)}catch(t){return{ok:!1,error:e(t)}}}function h(e){return e.length===1&&e[0]===`dismiss-overlay`?{ok:!0}:{ok:!1,response:t(`INVALID_ARGS`,`react-native supports only: dismiss-overlay`)}}function g(e){return e?t(`COMMAND_FAILED`,`React Native overlay detected, but no safe dismiss target was found`,{hint:`Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body.`}):{ok:!0,data:{action:`dismiss-overlay`,detected:!1,dismissed:!1,...l(`No React Native overlay detected`)}}}function _(e){return t(`COMMAND_FAILED`,`React Native overlay state could not be determined because the accessibility tree is unreadable`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth; if an overlay is visible, report it or navigate with coordinates, then retry snapshot or dismiss-overlay on a readable screen.`})}async function v(e,n,a,s,c){let{req:d,sessionStore:p}=e,m=e.contextFromFlags(d.flags,n.appBundleId,n.trace?.outPath),h=o(c,m).tapPoint;if(!h)return t(`UNSUPPORTED_OPERATION`,`react-native dismiss-overlay is not supported on this device`);let g=Date.now();i(n);let _=await h(s.point),v=Date.now(),x=await y(e,n),S=r({...u(a.nodes),..._,action:`dismiss-overlay`,overlayAction:s.action,x:s.point.x,y:s.point.y,ref:s.ref,label:s.label,warning:s.warning,dismissed:!0,verified:x.verified,verificationRequired:!x.verified,verificationWarning:x.verificationWarning,nextCommand:x.nextCommand,...l(b(x))});return f({session:n,sessionStore:p,command:d.command,positionals:d.positionals??[],flags:d.flags,result:S,responseData:S,actionStartedAt:g,actionFinishedAt:v})}async function y(e,t){let{req:n,sessionStore:r}=e,i=await p(t,n.flags,r,e.contextFromFlags,{interactiveOnly:!0});return d(i.snapshotQuality)?{verified:!1,verificationWarning:`React Native overlay dismissal could not be verified because the post-dismiss accessibility tree is unreadable. Use screenshot as visual truth.`,nextCommand:`agent-device screenshot`}:s(i.nodes).detected?{verified:!1,verificationWarning:`React Native overlay is still detected after dismissal. Use screenshot --overlay-refs for visual evidence and report the overlay instead of pressing the warning body.`,nextCommand:`agent-device screenshot --overlay-refs`}:{verified:!0}}function b(e){return e.verified?`React Native overlay dismiss action sent and verified gone`:`React Native overlay dismiss action sent, but verification still detects an overlay`}export{m as handleReactNativeCommands};
@@ -1 +1 @@
1
- import{D as e,L as t}from"./sdk-contracts.js";import{c as n}from"./capture.js";import{_ as r}from"./sdk-batch-runner.js";import{E as i,k as a}from"./sdk-device.js";import{D as o,E as s,O as c}from"./sdk-batch.js";import{i as l,n as u}from"./recording-export-quality.js";import{n as d,r as f}from"./recording-scope.js";import{c as p}from"./session-store.js";import{r as m}from"./diagnostics.js";import"./diagnostics2.js";import{i as h}from"./output-path.js";import{i as ee,n as g}from"./recording-stop-observation.js";import{n as _}from"./request-runtime-binding.js";import{n as v}from"./dispatch-resolve.js";import"./screen-recording-admission-ledger.js";import{a as y,t as b}from"./session-routing.js";import{a as x,c as S,i as C,o as w,s as T,t as E}from"./screen-recording-resource-recovery.js";import{t as D}from"./telemetry.js";import O from"node:path";import k from"node:fs";const A=[`clientOutPath`,`telemetryPath`,`warning`,`overlayWarning`];function j(e){let{resourcePath:t,record:n}=N(e);if(n.status!==`decoded`)return{kind:`none`};if(P(e,n.envelope),n.envelope.lifecycle!==`completed`)return{kind:`open`,resourcePath:t};let r=F(n.envelope.metadata);return r===void 0?(m({level:`warn`,phase:`screen_recording_completed_manifest_unreplayable`,data:{resourcePath:t}}),{kind:`none`}):k.existsSync(r.outPath)?{kind:`completed`,completion:r}:{kind:`none`}}function M(e){let{record:t}=N(e);return t.status===`decoded`&&t.envelope.lifecycle===`completed`}function N(e){let t=S.resourcePath(e.sessionStore,e.sessionName);return{resourcePath:t,record:S.store.read(t)}}function P(t,n){if(n.sessionId!==t.sessionName)throw new e(`COMMAND_FAILED`,`Screen recording recovery record does not belong to the requested session`,{reason:`runtime-contract-invalid`});if(!a(n.device,i(t.device)))throw new e(`COMMAND_FAILED`,`Screen recording recovery device does not match the selected device`,{reason:`runtime-contract-invalid`})}function F(e){let t=e?.[C];if(!(!r(t)||!I(t)||!L(t)||!R(t)))return t}function I(e){return z(e.outPath)&&z(e.backend)&&V(e.startedAt)&&V(e.completedAt)&&(e.capturedDurationMs===void 0||V(e.capturedDurationMs))&&d(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function L(e){return A.every(t=>B(e[t]))&&te(e.activeSessionApp)&&W(e.chunks)}function R(e){return(e.stopObservation===void 0||g(e.stopObservation))&&(e.nativePathDisposition===void 0||ee(e.nativePathDisposition))}function z(e){return typeof e==`string`&&e.length>0}function B(e){return e===void 0||z(e)}function V(e){return typeof e==`number`&&Number.isFinite(e)}function H(e){return!r(e)||!z(e.bundleId)?!1:B(e.name)}function te(e){return e===void 0||H(e)}function U(e){return Array.isArray(e)&&e.every(e=>r(e)&&Number.isFinite(e.index)&&z(e.path)&&B(e.clientOutPath))}function W(e){return e===void 0||U(e)}function G(t){let r=n(`record`,t.flags);if(r)throw new e(`INVALID_ARGS`,r);let i=t.flags?.fps;if(i!==void 0&&(!Number.isInteger(i)||i<1||i>120))throw new e(`INVALID_ARGS`,`fps must be an integer between 1 and 120`);let a=l(t.flags?.quality);if(t.flags?.quality!==void 0&&a===void 0)throw new e(`INVALID_ARGS`,`quality must be one of: ${u.join(`, `)} (legacy numeric values 5-10 are accepted)`);return{scope:K(t.flags?.recordingScope),...i===void 0?{}:{fps:i},...a===void 0?{}:{exportQuality:a},showTouches:t.flags?.hideTouches!==!0,hideTouchesRequested:t.flags?.hideTouches===!0}}function K(t){if(t===void 0)return`app`;if(t===`app`||t===`device`||t===`system`)return t;throw new e(`INVALID_ARGS`,`record scope must be app, device, or system`)}function q(e){return{ok:!1,error:{code:`INVALID_ARGS`,message:b(e)?`record start with app scope and an explicit session requires an active app session; run open <app> first, or use --scope device to record the full screen`:`record start defaults to app scope and requires an active app session; run open <app> first, or use --scope device to record the full screen`}}}function J(e,t,n){return{ok:!0,data:{recording:`started`,outPath:e.clientOutPath??n,sessionStateDir:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,showTouches:e.showTouches}}}function Y(e){return{action:`start`,...e.clientOutPath?{requestedFileName:O.basename(e.clientOutPath)}:{},showTouches:e.showTouches}}function X(e){return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:`record is not supported on this device`,hint:e.hint??`Select an Apple, Android, physical HarmonyOS, or web target that supports screen recording.`,details:{reason:e.reason}}}}function Z(e){let t=[Q(e)];if(e.chunks&&e.chunks.length>1&&t.push(...e.chunks.slice(1).map(e=>({field:`chunkPath`,artifactType:`screen-recording-chunk`,path:e.path,localPath:e.clientOutPath,fileName:O.basename(e.clientOutPath??e.path)}))),e.telemetryPath){let n=e.clientOutPath?D(e.clientOutPath):void 0;t.push({field:`telemetryPath`,artifactType:`screen-recording-telemetry`,path:e.telemetryPath,localPath:n,fileName:O.basename(e.telemetryPath)})}return{ok:!0,data:{recording:`stopped`,outPath:e.outPath,telemetryPath:e.telemetryPath,artifacts:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,durationMs:Math.max(0,e.completedAt-e.startedAt),...e.capturedDurationMs===void 0?{}:{capturedDurationMs:e.capturedDurationMs},...e.stopObservation===void 0?{}:{recorder:e.stopObservation.recorder},...e.nativePathDisposition===void 0?{}:{nativePathDisposition:e.nativePathDisposition},showTouches:e.showTouches,warning:e.warning,overlayWarning:e.overlayWarning,chunks:e.chunks?.map(e=>({index:e.index,path:e.clientOutPath??e.path}))}}}function Q(e){return{field:`outPath`,artifactType:`screen-recording`,path:e.outPath,localPath:e.clientOutPath,fileName:O.basename(e.clientOutPath??e.outPath)}}async function ne(e){try{return await re(e)}catch(e){return{ok:!1,error:t(e)}}}async function re(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n),{plan:a,scope:o}=ie(t,i);if(a.kind===`start`&&!f(o)&&!i)return q(t);let s=await ae(e,i),{session:c}=s;return a.kind===`start`?await oe(e,c,G(t),a.use,s.needsReadiness):await le(e,c,a.kind,s.needsReadiness)}function ie(e,t){let n=K(e.flags?.recordingScope);return{scope:n,plan:s({action:e.positionals?.[0],scope:n,hasLiveHandle:t?.screenRecording!==void 0})}}async function ae(e,t){let n=t?.device??await v(e.req.flags??{});return await e.retainDeviceExecutionLock(n.id),t?{session:t,needsReadiness:!1}:{session:fe(e,n),needsReadiness:!0}}async function oe(e,t,n,r,i){if(t.screenRecording)return{ok:!1,error:{code:`INVALID_ARGS`,message:`recording already in progress`}};let a=await e.bindDevice(t.device,o);i&&await _(a);let s=a.facts.screenRecordingStart;if(!s.available)return X(s);let c=await e.bindDevice(t.device,r),{fence:l,outputPaths:u}=$(e,t),d=await c.operations.screenRecordingStart(se(e,t,n,l,u.outputPath));await x({admissionLedger:e.admissionLedger,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore,device:t.device,owner:c.owner,fence:l,...d,throwIfCanceled:e.throwIfCanceled});let f=e.sessionStore.get(e.sessionName)?.screenRecording;if(!f)throw TypeError(`Screen recording adoption did not publish a live handle`);let m=f.handle.inspect();return p(e.sessionStore,t,e.req,e.req.command,Y(m)),J(m,e.sessionStore.ensureSessionDir(e.sessionName),u.requestedPath)}function $(e,t){let n=S.resourcePath(e.sessionStore,e.sessionName);return{fence:S.createNextFence({admissionLedger:e.admissionLedger,resourcePath:n,device:t.device}),outputPaths:h({requestedPath:e.req.positionals?.[1],platform:t.device.platform,cwd:e.req.meta?.cwd})}}function se(e,t,n,r,i){return{sessionId:e.sessionName,outputPath:i,clientOutputPath:e.req.meta?.clientArtifactPaths?.outPath,scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:n.hideTouchesRequested,recordOnlySession:t.recordOnlySession===!0,activeSessionApp:ce(t),exportQuality:n.exportQuality,fps:n.fps,fence:r}}function ce(e){if(e.appBundleId)return{bundleId:e.appBundleId,...e.appName?{name:e.appName}:{}}}async function le(e,t,n,r){let i;try{i=n===`stop-live`?{completion:await w({intent:`capture`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore}),recordsSessionAction:!0}:await de(e,t,r)}catch(n){throw ue(e,t),n}let a=i.completion,o=Z(a);return i.recordsSessionAction&&p(e.sessionStore,t,e.req,e.req.command,{action:`stop`,outPath:a.outPath,...a.clientOutPath?{requestedFileName:O.basename(a.clientOutPath)}:{},showTouches:a.showTouches}),t.recordOnlySession&&e.sessionStore.delete(e.sessionName),o}function ue(e,t){t.recordOnlySession&&M(e)&&e.sessionStore.delete(e.sessionName)}async function de(t,n,r){let i=j({sessionName:t.sessionName,sessionStore:t.sessionStore,device:n.device});if(i.kind===`completed`)return{completion:i.completion,recordsSessionAction:!1};if(i.kind===`none`)throw new e(`INVALID_ARGS`,`no active recording`);return{completion:await T({resourcePath:i.resourcePath,scope:t.requestScope,acquireControl:async(e,i)=>{let a=await t.bindExactDevice(n.device,e.owner,e.fence,c,i);return r&&await _(a),E({runtime:a,dispose:async()=>{}})}}),recordsSessionAction:!0}}function fe(e,t){return{name:e.sessionName,sessionScope:y(e.req),device:t,createdAt:Date.now(),recordOnlySession:!0,actions:[]}}export{ne as t};
1
+ import{O as e,R as t}from"./sdk-contracts.js";import{l as n}from"./capture.js";import{_ as r}from"./sdk-batch-runner.js";import{A as i,D as a}from"./sdk-device.js";import{D as o,E as s,O as c}from"./sdk-batch.js";import{i as l,n as u}from"./recording-export-quality.js";import{n as d,r as f}from"./recording-scope.js";import{c as p}from"./session-store.js";import{r as m}from"./diagnostics.js";import"./diagnostics2.js";import{i as h}from"./output-path.js";import{i as ee,n as g}from"./recording-stop-observation.js";import{n as _}from"./request-runtime-binding.js";import{n as v}from"./dispatch-resolve.js";import"./screen-recording-admission-ledger.js";import{a as y,t as b}from"./session-routing.js";import{a as x,c as S,i as C,o as w,s as T,t as E}from"./screen-recording-resource-recovery.js";import{t as D}from"./telemetry.js";import O from"node:path";import k from"node:fs";const A=[`clientOutPath`,`telemetryPath`,`warning`,`overlayWarning`];function j(e){let{resourcePath:t,record:n}=N(e);if(n.status!==`decoded`)return{kind:`none`};if(P(e,n.envelope),n.envelope.lifecycle!==`completed`)return{kind:`open`,resourcePath:t};let r=F(n.envelope.metadata);return r===void 0?(m({level:`warn`,phase:`screen_recording_completed_manifest_unreplayable`,data:{resourcePath:t}}),{kind:`none`}):k.existsSync(r.outPath)?{kind:`completed`,completion:r}:{kind:`none`}}function M(e){let{record:t}=N(e);return t.status===`decoded`&&t.envelope.lifecycle===`completed`}function N(e){let t=S.resourcePath(e.sessionStore,e.sessionName);return{resourcePath:t,record:S.store.read(t)}}function P(t,n){if(n.sessionId!==t.sessionName)throw new e(`COMMAND_FAILED`,`Screen recording recovery record does not belong to the requested session`,{reason:`runtime-contract-invalid`});if(!i(n.device,a(t.device)))throw new e(`COMMAND_FAILED`,`Screen recording recovery device does not match the selected device`,{reason:`runtime-contract-invalid`})}function F(e){let t=e?.[C];if(!(!r(t)||!I(t)||!L(t)||!R(t)))return t}function I(e){return z(e.outPath)&&z(e.backend)&&V(e.startedAt)&&V(e.completedAt)&&(e.capturedDurationMs===void 0||V(e.capturedDurationMs))&&d(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function L(e){return A.every(t=>B(e[t]))&&te(e.activeSessionApp)&&W(e.chunks)}function R(e){return(e.stopObservation===void 0||g(e.stopObservation))&&(e.nativePathDisposition===void 0||ee(e.nativePathDisposition))}function z(e){return typeof e==`string`&&e.length>0}function B(e){return e===void 0||z(e)}function V(e){return typeof e==`number`&&Number.isFinite(e)}function H(e){return!r(e)||!z(e.bundleId)?!1:B(e.name)}function te(e){return e===void 0||H(e)}function U(e){return Array.isArray(e)&&e.every(e=>r(e)&&Number.isFinite(e.index)&&z(e.path)&&B(e.clientOutPath))}function W(e){return e===void 0||U(e)}function G(t){let r=n(`record`,t.flags);if(r)throw new e(`INVALID_ARGS`,r);let i=t.flags?.fps;if(i!==void 0&&(!Number.isInteger(i)||i<1||i>120))throw new e(`INVALID_ARGS`,`fps must be an integer between 1 and 120`);let a=l(t.flags?.quality);if(t.flags?.quality!==void 0&&a===void 0)throw new e(`INVALID_ARGS`,`quality must be one of: ${u.join(`, `)} (legacy numeric values 5-10 are accepted)`);return{scope:K(t.flags?.recordingScope),...i===void 0?{}:{fps:i},...a===void 0?{}:{exportQuality:a},showTouches:t.flags?.hideTouches!==!0,hideTouchesRequested:t.flags?.hideTouches===!0}}function K(t){if(t===void 0)return`app`;if(t===`app`||t===`device`||t===`system`)return t;throw new e(`INVALID_ARGS`,`record scope must be app, device, or system`)}function q(e){return{ok:!1,error:{code:`INVALID_ARGS`,message:b(e)?`record start with app scope and an explicit session requires an active app session; run open <app> first, or use --scope device to record the full screen`:`record start defaults to app scope and requires an active app session; run open <app> first, or use --scope device to record the full screen`}}}function J(e,t,n){return{ok:!0,data:{recording:`started`,outPath:e.clientOutPath??n,sessionStateDir:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,showTouches:e.showTouches}}}function Y(e){return{action:`start`,...e.clientOutPath?{requestedFileName:O.basename(e.clientOutPath)}:{},showTouches:e.showTouches}}function X(e){return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:`record is not supported on this device`,hint:e.hint??`Select an Apple, Android, physical HarmonyOS, or web target that supports screen recording.`,details:{reason:e.reason}}}}function Z(e){let t=[Q(e)];if(e.chunks&&e.chunks.length>1&&t.push(...e.chunks.slice(1).map(e=>({field:`chunkPath`,artifactType:`screen-recording-chunk`,path:e.path,localPath:e.clientOutPath,fileName:O.basename(e.clientOutPath??e.path)}))),e.telemetryPath){let n=e.clientOutPath?D(e.clientOutPath):void 0;t.push({field:`telemetryPath`,artifactType:`screen-recording-telemetry`,path:e.telemetryPath,localPath:n,fileName:O.basename(e.telemetryPath)})}return{ok:!0,data:{recording:`stopped`,outPath:e.outPath,telemetryPath:e.telemetryPath,artifacts:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,durationMs:Math.max(0,e.completedAt-e.startedAt),...e.capturedDurationMs===void 0?{}:{capturedDurationMs:e.capturedDurationMs},...e.stopObservation===void 0?{}:{recorder:e.stopObservation.recorder},...e.nativePathDisposition===void 0?{}:{nativePathDisposition:e.nativePathDisposition},showTouches:e.showTouches,warning:e.warning,overlayWarning:e.overlayWarning,chunks:e.chunks?.map(e=>({index:e.index,path:e.clientOutPath??e.path}))}}}function Q(e){return{field:`outPath`,artifactType:`screen-recording`,path:e.outPath,localPath:e.clientOutPath,fileName:O.basename(e.clientOutPath??e.outPath)}}async function ne(e){try{return await re(e)}catch(e){return{ok:!1,error:t(e)}}}async function re(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n),{plan:a,scope:o}=ie(t,i);if(a.kind===`start`&&!f(o)&&!i)return q(t);let s=await ae(e,i),{session:c}=s;return a.kind===`start`?await oe(e,c,G(t),a.use,s.needsReadiness):await le(e,c,a.kind,s.needsReadiness)}function ie(e,t){let n=K(e.flags?.recordingScope);return{scope:n,plan:s({action:e.positionals?.[0],scope:n,hasLiveHandle:t?.screenRecording!==void 0})}}async function ae(e,t){let n=t?.device??await v(e.req.flags??{});return await e.retainDeviceExecutionLock(n.id),t?{session:t,needsReadiness:!1}:{session:fe(e,n),needsReadiness:!0}}async function oe(e,t,n,r,i){if(t.screenRecording)return{ok:!1,error:{code:`INVALID_ARGS`,message:`recording already in progress`}};let a=await e.bindDevice(t.device,o);i&&await _(a);let s=a.facts.screenRecordingStart;if(!s.available)return X(s);let c=await e.bindDevice(t.device,r),{fence:l,outputPaths:u}=$(e,t),d=await c.operations.screenRecordingStart(se(e,t,n,l,u.outputPath));await x({admissionLedger:e.admissionLedger,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore,device:t.device,owner:c.owner,fence:l,...d,throwIfCanceled:e.throwIfCanceled});let f=e.sessionStore.get(e.sessionName)?.screenRecording;if(!f)throw TypeError(`Screen recording adoption did not publish a live handle`);let m=f.handle.inspect();return p(e.sessionStore,t,e.req,e.req.command,Y(m)),J(m,e.sessionStore.ensureSessionDir(e.sessionName),u.requestedPath)}function $(e,t){let n=S.resourcePath(e.sessionStore,e.sessionName);return{fence:S.createNextFence({admissionLedger:e.admissionLedger,resourcePath:n,device:t.device}),outputPaths:h({requestedPath:e.req.positionals?.[1],platform:t.device.platform,cwd:e.req.meta?.cwd})}}function se(e,t,n,r,i){return{sessionId:e.sessionName,outputPath:i,clientOutputPath:e.req.meta?.clientArtifactPaths?.outPath,scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:n.hideTouchesRequested,recordOnlySession:t.recordOnlySession===!0,activeSessionApp:ce(t),exportQuality:n.exportQuality,fps:n.fps,fence:r}}function ce(e){if(e.appBundleId)return{bundleId:e.appBundleId,...e.appName?{name:e.appName}:{}}}async function le(e,t,n,r){let i;try{i=n===`stop-live`?{completion:await w({intent:`capture`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore}),recordsSessionAction:!0}:await de(e,t,r)}catch(n){throw ue(e,t),n}let a=i.completion,o=Z(a);return i.recordsSessionAction&&p(e.sessionStore,t,e.req,e.req.command,{action:`stop`,outPath:a.outPath,...a.clientOutPath?{requestedFileName:O.basename(a.clientOutPath)}:{},showTouches:a.showTouches}),t.recordOnlySession&&e.sessionStore.delete(e.sessionName),o}function ue(e,t){t.recordOnlySession&&M(e)&&e.sessionStore.delete(e.sessionName)}async function de(t,n,r){let i=j({sessionName:t.sessionName,sessionStore:t.sessionStore,device:n.device});if(i.kind===`completed`)return{completion:i.completion,recordsSessionAction:!1};if(i.kind===`none`)throw new e(`INVALID_ARGS`,`no active recording`);return{completion:await T({resourcePath:i.resourcePath,scope:t.requestScope,acquireControl:async(e,i)=>{let a=await t.bindExactDevice(n.device,e.owner,e.fence,c,i);return r&&await _(a),E({runtime:a,dispose:async()=>{}})}}),recordsSessionAction:!0}}function fe(e,t){return{name:e.sessionName,sessionScope:y(e.req),device:t,createdAt:Date.now(),recordOnlySession:!0,actions:[]}}export{ne as t};
@@ -1,3 +1,3 @@
1
- import{D as e}from"./sdk-contracts.js";import{n as t}from"./path-resolution.js";import"./file.js";import{t as n}from"./shared.js";const r=async({positionals:r,flags:o})=>{if(r[0]!==`contact-sheet`)return!1;if(r.length>2)throw new e(`INVALID_ARGS`,`record contact-sheet accepts one recording path: record contact-sheet <video.mp4> [--out <sheet.png>]`);let s=t(i(r[1])),c=typeof o.out==`string`?t(o.out):void 0,[{createAgentDevice:l,localCommandPolicy:u},{createLocalArtifactAdapter:d}]=await Promise.all([import(`./runtime10.js`),import(`./sdk-io.js`).then(e=>e.n)]),f=await l({backend:{platform:`ios`},artifacts:d(),sessions:{get:e=>({name:e}),set:()=>{}},policy:u()}).recording.contactSheet({video:{kind:`path`,path:s},...c?{out:{kind:`path`,path:c}}:{}});return await n(o,f,()=>a(f)),!0};function i(t){if(t)return t;throw new e(`INVALID_ARGS`,`record contact-sheet requires a recording path: record contact-sheet <video.mp4>`)}function a(e){let t=(e.durationMs/1e3).toFixed(e.durationMs%1e3==0?0:1),n=[e.path,`${e.cells.length} cells over ${t}s (${e.sampledFrameCount} sample times, ${e.decodedFrameCount} frames decoded)`];return e.warning?[...n,e.warning].join(`
1
+ import{O as e}from"./sdk-contracts.js";import{n as t}from"./path-resolution.js";import"./file.js";import{t as n}from"./shared.js";const r=async({positionals:r,flags:o})=>{if(r[0]!==`contact-sheet`)return!1;if(r.length>2)throw new e(`INVALID_ARGS`,`record contact-sheet accepts one recording path: record contact-sheet <video.mp4> [--out <sheet.png>]`);let s=t(i(r[1])),c=typeof o.out==`string`?t(o.out):void 0,[{createAgentDevice:l,localCommandPolicy:u},{createLocalArtifactAdapter:d}]=await Promise.all([import(`./runtime10.js`),import(`./sdk-io.js`).then(e=>e.n)]),f=await l({backend:{platform:`ios`},artifacts:d(),sessions:{get:e=>({name:e}),set:()=>{}},policy:u()}).recording.contactSheet({video:{kind:`path`,path:s},...c?{out:{kind:`path`,path:c}}:{}});return await n(o,f,()=>a(f)),!0};function i(t){if(t)return t;throw new e(`INVALID_ARGS`,`record contact-sheet requires a recording path: record contact-sheet <video.mp4>`)}function a(e){let t=(e.durationMs/1e3).toFixed(e.durationMs%1e3==0?0:1),n=[e.path,`${e.cells.length} cells over ${t}s (${e.sampledFrameCount} sample times, ${e.decodedFrameCount} frames decoded)`];return e.warning?[...n,e.warning].join(`
2
2
  `):n.join(`
3
3
  `)}export{r as recordingCommand};
@@ -1 +1 @@
1
- import{D as e}from"./sdk-contracts.js";import{t}from"./src2.js";import{i as n}from"./src3.js";const r=new Map;function i(e){for(let t of e.platforms){if(r.has(t))throw Error(`PlatformPlugin already registered for platform "${t}"`);r.set(t,e)}}function a(t){let n=r.get(t);if(!n)throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform: ${t}`);return n}function o(e){return r.get(e)}const s=[t,{id:`android`,platforms:[`android`],providers:{platformGatedResolvers:[`androidAdbProvider`]},createInteractor:async(e,t)=>{let{createAndroidInteractor:n}=await import(`./android.js`).then(e=>e.t);return n(e,void 0,t)}},{id:`harmonyos`,platforms:[`harmonyos`],createInteractor:async(e,t)=>{let{createHarmonyInteractor:n}=await import(`./harmonyos.js`);return n(e,t)}},n,{id:`linux`,platforms:[`linux`],providers:{platformGatedResolvers:[`linuxToolProvider`]},createInteractor:async()=>{let{createLinuxInteractor:e}=await import(`./linux.js`);return e()}},{id:`web`,platforms:[`web`],providers:{platformGatedResolvers:[`webProvider`]},createInteractor:async()=>{let{createWebInteractor:e}=await import(`./web2.js`);return await e()}}];let c=!1;function l(){if(!c){for(let e of s)i(e);c=!0}}export{a as n,o as r,l as t};
1
+ import{O as e}from"./sdk-contracts.js";import{t}from"./src2.js";import{i as n}from"./src3.js";const r=new Map;function i(e){for(let t of e.platforms){if(r.has(t))throw Error(`PlatformPlugin already registered for platform "${t}"`);r.set(t,e)}}function a(t){let n=r.get(t);if(!n)throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform: ${t}`);return n}function o(e){return r.get(e)}const s=[t,{id:`android`,platforms:[`android`],providers:{platformGatedResolvers:[`androidAdbProvider`]},createInteractor:async(e,t)=>{let{createAndroidInteractor:n}=await import(`./android.js`).then(e=>e.t);return n(e,void 0,t)}},{id:`harmonyos`,platforms:[`harmonyos`],createInteractor:async(e,t)=>{let{createHarmonyInteractor:n}=await import(`./harmonyos.js`);return n(e,t)}},n,{id:`linux`,platforms:[`linux`],providers:{platformGatedResolvers:[`linuxToolProvider`]},createInteractor:async()=>{let{createLinuxInteractor:e}=await import(`./linux.js`);return e()}},{id:`web`,platforms:[`web`],providers:{platformGatedResolvers:[`webProvider`]},createInteractor:async()=>{let{createWebInteractor:e}=await import(`./web2.js`);return await e()}}];let c=!1;function l(){if(!c){for(let e of s)i(e);c=!0}}export{a as n,o as r,l as t};