agent-device 0.21.13 → 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 (244) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.13.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.13.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.13.manifest.json → agent-device-android-snapshot-helper-0.21.14.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +23 -0
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +12 -19
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +19 -15
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +2 -3
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +16 -20
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+GestureExecution.swift +8 -13
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +16 -19
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollDragExecution.swift +8 -24
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +20 -42
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +7 -14
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +17 -17
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +2 -3
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +48 -19
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +0 -1
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +0 -7
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +7 -14
  23. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotCoordinateSpace.swift +16 -19
  24. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +21 -9
  25. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +59 -10
  26. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +12 -10
  27. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +13 -8
  28. package/dist/src/absence-observation-errors.js +1 -1
  29. package/dist/src/adapter.js +1 -1
  30. package/dist/src/adb-executor.js +1 -1
  31. package/dist/src/adb-failure.js +1 -1
  32. package/dist/src/adb-transport.js +1 -1
  33. package/dist/src/agent-browser-provider.js +1 -1
  34. package/dist/src/agent-browser-tool.js +1 -1
  35. package/dist/src/agent-device-client.js +2 -2
  36. package/dist/src/ai-sdk.js +1 -1
  37. package/dist/src/alert-runtime.js +1 -1
  38. package/dist/src/app-catalog.js +1 -1
  39. package/dist/src/app-deployment-resolution.js +1 -1
  40. package/dist/src/app-inventory.js +1 -1
  41. package/dist/src/app-launch.js +1 -1
  42. package/dist/src/app-lifecycle.js +1 -1
  43. package/dist/src/app-lifecycle2.js +1 -1
  44. package/dist/src/app-log-files.js +1 -1
  45. package/dist/src/app-log-runtime2.js +1 -1
  46. package/dist/src/app-resolution.js +2 -2
  47. package/dist/src/apple-runner-platform.js +1 -1
  48. package/dist/src/application-lifecycle-interaction.js +1 -1
  49. package/dist/src/archive.js +1 -1
  50. package/dist/src/artifact-download.js +1 -1
  51. package/dist/src/auth-session.js +1 -1
  52. package/dist/src/auth.js +1 -1
  53. package/dist/src/backend-snapshot-options.js +1 -1
  54. package/dist/src/boot-diagnostics.js +1 -1
  55. package/dist/src/capture-disclosure.js +1 -1
  56. package/dist/src/capture.js +1 -1
  57. package/dist/src/cli-config.js +1 -1
  58. package/dist/src/cli-help.js +2 -2
  59. package/dist/src/cli.js +4 -4
  60. package/dist/src/click-button.js +1 -1
  61. package/dist/src/client-metro.js +1 -1
  62. package/dist/src/clipboard-shell-response.js +1 -1
  63. package/dist/src/command-schema.js +1 -1
  64. package/dist/src/command-tools.js +2 -2
  65. package/dist/src/connection-runtime.js +1 -1
  66. package/dist/src/connection.js +1 -1
  67. package/dist/src/contracts.js +1 -1
  68. package/dist/src/daemon-client-lifecycle.js +1 -1
  69. package/dist/src/daemon.js +1 -1
  70. package/dist/src/debug-symbols-facade.js +1 -1
  71. package/dist/src/device-claim-rule.js +2 -2
  72. package/dist/src/device-inventory-context.js +1 -1
  73. package/dist/src/device-rotation.js +1 -1
  74. package/dist/src/device-selection-resolver.js +1 -1
  75. package/dist/src/device-session.js +1 -1
  76. package/dist/src/device-shell.js +1 -1
  77. package/dist/src/device2.js +1 -1
  78. package/dist/src/devicectl.js +1 -1
  79. package/dist/src/diagnostics.js +1 -1
  80. package/dist/src/dispatch-resolve.js +1 -1
  81. package/dist/src/doctor2.js +1 -1
  82. package/dist/src/engine-eval-script.js +1 -1
  83. package/dist/src/error.js +1 -1
  84. package/dist/src/exec.js +1 -1
  85. package/dist/src/file.js +1 -1
  86. package/dist/src/find.js +1 -1
  87. package/dist/src/format.js +1 -1
  88. package/dist/src/gesture-plan.js +1 -1
  89. package/dist/src/gesture-runtime.js +1 -1
  90. package/dist/src/harmonyos.js +1 -1
  91. package/dist/src/helper.js +1 -1
  92. package/dist/src/human-control-contract.js +1 -1
  93. package/dist/src/human-control.js +1 -1
  94. package/dist/src/index.js +1 -1
  95. package/dist/src/input-actions.js +1 -1
  96. package/dist/src/input-actions2.js +1 -1
  97. package/dist/src/install-artifact-facade.js +1 -1
  98. package/dist/src/install-source-network-transport.js +1 -1
  99. package/dist/src/install-source2.js +1 -1
  100. package/dist/src/interaction-positionals.js +1 -1
  101. package/dist/src/interaction-ref-policy.js +1 -1
  102. package/dist/src/interaction2.js +1 -1
  103. package/dist/src/interactor-operation-binding.js +1 -1
  104. package/dist/src/interactor.js +1 -1
  105. package/dist/src/interactor2.js +1 -1
  106. package/dist/src/interactors.js +1 -1
  107. package/dist/src/internal/bin.js +1 -1
  108. package/dist/src/internal/daemon.js +2 -2
  109. package/dist/src/internal/png-worker.js +1 -1
  110. package/dist/src/internal/run-script-http-child.js +1 -1
  111. package/dist/src/inventory.js +1 -1
  112. package/dist/src/inventory2.js +1 -1
  113. package/dist/src/inventory3.js +1 -1
  114. package/dist/src/inventory5.js +1 -1
  115. package/dist/src/ios-snapshot-runtime.js +1 -1
  116. package/dist/src/lease.js +1 -1
  117. package/dist/src/limrun-download-file.js +1 -1
  118. package/dist/src/limrun-runtime-dependencies.js +1 -1
  119. package/dist/src/linux.js +1 -1
  120. package/dist/src/location-coordinates.js +1 -1
  121. package/dist/src/managed-device-scope.js +1 -1
  122. package/dist/src/mechanics.js +5 -5
  123. package/dist/src/multitouch-support.js +1 -1
  124. package/dist/src/native-build-cache.js +1 -0
  125. package/dist/src/observation.js +1 -1
  126. package/dist/src/parameterized-recorded-fill.js +1 -1
  127. package/dist/src/perf-facade.js +1 -1
  128. package/dist/src/perf-runtime-operation-builder.js +1 -1
  129. package/dist/src/perf-runtime-plan.js +1 -1
  130. package/dist/src/perf-target.js +2 -2
  131. package/dist/src/perf.js +1 -1
  132. package/dist/src/physical-device-control.js +1 -1
  133. package/dist/src/platform-runtime-host.js +1 -1
  134. package/dist/src/platform-runtime-managed-owner.js +1 -1
  135. package/dist/src/platform-runtime-open-target.js +1 -1
  136. package/dist/src/platform-runtime-operation-host.js +2 -2
  137. package/dist/src/platform-runtime-runtime-hints.js +1 -1
  138. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  139. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  140. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
  141. package/dist/src/platform-runtime.js +1 -1
  142. package/dist/src/platform-runtime2.js +1 -1
  143. package/dist/src/png-crop-bytes.js +1 -1
  144. package/dist/src/png-size.js +1 -1
  145. package/dist/src/png-worker-client.js +1 -1
  146. package/dist/src/png.js +1 -1
  147. package/dist/src/prepare-kind.js +1 -1
  148. package/dist/src/provider-session-ownership.js +1 -1
  149. package/dist/src/provider-webdriver.js +1 -1
  150. package/dist/src/proxy.js +1 -1
  151. package/dist/src/quality-warnings.js +1 -1
  152. package/dist/src/react-native.js +1 -1
  153. package/dist/src/record-runtime.js +1 -1
  154. package/dist/src/recording.js +1 -1
  155. package/dist/src/register-builtins.js +1 -1
  156. package/dist/src/registry.js +13 -13
  157. package/dist/src/remote-config2.js +1 -1
  158. package/dist/src/replay-divergence.js +1 -1
  159. package/dist/src/replay.js +1 -1
  160. package/dist/src/reporting.js +1 -1
  161. package/dist/src/request-admission.js +1 -1
  162. package/dist/src/request-cancel.js +1 -1
  163. package/dist/src/request-runtime-binding.js +1 -1
  164. package/dist/src/retry.js +1 -1
  165. package/dist/src/runner-cache-metadata.js +1 -1
  166. package/dist/src/runner-client.js +1 -1
  167. package/dist/src/runner-dev-tools-security.js +1 -1
  168. package/dist/src/runner-device-readiness.js +1 -1
  169. package/dist/src/runner-disposal.js +1 -1
  170. package/dist/src/runner-error-classification.js +2 -2
  171. package/dist/src/runner.js +1 -1
  172. package/dist/src/runtime-transport-hints.js +1 -1
  173. package/dist/src/runtime.js +3 -3
  174. package/dist/src/runtime10.js +2 -2
  175. package/dist/src/runtime2.js +1 -1
  176. package/dist/src/runtime3.js +1 -1
  177. package/dist/src/runtime4.js +5 -5
  178. package/dist/src/runtime5.js +1 -1
  179. package/dist/src/runtime6.js +1 -1
  180. package/dist/src/runtime7.js +1 -1
  181. package/dist/src/runtime8.js +1 -1
  182. package/dist/src/runtime9.js +1 -1
  183. package/dist/src/screen-recording-admission-ledger.js +1 -1
  184. package/dist/src/screen-recording-completion.js +1 -1
  185. package/dist/src/screen-recording-options.js +1 -1
  186. package/dist/src/screen-recording-resource-recovery.js +1 -1
  187. package/dist/src/screenshot-density.js +1 -1
  188. package/dist/src/screenshot-image.js +1 -1
  189. package/dist/src/screenshot-runtime.js +1 -1
  190. package/dist/src/screenshot.js +1 -1
  191. package/dist/src/screenshot3.js +1 -1
  192. package/dist/src/script.js +1 -1
  193. package/dist/src/scroll-command.js +1 -1
  194. package/dist/src/scroll-gesture.js +1 -1
  195. package/dist/src/sdk-batch-runner.js +2 -2
  196. package/dist/src/sdk-batch.js +2 -2
  197. package/dist/src/sdk-contracts.d.ts +21 -2
  198. package/dist/src/sdk-contracts.js +1 -1
  199. package/dist/src/sdk-device.js +1 -1
  200. package/dist/src/sdk-io.js +1 -1
  201. package/dist/src/sdk-remote-config.js +1 -1
  202. package/dist/src/selector-runtime.js +1 -1
  203. package/dist/src/server.js +1 -1
  204. package/dist/src/session-allocation.js +1 -1
  205. package/dist/src/session-routing.js +1 -1
  206. package/dist/src/session-runtime-admission.js +1 -1
  207. package/dist/src/session-snapshot.js +1 -1
  208. package/dist/src/session-store.js +2 -2
  209. package/dist/src/session2.js +3 -3
  210. package/dist/src/settings.js +1 -1
  211. package/dist/src/simctl.js +1 -1
  212. package/dist/src/simulator-state.js +1 -1
  213. package/dist/src/simulator.js +1 -1
  214. package/dist/src/snapshot-runtime-binding.js +1 -1
  215. package/dist/src/snapshot-runtime.js +1 -1
  216. package/dist/src/snapshot-state.js +1 -1
  217. package/dist/src/snapshot2.js +1 -1
  218. package/dist/src/snapshot3.js +1 -1
  219. package/dist/src/snapshot4.js +1 -1
  220. package/dist/src/src.js +1 -1
  221. package/dist/src/src7.js +1 -1
  222. package/dist/src/src8.js +2 -2
  223. package/dist/src/string-enum.js +1 -1
  224. package/dist/src/takeover.js +1 -1
  225. package/dist/src/text-entry-focus.js +1 -1
  226. package/dist/src/tool-provider-facade.js +1 -1
  227. package/dist/src/tool-provider.js +2 -2
  228. package/dist/src/tool-provider2.js +1 -1
  229. package/dist/src/touch-runtime.js +1 -1
  230. package/dist/src/transport.js +1 -1
  231. package/dist/src/tv-remote.js +1 -1
  232. package/dist/src/type-text-runtime.js +1 -1
  233. package/dist/src/verified-file.js +1 -1
  234. package/dist/src/video.js +1 -1
  235. package/dist/src/viewport.js +1 -1
  236. package/dist/src/web.js +1 -1
  237. package/dist/src/web2.js +1 -1
  238. package/dist/src/webdriver-source.js +1 -1
  239. package/package.json +1 -1
  240. package/server.json +2 -2
  241. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.13.apk.sha256 +0 -1
  242. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.13.apk +0 -0
  243. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.13.apk.sha256 +0 -1
  244. package/dist/src/snapshot-process.js +0 -1
@@ -1,2 +1,2 @@
1
- import{D as e,F as t,j as n,k as r}from"./sdk-contracts.js";import{i}from"./recording-export-quality.js";import{_ as a,a as o,d as s,f as c,g as l,i as u,o as d,p as f,r as p,t as ee,v as te,x as m,y as ne}from"./runtime.js";import{r as h}from"./success-text.js";import{n as re,t as ie}from"./app-inventory.js";import"./app-inventory-contract.js";import{D as ae}from"./owner-identity.js";import{c as oe}from"./exec.js";import"./file.js";import{r as se}from"./tv-remote.js";import"./command.js";import{r as g}from"./version.js";import{t as ce}from"./keyboard-actions.js";import{i as le}from"./quality-warnings.js";import{i as ue}from"./png-worker-client.js";import{r as _}from"./png.js";import{t as de}from"./png-size.js";import{i as v,n as fe,r as pe}from"./screenshot-overlay-draw.js";import{t as me}from"./png-encode.js";import{r as y}from"./artifact-paths.js";import{t as he}from"./mp4-duration.js";import{c as b,o as ge,r as _e,s as ve}from"./video.js";import x from"node:path";import S from"node:fs";import ye from"node:os";function C(e,t){if(e!==void 0)return w(e,t)}function w(t,n){let r=t?.trim();if(!r)throw new e(`INVALID_ARGS`,`${n} must be a non-empty string`);return r}const be=async(t,n={})=>{if(!t.backend.listDevices)throw new e(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await t.backend.listDevices(f(t,n),n.filter)}},xe=async(t,n={})=>{if(!t.backend.bootDevice)throw new e(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let r=D(n.target),i=await t.backend.bootDevice(f(t,n),r),a=c(i);return{kind:`deviceBooted`,...r?{target:r}:{},...a?{backendResult:a}:{},...h(`Booted device`)}},Se=async(t,n={})=>{if(!t.backend.shutdownDevice)throw new e(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let r=D(n.target),i=await t.backend.shutdownDevice(f(t,n),r),a=c(i);return{kind:`deviceShutdown`,...r?{target:r}:{},...a?{backendResult:a}:{},...h(`Shutdown device`)}},Ce=async(e,t)=>await T(e,t,`install`),we=async(e,t)=>await T(e,t,`reinstall`),Te=async(e,t)=>await T(e,t,`installFromSource`);async function T(t,n,r){let i=r===`reinstall`?`reinstallApp`:`installApp`,a=t.backend[i];if(!a)throw new e(`UNSUPPORTED_OPERATION`,`admin.${r} is not supported by this backend`);let o=`app`in n&&n.app!==void 0?w(n.app,`app`):void 0;if(r!==`installFromSource`&&!o)throw new e(`INVALID_ARGS`,`admin.${r} requires app`);let s=f(t,n),c=await Ee(t,s,n.source);try{let e=await a.call(t.backend,s,{...o?{app:o}:{},source:c.source});return ke(r,o,c.source,e)}finally{await c.cleanup?.()}}async function Ee(e,t,n){let r=await De(e,E(n));try{return{source:E(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function De(e,t){if(t.kind===`url`)return{source:t};let n=await u(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function E(t){if(!t||typeof t!=`object`)throw new e(`INVALID_ARGS`,`install source is required`);if(t.kind===`path`)return{kind:`path`,path:w(t.path,`source.path`)};if(t.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:w(t.id,`source.id`)};if(t.kind===`url`){let e=w(t.url,`source.url`);return Oe(e),{kind:`url`,url:e}}throw new e(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function Oe(t){let n;try{n=new URL(t)}catch{throw new e(`INVALID_ARGS`,`Invalid install source URL: ${t}`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new e(`INVALID_ARGS`,`Install source URL must use http or https`)}function D(e){if(!e)return;let t=C(e.id,`target.id`),n=C(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function ke(e,t,n,r){let i=c(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=O(r,`appName`),s=O(r,`appId`),l=O(r,`bundleId`),u=O(r,`packageName`),d=O(r,`launchTarget`),f=O(r,`installablePath`),p=O(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...l?{bundleId:l}:{},...u?{packageName:u}:{},...d?{launchTarget:d}:{},...f?{installablePath:f}:{},...p?{archivePath:p}:{},...i?{backendResult:i}:{},...h(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??d??t??Ae(n)}`)}}function O(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function Ae(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const je=/^[A-Za-z0-9_.:-]{1,64}$/,Me=async(t,n)=>{if(!t.backend.openApp)throw new e(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let r=Re(n),i=await t.backend.openApp(A(t,n),r,{launchArgs:n.launchArgs,relaunch:n.relaunch}),a=c(i);return{kind:`appOpened`,target:r,relaunch:n.relaunch===!0,...a?{backendResult:a}:{},...h(`Opened: ${Be(r)}`)}},Ne=async(t,n={})=>{if(!t.backend.closeApp)throw new e(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let r=C(n.app,`app`),i=await t.backend.closeApp(A(t,n),r),a=c(i);return{kind:`appClosed`,...r?{app:r}:{},...a?{backendResult:a}:{},...h(r?`Closed: ${r}`:`Closed app`)}},Pe=async(t,n={})=>{if(!t.backend.listApps)throw new e(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await t.backend.listApps(A(t,n),ie(n.filter))}},Fe=async(t,n)=>{if(!t.backend.getAppState)throw new e(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let r=w(n.app,`app`);return{kind:`appState`,app:r,state:await t.backend.getAppState(A(t,n),r)}},Ie=async(t,n)=>{if(!t.backend.pushFile)throw new e(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let r=w(n.app,`app`),i=await Ve(t,n.input);try{let e=await t.backend.pushFile(A(t,n),i.backendInput,r),a=c(e);return{kind:`appPushed`,app:r,inputKind:i.inputKind,...a?{backendResult:a}:{},...h(`Pushed to ${r}`)}}finally{await i.cleanup?.()}},Le=async(t,n)=>{if(!t.backend.triggerAppEvent)throw new e(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let r=He(n.name);Ue(n.payload,`apps.triggerEvent payload for "${r}"`);let i=await t.backend.triggerAppEvent(A(t,n),{name:r,...n.payload?{payload:n.payload}:{}}),a=c(i);return{kind:`appEventTriggered`,name:r,...n.payload?{payload:n.payload}:{},...a?{backendResult:a}:{},...h(`Triggered app event: ${r}`)}};function Re(t){let n=C(t.app,`app`),r=C(t.appId,`appId`),i=C(t.bundleId,`bundleId`),a=C(t.packageName,`packageName`),o=C(t.url,`url`),s=C(t.activity,`activity`),c={...n?{app:n}:{},...r?{appId:r}:{},...i?{bundleId:i}:{},...a?{packageName:a}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!ze(c))throw new e(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function ze(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function Be(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function Ve(t,n){if(!n||typeof n!=`object`)throw new e(`INVALID_ARGS`,`apps.push requires an input`);if(n.kind===`json`)return k(n.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:n.payload},inputKind:`json`};let r=await u(t,n,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:r.path},inputKind:`file`,...r.cleanup?{cleanup:r.cleanup}:{}}}function He(t){let n=w(t,`name`);if(!je.test(n))throw new e(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return n}function Ue(e,t){e!==void 0&&k(e,t,8192)}function k(t,n,r){if(We(t,n),Buffer.byteLength(Ge(t,n),`utf8`)>r)throw new e(`INVALID_ARGS`,`${n} exceeds ${r} bytes`)}function We(t,n){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`${n} must be a JSON object`)}function Ge(t,n){try{let r=JSON.stringify(t);if(typeof r!=`string`)throw new e(`INVALID_ARGS`,`${n} must be JSON-serializable`);return r}catch{throw new e(`INVALID_ARGS`,`${n} must be JSON-serializable`)}}function A(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const j={open:Me,close:Ne,list:Pe,state:Fe,push:Ie,triggerEvent:Le},Ke={devices:be,boot:xe,shutdown:Se,install:Ce,reinstall:we,installFromSource:Te};function qe(e){return{...s(j,e),list:(t={})=>j.list(e,{...t,filter:re(t.filter)})}}const Je=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,Ye=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function Xe(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(Ye,()=>(t=!0,`[REDACTED]`)),n=Qe(n,()=>{t=!0}),{value:n,redacted:t}}function Ze(e){try{let t=new URL(e),n=$e(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Qe(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=Ze(e);return n?(n.redacted&&t(),n.value):e}):e}function $e(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Je.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const M=2048,N=4096,P=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function et(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function tt(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?rt(e.url):void 0,i=t===`headers`||t===`all`?F(e.requestHeaders):void 0,a=t===`headers`||t===`all`?F(e.responseHeaders):void 0,o=t===`body`||t===`all`?I(e.requestBody):void 0,s=t===`body`||t===`all`?I(e.responseBody):void 0,c=L(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function nt(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function F(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(P.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=z(i,M);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function rt(e){return Ze(e)??z(e,M)}function I(e){return e===void 0?{redacted:!1}:it(e)??z(e,M)}function it(e){try{let t=R(JSON.parse(e),Xe);return B(JSON.stringify(t.value),M,t.redacted)}catch{return}}function L(e){return R(e,e=>z(e,M))}function R(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=R(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(P.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=R(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function z(e,t){if(e===void 0)return{redacted:!1};let n=Xe(e);return B(n.value,t,n.redacted)}function B(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const at=async(t,n={})=>{if(!t.backend.readLogs)throw new e(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return et(await t.backend.readLogs(await V(t,n),ct(n)))},ot=async(t,n={})=>{if(!t.backend.dumpNetwork)throw new e(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let r=lt(n);return tt(await t.backend.dumpNetwork(await V(t,n),r),r.include??`summary`)},st=async(t,n={})=>{if(!t.backend.measurePerf)throw new e(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return nt(await t.backend.measurePerf(await V(t,n),ut(n)))};async function V(e,t){let n=f(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function ct(e){return{...H(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:W(e.levels,`levels`)},...e.search===void 0?{}:{search:w(e.search,`search`)},...e.source===void 0?{}:{source:w(e.source,`source`)}}}function lt(e){return{...H(e,25,200,`network limit`),include:dt(e.include)}}function ut(e){return{...U(e),...e.sampleMs===void 0?{}:{sampleMs:m(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:W(e.metrics,`metrics`,20)}}}function H(e,t,n,r){return{...U(e),...e.cursor===void 0?{}:{cursor:w(e.cursor,`cursor`)},limit:e.limit===void 0?t:m(e.limit,r,1,n)}}function U(e){return{...e.since===void 0?{}:{since:w(e.since,`since`)},...e.until===void 0?{}:{until:w(e.until,`until`)}}}function dt(t){if(t===void 0)return`summary`;if(t===`summary`||t===`headers`||t===`body`||t===`all`)return t;throw new e(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function W(t,n,r=50){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`${n} must be an array of strings`);if(t.length>r)throw new e(`INVALID_ARGS`,`${n} must contain at most ${r} entries`);return t.map((e,t)=>w(e,`${n}[${t}]`))}const ft={logs:at,network:ot,perf:st},G=`contact_sheet_frame_extraction_failed`,K=`contact_sheet_no_frames`;function q(t=process.platform){if(t!==`darwin`)throw new e(`UNSUPPORTED_OPERATION`,`Contact sheets can only be built on macOS hosts, which is where the frame decoder runs`,{reason:`contact_sheet_unsupported_host`,hostPlatform:t,hint:`Run this command on the macOS host that recorded the clip, or read the video artifact itself.`})}async function pt(t){if(q(t.hostPlatform??process.platform),t.timesMs.length===0)throw new e(`COMMAND_FAILED`,`Contact sheet sampling requested no frames`,{reason:K,videoPath:t.videoPath});vt(t.signal);let n=await _t(t);vt(t.signal);let r;try{r=await oe(n,[`--input`,t.videoPath,`--output-dir`,t.scratchDir,`--times`,t.timesMs.join(`,`),`--max-width`,String(t.maxWidth)],{timeoutMs:9e4,env:ge(),allowFailure:!0,...t.signal===void 0?{}:{signal:t.signal}})}catch(e){X(e,t.videoPath,`Failed to run the frame decoder`)}if(r.exitCode!==0)throw new e(`COMMAND_FAILED`,`Failed to extract frames from the recording: ${gt(r.stderr)||`exit ${r.exitCode}`}`,{reason:G,videoPath:t.videoPath,exitCode:r.exitCode});let i=mt(r.stdout,t.videoPath,t.scratchDir,t.timesMs.length);if(i.frames.length===0)throw new e(`COMMAND_FAILED`,`The recording returned no decodable frames for a contact sheet`,{reason:K,videoPath:t.videoPath,skippedSampleCount:i.skippedSampleCount});return i}function mt(e,t,n,r){let i;try{i=JSON.parse(e)}catch(e){throw Y(t,`invalid manifest: ${String(e)}`)}let a=Z(i).frames;if(!Array.isArray(a))throw Y(t,`manifest has no frames array`);let o=Z(i).skipped;if(a.length>r)throw Y(t,`returned ${a.length} frames for ${r} requested samples`);let s=a.flatMap(e=>{let r=Z(e),i=ht(r.path),a=Q(r.actualTimeMs);if(i===void 0||a===void 0||a<0)throw Y(t,`frame entry is missing a path or presentation time`);let o=x.resolve(n,x.basename(i));return S.existsSync(o)?[{requestedTimeMs:Q(r.requestedTimeMs)??a,actualTimeMs:a,path:o}]:[]});return{frames:s.sort((e,t)=>e.actualTimeMs-t.actualTimeMs),skippedSampleCount:Math.max(Array.isArray(o)?o.length:0,r-s.length)}}function J(t,n,r){return new e(`COMMAND_FAILED`,t,{reason:G,videoPath:n},r)}function Y(e,t){return J(`Frame extraction returned an unreadable manifest: ${t}`,e)}function X(r,i,a){throw t(r)||r instanceof e&&r.code===`COMMAND_FAILED`&&r.details?.reason?r:J(`${a} for ${i}: ${n(r)}`,i,r)}function Z(e){return typeof e==`object`&&e?e:{}}function ht(e){return typeof e==`string`&&e!==``?e:void 0}function Q(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function gt(e){return(e.trim().split(`
2
- `).pop()??``).trim()}async function _t(e){try{return await ve({sourcePath:b(`recording-frames.swift`,g()),extraSourcePaths:[b(`RecordingExportSupport.swift`,g())],cacheName:`recording-frames`,timeoutMs:12e4})}catch(t){X(t,e.videoPath,`Could not build the frame decoder`)}}function vt(e){if(e?.aborted)throw r()}function yt(t,n){if(t===void 0||!Number.isFinite(t)||t<0)throw new e(`COMMAND_FAILED`,`Cannot plan a contact sheet: the video timeline of ${n} could not be read`,{reason:`contact_sheet_duration_unknown`,videoPath:n,hint:`Retry once the recording finished finalizing; a clip whose container is still being written has no readable duration.`});if(t<=250)return{durationMs:t,timesMs:t>0?[0,Math.round(t)]:[0]};let r=Math.min(48,Math.floor(t/250)+1),i=t/(r-1);return{durationMs:t,timesMs:Array.from({length:r},(e,t)=>Math.round(t*i))}}const bt=[360,320,280,240,200,160],xt=[255,255,255,255],St=[17,24,39,255],$=pe(2)+8;function Ct(t){let{cells:n}=t;if(n.length===0)throw new e(`COMMAND_FAILED`,`Contact sheet has no cells to render`);let r=Tt(n[0].image.height/Math.max(1,n[0].image.width),n.length,t),i=Ot(r.width,r.height,St);return n.forEach((e,t)=>{let n=t%r.columns,a=Math.floor(t/r.columns);wt(i,8+n*(r.cellWidth+8),8+a*($+r.cellHeight+8),e,r.cellWidth,r.cellHeight)}),{bytes:me(i.data,r.width,r.height,4),width:r.width,height:r.height,cellWidth:r.cellWidth}}function wt(e,t,n,r,i,a){fe(e,{x:t+4,y:n+4,text:jt(r.timeMs),color:xt,scale:2}),kt(e,le(At(r.image),i,a),t,n+$)}function Tt(t,n,r){let i=Et(t,n,r.maxPixels);if(i)return i;let a=Dt(t,n,160);throw new e(`COMMAND_FAILED`,`Contact sheet would be ${a.width*a.height} pixels, above the configured maxImagePixels limit of ${r.maxPixels}`,{reason:`contact_sheet_pixel_budget_exceeded`,cellCount:r.cells.length,maxPixels:r.maxPixels,hint:`Shorten the recording or raise the command policy maxImagePixels limit.`})}function Et(e,t,n){for(let r of bt){let i=Dt(e,t,r);if(i.width*i.height<=n)return i}}function Dt(e,t,n){let r=Math.min(4,t),i=Math.ceil(t/r),a=Math.max(1,Math.round(n*e));return{columns:r,cellWidth:n,cellHeight:a,width:16+r*n+(r-1)*8,height:16+i*($+a)+(i-1)*8}}function Ot(e,t,n){let r=new _.PNG({width:e,height:t});for(let i=0;i<t;i+=1)for(let t=0;t<e;t+=1)v(r,t,i,n);return r}function kt(e,t,n,r){for(let i=0;i<t.height;i+=1)for(let a=0;a<t.width;a+=1){let o=(i*t.width+a)*4;v(e,n+a,r+i,[t.data[o],t.data[o+1],t.data[o+2],t.data[o+3]])}}function At(e){let t=new _.PNG({width:e.width,height:e.height});return Buffer.from(e.data.buffer,e.data.byteOffset,e.data.byteLength).copy(t.data),t}function jt(e){let t=Math.floor(e/1e3),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=Math.floor(e%1e3);return`${[n,r,i].map(e=>String(e).padStart(2,`0`)).join(`:`)}.${String(a).padStart(3,`0`)}`}function Mt(e,t){if(e.width!==t.width||e.height!==t.height)return{status:`dimension_mismatch`};let n=e.width*e.height;if(n===0)return{status:`compared`,changedPixelRatio:0};if(e.data.length!==t.data.length)return{status:`dimension_mismatch`};let r=0;for(let n=0;n+3<e.data.length;n+=4)(e.data[n]!==t.data[n]||e.data[n+1]!==t.data[n+1]||e.data[n+2]!==t.data[n+2])&&(r+=1);return{status:`compared`,changedPixelRatio:r/n}}function Nt(e,t=.02,n=24){let r=[],i;for(let n of e){let e=i?Ft(i,n.image):1;e<t||(r.push({timeMs:n.timeMs,changedPixelRatio:e,image:n.image}),i=n.image)}Pt(r,e);let a=r.length>n?It(r,n):r;return{cells:a,keptCellCount:r.length,thinned:a.length<r.length}}function Pt(e,t){let n=t.at(-1);if(!n)return;let r=e.at(-1);!r||r.timeMs===n.timeMs||e.push({timeMs:n.timeMs,changedPixelRatio:Ft(r.image,n.image),image:n.image})}function Ft(e,t){let n=Mt(e,t);return n.status===`compared`?n.changedPixelRatio:1}function It(e,t){if(t<=1)return[e.at(-1)];let n=(e.length-1)/(t-1);return Array.from({length:t},(t,r)=>e[Math.round(r*n)])}async function Lt(t){q(t.hostPlatform??process.platform);let n=x.resolve(t.videoPath),r=x.resolve(t.outputPath??y(n));Bt(n,r);let i=await _e(n);if(i!==`mp4`)throw new e(`INVALID_ARGS`,i===`webm`?`Contact sheets need an MP4 recording; ${n} is WebM, whose frames this decoder does not read`:`Contact sheets need an MP4 recording; ${n} is not a readable MP4`,{reason:`contact_sheet_container_unsupported`,videoPath:n,container:i??`unknown`,hint:`Re-record on a backend that exports MP4, or pass the MP4 artifact the recording produced.`});let a=yt(he(n),n),o=S.mkdtempSync(x.join(ye.tmpdir(),`agent-device-contact-sheet-`));try{let e=await pt({videoPath:n,scratchDir:o,timesMs:a.timesMs,maxWidth:360,hostPlatform:t.hostPlatform??process.platform,...t.signal===void 0?{}:{signal:t.signal}}),i=await Rt(e.frames,t.maxPixels);zt(t.signal);let s=Nt(i,t.changedPixelThreshold??.02),c=Ct({cells:s.cells,maxPixels:t.maxPixels});return Gt(r,c.bytes),{path:r,videoPath:n,durationMs:a.durationMs,width:c.width,height:c.height,sampledFrameCount:a.timesMs.length,decodedFrameCount:e.frames.length,skippedSampleCount:e.skippedSampleCount,changedPixelThreshold:t.changedPixelThreshold??.02,cells:s.cells.map(Ut),...Wt(s,e)}}finally{S.rmSync(o,{recursive:!0,force:!0})}}async function Rt(t,n){let r=[];for(let i of t){let t=await de(i.path);if(t.width>360)throw new e(`COMMAND_FAILED`,`Frame extraction returned a ${t.width}px-wide frame when the sheet asked for 360px cells`,{reason:G,framePath:i.path,frameWidth:t.width,frameWidthLimit:360});if(t.width*t.height>n)throw new e(`COMMAND_FAILED`,`Frame extraction returned a ${t.width}x${t.height} frame, above the ${n}-pixel budget for the whole sheet`,{reason:G,framePath:i.path,framePixels:t.width*t.height,maxPixels:n});let a=await ue(S.readFileSync(i.path),`recording frame`);r.push({timeMs:i.actualTimeMs,image:a})}return r}function zt(e){if(e?.aborted)throw r()}function Bt(t,n){if(Vt(t,n)??n===t)throw new e(`INVALID_ARGS`,`A contact sheet cannot be written over the recording it describes: ${n}`,{reason:`contact_sheet_output_collides_with_input`,videoPath:t,outputPath:n,hint:`Choose a different --out path, or omit it to write beside the recording.`})}function Vt(e,t){let n=Ht(e),r=Ht(t);if(n!==void 0&&r!==void 0)return n.dev===r.dev&&n.ino===r.ino}function Ht(e){try{return S.statSync(e)}catch{return}}function Ut(e){return{timeMs:e.timeMs,changedPixelRatio:e.changedPixelRatio}}function Wt(e,t){let n=[];return t.skippedSampleCount>0&&n.push(`${t.skippedSampleCount} sample times returned no frame, so the sheet covers less of the recording than it asked for`),e.thinned&&n.push(`${e.keptCellCount} changes were found and 24 cells are printed, so the sheet thins evenly across the recording instead of showing every change`),n.length===0?{}:{warning:n.join(`; `)}}function Gt(t,n){try{S.mkdirSync(x.dirname(t),{recursive:!0}),ae({destination:t,contents:n})}catch(n){throw new e(`COMMAND_FAILED`,`Failed to write the contact sheet to ${t}: ${n instanceof Error?n.message:String(n)}`,{reason:`contact_sheet_output_write_failed`,outputPath:t})}}const Kt=async(t,n)=>{if(!n.video)throw new e(`INVALID_ARGS`,`record contact-sheet requires a recording to read`);Jt(n.changedPixelThreshold);let r=await u(t,n.video,{usage:`record contact-sheet`,field:`video`}),i;try{let e=qt(n,n.video,r.path);i=await p(t,e,{field:`path`,ext:`.png`,artifactType:`screen-recording-contact-sheet`});let a=await Lt({videoPath:r.path,outputPath:i.path,maxPixels:t.policy.maxImagePixels,...n.changedPixelThreshold===void 0?{}:{changedPixelThreshold:n.changedPixelThreshold},signal:n.signal??t.signal}),o=await i.publish();return{...a,path:Yt(a.path,o),...o?{artifact:o}:{}}}catch(e){throw await i?.cleanup?.(),e}finally{await r.cleanup?.()}};function qt(t,n,r){if(t.out)return t.out;if(n.kind===`path`)return{kind:`path`,path:x.resolve(y(n.path||r))};throw new e(`INVALID_ARGS`,`record contact-sheet needs an output path when the recording is an uploaded artifact`,{hint:"Pass --out <sheet.png> (CLI) or `out` (Node) to name where the sheet is written."})}function Jt(t){if(t!==void 0&&(!Number.isFinite(t)||t<0||t>1))throw new e(`INVALID_ARGS`,`record contact-sheet needs a changedPixelThreshold between 0 and 1, got ${t}`,{reason:`contact_sheet_threshold_invalid`,changedPixelThreshold:t,hint:`Omit it to use the calibrated default, or pass a share of the frame between 0 and 1.`})}function Yt(e,t){return t?t.kind===`localPath`?t.path:t.clientPath??e:e}const Xt=async(t,n)=>{let r=tn(n.action,`record`),i=r===`start`?t.backend.startRecording:t.backend.stopRecording;if(!i)throw new e(`UNSUPPORTED_OPERATION`,`record ${r} is not supported by this backend`);let a=n.out?await p(t,n.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let e=Qt(n,a?.path);return nn(r,await i.call(t.backend,f(t,n),e),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}},Zt=async(t,n)=>{let r=tn(n.action,`trace`),i=r===`start`?t.backend.startTrace:t.backend.stopTrace;if(!i)throw new e(`UNSUPPORTED_OPERATION`,`trace ${r} is not supported by this backend`);let a=n.out?await p(t,n.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let e=a?.path?{outPath:a.path}:{};return rn(r,await i.call(t.backend,f(t,n),e),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}};function Qt(e,t){let n={};t&&(n.outPath=t);let r=$t(e.fps);r!==void 0&&(n.fps=r);let i=en(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function $t(e){return e===void 0?void 0:m(e,`fps`,1,60)}function en(t){if(t===void 0)return;let n=i(t);if(n===void 0)throw new e(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return n}function tn(t,n){if(t===`start`||t===`stop`)return t;throw new e(`INVALID_ARGS`,`${n} action must be start or stop`)}function nn(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...an(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function rn(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...an(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function an(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...h(e===`start`?r.startMessage:r.stopMessage)}}const on={record:Xt,trace:Zt,contactSheet:Kt},sn=async(t,n={})=>{if(!t.backend.pressBack)throw new e(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let r=n.mode??`in-app`;if(r!==`in-app`&&r!==`system`)throw new e(`INVALID_ARGS`,`system.back mode must be in-app or system`);let i=await t.backend.pressBack(f(t,n),{mode:r}),a=c(i);return{kind:`systemBack`,mode:r,...a?{backendResult:a}:{},...h(`Back`)}},cn=async(t,n={})=>{if(!t.backend.pressHome)throw new e(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let r=await t.backend.pressHome(f(t,n)),i=c(r);return{kind:`systemHome`,...i?{backendResult:i}:{},...h(`Home`)}},ln=async(t,n)=>{if(!t.backend.pressTvRemote)throw new e(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let r=se(n.button),i=n.durationMs===void 0?void 0:m(n.durationMs,`durationMs`,0,1e4),a=await t.backend.pressTvRemote(f(t,n),{button:r,...i===void 0?{}:{durationMs:i}}),o=c(a);return{kind:`tvRemotePressed`,button:r,...i===void 0?{}:{durationMs:i},...o?{backendResult:o}:{},...h(`Pressed TV remote ${r}`)}},un=async(t,n)=>{if(!t.backend.setOrientation)throw new e(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let r=gn(n.orientation),i=await t.backend.setOrientation(f(t,n),r),a=c(i);return{kind:`systemOrientationSet`,orientation:r,...a?{backendResult:a}:{},...h(`Rotated to ${r}`)}},dn=async(t,n={})=>{if(!t.backend.setKeyboard)throw new e(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let r=n.action??`status`;if(!ce(r))throw new e(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let i=await t.backend.setKeyboard(f(t,n),{action:r}),a=c(i),o=Tn(i)?i:{};return r===`enter`||r===`return`?vn(o,a):r===`dismiss`?yn(r,o,a):xn(r,o,a)},fn=async(t,n)=>{if(n.action===`read`){if(!t.backend.getClipboard)throw new e(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let r=await t.backend.getClipboard(f(t,n));return{kind:`clipboardText`,action:`read`,text:typeof r==`string`?r:r.text}}if(n.action!==`write`)throw new e(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!t.backend.setClipboard)throw new e(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof n.text!=`string`)throw new e(`INVALID_ARGS`,`system.clipboard write requires text`);let r=await t.backend.setClipboard(f(t,n),n.text),i=c(r);return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(n.text).length,...i?{backendResult:i}:{},...h(`Clipboard updated`)}},pn=async(t,n={})=>{if(!t.backend.openSettings)throw new e(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let r=C(n.target,`target`),i=await t.backend.openSettings(f(t,n),r),a=c(i);return{kind:`settingsOpened`,...r?{target:r}:{},...a?{backendResult:a}:{},...h(r?`Opened settings: ${r}`:`Opened settings`)}},mn=async(t,n={})=>{if(!t.backend.handleAlert)throw new e(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let r=n.action??`get`;if(r!==`get`&&r!==`accept`&&r!==`dismiss`&&r!==`wait`)throw new e(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let i=n.timeoutMs===void 0?void 0:m(n.timeoutMs,`timeoutMs`,0,12e4);return _n(r,await t.backend.handleAlert(f(t,n),r,{timeoutMs:i}))},hn=async(t,n={})=>{if(!t.backend.openAppSwitcher)throw new e(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let r=await t.backend.openAppSwitcher(f(t,n)),i=c(r);return{kind:`appSwitcherOpened`,...i?{backendResult:i}:{},...h(`Opened app switcher`)}};function gn(t){switch(t){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return t;default:throw new e(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function _n(e,t){return e===`get`?Sn(t):e===`wait`?Cn(t):wn(e,t)}function vn(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...h(`Keyboard enter pressed`)}}function yn(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...h(bn(t))}}function bn(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function xn(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function Sn(t){if(t.kind!==`alertStatus`)throw new e(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:t.alert}}function Cn(t){if(t.kind!==`alertWait`)throw new e(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:t.alert,...t.waitedMs===void 0?{}:{waitedMs:t.waitedMs},...t.timedOut===void 0?{}:{timedOut:t.timedOut},...h(t.alert?`Alert visible`:`Alert wait timed out`)}}function wn(t,n){if(n.kind!==`alertHandled`)throw new e(`COMMAND_FAILED`,`system.alert ${t} returned an invalid backend result`);return{kind:`alertHandled`,action:t,handled:n.handled,...n.alert?{alert:n.alert}:{},...n.button?{button:n.button}:{},...h(n.handled?`Alert ${t}ed`:`No alert handled`)}}function Tn(e){return!!(e&&typeof e==`object`)}const En={back:sn,home:cn,orientation:un,keyboard:dn,clipboard:fn,settings:pn,alert:mn,appSwitcher:hn,tvRemote:ln};function Dn(e){return{capture:ee(e),selectors:d(e),interactions:o(e),system:s(En,e),apps:qe(e),admin:s(Ke,e),recording:s(on,e),observability:s(ft,e)}}function On(e){let t=l(e);return{...t,...Dn(t)}}export{On as createAgentDevice,a as createMemorySessionStore,te as localCommandPolicy,ne as restrictedCommandPolicy};
1
+ import{A as e,I as t,M as n,O as r}from"./sdk-contracts.js";import{i}from"./recording-export-quality.js";import{_ as a,a as o,d as s,f as c,g as l,i as u,o as d,p as f,r as p,t as ee,v as te,x as m,y as ne}from"./runtime.js";import{r as h}from"./success-text.js";import{n as re,t as ie}from"./app-inventory.js";import"./app-inventory-contract.js";import{D as ae}from"./owner-identity.js";import{c as oe}from"./exec.js";import"./file.js";import{r as se}from"./tv-remote.js";import"./command.js";import{r as g}from"./version.js";import{t as ce}from"./keyboard-actions.js";import{i as le}from"./quality-warnings.js";import{i as ue}from"./png-worker-client.js";import{r as _}from"./png.js";import{t as de}from"./png-size.js";import{i as v,n as fe,r as pe}from"./screenshot-overlay-draw.js";import{t as me}from"./png-encode.js";import{r as y}from"./artifact-paths.js";import{t as he}from"./mp4-duration.js";import{c as b,o as ge,r as _e,s as ve}from"./video.js";import x from"node:path";import S from"node:fs";import ye from"node:os";function C(e,t){if(e!==void 0)return w(e,t)}function w(e,t){let n=e?.trim();if(!n)throw new r(`INVALID_ARGS`,`${t} must be a non-empty string`);return n}const be=async(e,t={})=>{if(!e.backend.listDevices)throw new r(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(f(e,t),t.filter)}},xe=async(e,t={})=>{if(!e.backend.bootDevice)throw new r(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let n=D(t.target),i=await e.backend.bootDevice(f(e,t),n),a=c(i);return{kind:`deviceBooted`,...n?{target:n}:{},...a?{backendResult:a}:{},...h(`Booted device`)}},Se=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new r(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let n=D(t.target),i=await e.backend.shutdownDevice(f(e,t),n),a=c(i);return{kind:`deviceShutdown`,...n?{target:n}:{},...a?{backendResult:a}:{},...h(`Shutdown device`)}},Ce=async(e,t)=>await T(e,t,`install`),we=async(e,t)=>await T(e,t,`reinstall`),Te=async(e,t)=>await T(e,t,`installFromSource`);async function T(e,t,n){let i=n===`reinstall`?`reinstallApp`:`installApp`,a=e.backend[i];if(!a)throw new r(`UNSUPPORTED_OPERATION`,`admin.${n} is not supported by this backend`);let o=`app`in t&&t.app!==void 0?w(t.app,`app`):void 0;if(n!==`installFromSource`&&!o)throw new r(`INVALID_ARGS`,`admin.${n} requires app`);let s=f(e,t),c=await Ee(e,s,t.source);try{let t=await a.call(e.backend,s,{...o?{app:o}:{},source:c.source});return ke(n,o,c.source,t)}finally{await c.cleanup?.()}}async function Ee(e,t,n){let r=await De(e,E(n));try{return{source:E(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function De(e,t){if(t.kind===`url`)return{source:t};let n=await u(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function E(e){if(!e||typeof e!=`object`)throw new r(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:w(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:w(e.id,`source.id`)};if(e.kind===`url`){let t=w(e.url,`source.url`);return Oe(t),{kind:`url`,url:t}}throw new r(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function Oe(e){let t;try{t=new URL(e)}catch{throw new r(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new r(`INVALID_ARGS`,`Install source URL must use http or https`)}function D(e){if(!e)return;let t=C(e.id,`target.id`),n=C(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function ke(e,t,n,r){let i=c(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=O(r,`appName`),s=O(r,`appId`),l=O(r,`bundleId`),u=O(r,`packageName`),d=O(r,`launchTarget`),f=O(r,`installablePath`),p=O(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...l?{bundleId:l}:{},...u?{packageName:u}:{},...d?{launchTarget:d}:{},...f?{installablePath:f}:{},...p?{archivePath:p}:{},...i?{backendResult:i}:{},...h(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??d??t??Ae(n)}`)}}function O(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function Ae(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const je=/^[A-Za-z0-9_.:-]{1,64}$/,Me=async(e,t)=>{if(!e.backend.openApp)throw new r(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let n=Re(t),i=await e.backend.openApp(A(e,t),n,{launchArgs:t.launchArgs,relaunch:t.relaunch}),a=c(i);return{kind:`appOpened`,target:n,relaunch:t.relaunch===!0,...a?{backendResult:a}:{},...h(`Opened: ${Be(n)}`)}},Ne=async(e,t={})=>{if(!e.backend.closeApp)throw new r(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let n=C(t.app,`app`),i=await e.backend.closeApp(A(e,t),n),a=c(i);return{kind:`appClosed`,...n?{app:n}:{},...a?{backendResult:a}:{},...h(n?`Closed: ${n}`:`Closed app`)}},Pe=async(e,t={})=>{if(!e.backend.listApps)throw new r(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(A(e,t),ie(t.filter))}},Fe=async(e,t)=>{if(!e.backend.getAppState)throw new r(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let n=w(t.app,`app`);return{kind:`appState`,app:n,state:await e.backend.getAppState(A(e,t),n)}},Ie=async(e,t)=>{if(!e.backend.pushFile)throw new r(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let n=w(t.app,`app`),i=await Ve(e,t.input);try{let r=await e.backend.pushFile(A(e,t),i.backendInput,n),a=c(r);return{kind:`appPushed`,app:n,inputKind:i.inputKind,...a?{backendResult:a}:{},...h(`Pushed to ${n}`)}}finally{await i.cleanup?.()}},Le=async(e,t)=>{if(!e.backend.triggerAppEvent)throw new r(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let n=He(t.name);Ue(t.payload,`apps.triggerEvent payload for "${n}"`);let i=await e.backend.triggerAppEvent(A(e,t),{name:n,...t.payload?{payload:t.payload}:{}}),a=c(i);return{kind:`appEventTriggered`,name:n,...t.payload?{payload:t.payload}:{},...a?{backendResult:a}:{},...h(`Triggered app event: ${n}`)}};function Re(e){let t=C(e.app,`app`),n=C(e.appId,`appId`),i=C(e.bundleId,`bundleId`),a=C(e.packageName,`packageName`),o=C(e.url,`url`),s=C(e.activity,`activity`),c={...t?{app:t}:{},...n?{appId:n}:{},...i?{bundleId:i}:{},...a?{packageName:a}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!ze(c))throw new r(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function ze(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function Be(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function Ve(e,t){if(!t||typeof t!=`object`)throw new r(`INVALID_ARGS`,`apps.push requires an input`);if(t.kind===`json`)return k(t.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:t.payload},inputKind:`json`};let n=await u(e,t,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:n.path},inputKind:`file`,...n.cleanup?{cleanup:n.cleanup}:{}}}function He(e){let t=w(e,`name`);if(!je.test(t))throw new r(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${t}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return t}function Ue(e,t){e!==void 0&&k(e,t,8192)}function k(e,t,n){if(We(e,t),Buffer.byteLength(Ge(e,t),`utf8`)>n)throw new r(`INVALID_ARGS`,`${t} exceeds ${n} bytes`)}function We(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be a JSON object`)}function Ge(e,t){try{let n=JSON.stringify(e);if(typeof n!=`string`)throw new r(`INVALID_ARGS`,`${t} must be JSON-serializable`);return n}catch{throw new r(`INVALID_ARGS`,`${t} must be JSON-serializable`)}}function A(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const j={open:Me,close:Ne,list:Pe,state:Fe,push:Ie,triggerEvent:Le},Ke={devices:be,boot:xe,shutdown:Se,install:Ce,reinstall:we,installFromSource:Te};function qe(e){return{...s(j,e),list:(t={})=>j.list(e,{...t,filter:re(t.filter)})}}const Je=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,Ye=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function Xe(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(Ye,()=>(t=!0,`[REDACTED]`)),n=Qe(n,()=>{t=!0}),{value:n,redacted:t}}function Ze(e){try{let t=new URL(e),n=$e(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Qe(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=Ze(e);return n?(n.redacted&&t(),n.value):e}):e}function $e(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Je.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const M=2048,N=4096,P=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function et(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function tt(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?rt(e.url):void 0,i=t===`headers`||t===`all`?F(e.requestHeaders):void 0,a=t===`headers`||t===`all`?F(e.responseHeaders):void 0,o=t===`body`||t===`all`?I(e.requestBody):void 0,s=t===`body`||t===`all`?I(e.responseBody):void 0,c=L(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function nt(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function F(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(P.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=z(i,M);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function rt(e){return Ze(e)??z(e,M)}function I(e){return e===void 0?{redacted:!1}:it(e)??z(e,M)}function it(e){try{let t=R(JSON.parse(e),Xe);return B(JSON.stringify(t.value),M,t.redacted)}catch{return}}function L(e){return R(e,e=>z(e,M))}function R(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=R(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(P.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=R(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function z(e,t){if(e===void 0)return{redacted:!1};let n=Xe(e);return B(n.value,t,n.redacted)}function B(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const at=async(e,t={})=>{if(!e.backend.readLogs)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return et(await e.backend.readLogs(await V(e,t),ct(t)))},ot=async(e,t={})=>{if(!e.backend.dumpNetwork)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let n=lt(t);return tt(await e.backend.dumpNetwork(await V(e,t),n),n.include??`summary`)},st=async(e,t={})=>{if(!e.backend.measurePerf)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return nt(await e.backend.measurePerf(await V(e,t),ut(t)))};async function V(e,t){let n=f(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function ct(e){return{...H(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:W(e.levels,`levels`)},...e.search===void 0?{}:{search:w(e.search,`search`)},...e.source===void 0?{}:{source:w(e.source,`source`)}}}function lt(e){return{...H(e,25,200,`network limit`),include:dt(e.include)}}function ut(e){return{...U(e),...e.sampleMs===void 0?{}:{sampleMs:m(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:W(e.metrics,`metrics`,20)}}}function H(e,t,n,r){return{...U(e),...e.cursor===void 0?{}:{cursor:w(e.cursor,`cursor`)},limit:e.limit===void 0?t:m(e.limit,r,1,n)}}function U(e){return{...e.since===void 0?{}:{since:w(e.since,`since`)},...e.until===void 0?{}:{until:w(e.until,`until`)}}}function dt(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new r(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function W(e,t,n=50){if(!Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be an array of strings`);if(e.length>n)throw new r(`INVALID_ARGS`,`${t} must contain at most ${n} entries`);return e.map((e,n)=>w(e,`${t}[${n}]`))}const ft={logs:at,network:ot,perf:st},G=`contact_sheet_frame_extraction_failed`,K=`contact_sheet_no_frames`;function q(e=process.platform){if(e!==`darwin`)throw new r(`UNSUPPORTED_OPERATION`,`Contact sheets can only be built on macOS hosts, which is where the frame decoder runs`,{reason:`contact_sheet_unsupported_host`,hostPlatform:e,hint:`Run this command on the macOS host that recorded the clip, or read the video artifact itself.`})}async function pt(e){if(q(e.hostPlatform??process.platform),e.timesMs.length===0)throw new r(`COMMAND_FAILED`,`Contact sheet sampling requested no frames`,{reason:K,videoPath:e.videoPath});vt(e.signal);let t=await _t(e);vt(e.signal);let n;try{n=await oe(t,[`--input`,e.videoPath,`--output-dir`,e.scratchDir,`--times`,e.timesMs.join(`,`),`--max-width`,String(e.maxWidth)],{timeoutMs:9e4,env:ge(),allowFailure:!0,...e.signal===void 0?{}:{signal:e.signal}})}catch(t){X(t,e.videoPath,`Failed to run the frame decoder`)}if(n.exitCode!==0)throw new r(`COMMAND_FAILED`,`Failed to extract frames from the recording: ${gt(n.stderr)||`exit ${n.exitCode}`}`,{reason:G,videoPath:e.videoPath,exitCode:n.exitCode});let i=mt(n.stdout,e.videoPath,e.scratchDir,e.timesMs.length);if(i.frames.length===0)throw new r(`COMMAND_FAILED`,`The recording returned no decodable frames for a contact sheet`,{reason:K,videoPath:e.videoPath,skippedSampleCount:i.skippedSampleCount});return i}function mt(e,t,n,r){let i;try{i=JSON.parse(e)}catch(e){throw Y(t,`invalid manifest: ${String(e)}`)}let a=Z(i).frames;if(!Array.isArray(a))throw Y(t,`manifest has no frames array`);let o=Z(i).skipped;if(a.length>r)throw Y(t,`returned ${a.length} frames for ${r} requested samples`);let s=a.flatMap(e=>{let r=Z(e),i=ht(r.path),a=Q(r.actualTimeMs);if(i===void 0||a===void 0||a<0)throw Y(t,`frame entry is missing a path or presentation time`);let o=x.resolve(n,x.basename(i));return S.existsSync(o)?[{requestedTimeMs:Q(r.requestedTimeMs)??a,actualTimeMs:a,path:o}]:[]});return{frames:s.sort((e,t)=>e.actualTimeMs-t.actualTimeMs),skippedSampleCount:Math.max(Array.isArray(o)?o.length:0,r-s.length)}}function J(e,t,n){return new r(`COMMAND_FAILED`,e,{reason:G,videoPath:t},n)}function Y(e,t){return J(`Frame extraction returned an unreadable manifest: ${t}`,e)}function X(e,i,a){throw t(e)||e instanceof r&&e.code===`COMMAND_FAILED`&&e.details?.reason?e:J(`${a} for ${i}: ${n(e)}`,i,e)}function Z(e){return typeof e==`object`&&e?e:{}}function ht(e){return typeof e==`string`&&e!==``?e:void 0}function Q(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function gt(e){return(e.trim().split(`
2
+ `).pop()??``).trim()}async function _t(e){try{return await ve({sourcePath:b(`recording-frames.swift`,g()),extraSourcePaths:[b(`RecordingExportSupport.swift`,g())],cacheName:`recording-frames`,timeoutMs:12e4})}catch(t){X(t,e.videoPath,`Could not build the frame decoder`)}}function vt(t){if(t?.aborted)throw e()}function yt(e,t){if(e===void 0||!Number.isFinite(e)||e<0)throw new r(`COMMAND_FAILED`,`Cannot plan a contact sheet: the video timeline of ${t} could not be read`,{reason:`contact_sheet_duration_unknown`,videoPath:t,hint:`Retry once the recording finished finalizing; a clip whose container is still being written has no readable duration.`});if(e<=250)return{durationMs:e,timesMs:e>0?[0,Math.round(e)]:[0]};let n=Math.min(48,Math.floor(e/250)+1),i=e/(n-1);return{durationMs:e,timesMs:Array.from({length:n},(e,t)=>Math.round(t*i))}}const bt=[360,320,280,240,200,160],xt=[255,255,255,255],St=[17,24,39,255],$=pe(2)+8;function Ct(e){let{cells:t}=e;if(t.length===0)throw new r(`COMMAND_FAILED`,`Contact sheet has no cells to render`);let n=Tt(t[0].image.height/Math.max(1,t[0].image.width),t.length,e),i=Ot(n.width,n.height,St);return t.forEach((e,t)=>{let r=t%n.columns,a=Math.floor(t/n.columns);wt(i,8+r*(n.cellWidth+8),8+a*($+n.cellHeight+8),e,n.cellWidth,n.cellHeight)}),{bytes:me(i.data,n.width,n.height,4),width:n.width,height:n.height,cellWidth:n.cellWidth}}function wt(e,t,n,r,i,a){fe(e,{x:t+4,y:n+4,text:jt(r.timeMs),color:xt,scale:2}),kt(e,le(At(r.image),i,a),t,n+$)}function Tt(e,t,n){let i=Et(e,t,n.maxPixels);if(i)return i;let a=Dt(e,t,160);throw new r(`COMMAND_FAILED`,`Contact sheet would be ${a.width*a.height} pixels, above the configured maxImagePixels limit of ${n.maxPixels}`,{reason:`contact_sheet_pixel_budget_exceeded`,cellCount:n.cells.length,maxPixels:n.maxPixels,hint:`Shorten the recording or raise the command policy maxImagePixels limit.`})}function Et(e,t,n){for(let r of bt){let i=Dt(e,t,r);if(i.width*i.height<=n)return i}}function Dt(e,t,n){let r=Math.min(4,t),i=Math.ceil(t/r),a=Math.max(1,Math.round(n*e));return{columns:r,cellWidth:n,cellHeight:a,width:16+r*n+(r-1)*8,height:16+i*($+a)+(i-1)*8}}function Ot(e,t,n){let r=new _.PNG({width:e,height:t});for(let i=0;i<t;i+=1)for(let t=0;t<e;t+=1)v(r,t,i,n);return r}function kt(e,t,n,r){for(let i=0;i<t.height;i+=1)for(let a=0;a<t.width;a+=1){let o=(i*t.width+a)*4;v(e,n+a,r+i,[t.data[o],t.data[o+1],t.data[o+2],t.data[o+3]])}}function At(e){let t=new _.PNG({width:e.width,height:e.height});return Buffer.from(e.data.buffer,e.data.byteOffset,e.data.byteLength).copy(t.data),t}function jt(e){let t=Math.floor(e/1e3),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=Math.floor(e%1e3);return`${[n,r,i].map(e=>String(e).padStart(2,`0`)).join(`:`)}.${String(a).padStart(3,`0`)}`}function Mt(e,t){if(e.width!==t.width||e.height!==t.height)return{status:`dimension_mismatch`};let n=e.width*e.height;if(n===0)return{status:`compared`,changedPixelRatio:0};if(e.data.length!==t.data.length)return{status:`dimension_mismatch`};let r=0;for(let n=0;n+3<e.data.length;n+=4)(e.data[n]!==t.data[n]||e.data[n+1]!==t.data[n+1]||e.data[n+2]!==t.data[n+2])&&(r+=1);return{status:`compared`,changedPixelRatio:r/n}}function Nt(e,t=.02,n=24){let r=[],i;for(let n of e){let e=i?Ft(i,n.image):1;e<t||(r.push({timeMs:n.timeMs,changedPixelRatio:e,image:n.image}),i=n.image)}Pt(r,e);let a=r.length>n?It(r,n):r;return{cells:a,keptCellCount:r.length,thinned:a.length<r.length}}function Pt(e,t){let n=t.at(-1);if(!n)return;let r=e.at(-1);!r||r.timeMs===n.timeMs||e.push({timeMs:n.timeMs,changedPixelRatio:Ft(r.image,n.image),image:n.image})}function Ft(e,t){let n=Mt(e,t);return n.status===`compared`?n.changedPixelRatio:1}function It(e,t){if(t<=1)return[e.at(-1)];let n=(e.length-1)/(t-1);return Array.from({length:t},(t,r)=>e[Math.round(r*n)])}async function Lt(e){q(e.hostPlatform??process.platform);let t=x.resolve(e.videoPath),n=x.resolve(e.outputPath??y(t));Bt(t,n);let i=await _e(t);if(i!==`mp4`)throw new r(`INVALID_ARGS`,i===`webm`?`Contact sheets need an MP4 recording; ${t} is WebM, whose frames this decoder does not read`:`Contact sheets need an MP4 recording; ${t} is not a readable MP4`,{reason:`contact_sheet_container_unsupported`,videoPath:t,container:i??`unknown`,hint:`Re-record on a backend that exports MP4, or pass the MP4 artifact the recording produced.`});let a=yt(he(t),t),o=S.mkdtempSync(x.join(ye.tmpdir(),`agent-device-contact-sheet-`));try{let r=await pt({videoPath:t,scratchDir:o,timesMs:a.timesMs,maxWidth:360,hostPlatform:e.hostPlatform??process.platform,...e.signal===void 0?{}:{signal:e.signal}}),i=await Rt(r.frames,e.maxPixels);zt(e.signal);let s=Nt(i,e.changedPixelThreshold??.02),c=Ct({cells:s.cells,maxPixels:e.maxPixels});return Gt(n,c.bytes),{path:n,videoPath:t,durationMs:a.durationMs,width:c.width,height:c.height,sampledFrameCount:a.timesMs.length,decodedFrameCount:r.frames.length,skippedSampleCount:r.skippedSampleCount,changedPixelThreshold:e.changedPixelThreshold??.02,cells:s.cells.map(Ut),...Wt(s,r)}}finally{S.rmSync(o,{recursive:!0,force:!0})}}async function Rt(e,t){let n=[];for(let i of e){let e=await de(i.path);if(e.width>360)throw new r(`COMMAND_FAILED`,`Frame extraction returned a ${e.width}px-wide frame when the sheet asked for 360px cells`,{reason:G,framePath:i.path,frameWidth:e.width,frameWidthLimit:360});if(e.width*e.height>t)throw new r(`COMMAND_FAILED`,`Frame extraction returned a ${e.width}x${e.height} frame, above the ${t}-pixel budget for the whole sheet`,{reason:G,framePath:i.path,framePixels:e.width*e.height,maxPixels:t});let a=await ue(S.readFileSync(i.path),`recording frame`);n.push({timeMs:i.actualTimeMs,image:a})}return n}function zt(t){if(t?.aborted)throw e()}function Bt(e,t){if(Vt(e,t)??t===e)throw new r(`INVALID_ARGS`,`A contact sheet cannot be written over the recording it describes: ${t}`,{reason:`contact_sheet_output_collides_with_input`,videoPath:e,outputPath:t,hint:`Choose a different --out path, or omit it to write beside the recording.`})}function Vt(e,t){let n=Ht(e),r=Ht(t);if(n!==void 0&&r!==void 0)return n.dev===r.dev&&n.ino===r.ino}function Ht(e){try{return S.statSync(e)}catch{return}}function Ut(e){return{timeMs:e.timeMs,changedPixelRatio:e.changedPixelRatio}}function Wt(e,t){let n=[];return t.skippedSampleCount>0&&n.push(`${t.skippedSampleCount} sample times returned no frame, so the sheet covers less of the recording than it asked for`),e.thinned&&n.push(`${e.keptCellCount} changes were found and 24 cells are printed, so the sheet thins evenly across the recording instead of showing every change`),n.length===0?{}:{warning:n.join(`; `)}}function Gt(e,t){try{S.mkdirSync(x.dirname(e),{recursive:!0}),ae({destination:e,contents:t})}catch(t){throw new r(`COMMAND_FAILED`,`Failed to write the contact sheet to ${e}: ${t instanceof Error?t.message:String(t)}`,{reason:`contact_sheet_output_write_failed`,outputPath:e})}}const Kt=async(e,t)=>{if(!t.video)throw new r(`INVALID_ARGS`,`record contact-sheet requires a recording to read`);Jt(t.changedPixelThreshold);let n=await u(e,t.video,{usage:`record contact-sheet`,field:`video`}),i;try{let r=qt(t,t.video,n.path);i=await p(e,r,{field:`path`,ext:`.png`,artifactType:`screen-recording-contact-sheet`});let a=await Lt({videoPath:n.path,outputPath:i.path,maxPixels:e.policy.maxImagePixels,...t.changedPixelThreshold===void 0?{}:{changedPixelThreshold:t.changedPixelThreshold},signal:t.signal??e.signal}),o=await i.publish();return{...a,path:Yt(a.path,o),...o?{artifact:o}:{}}}catch(e){throw await i?.cleanup?.(),e}finally{await n.cleanup?.()}};function qt(e,t,n){if(e.out)return e.out;if(t.kind===`path`)return{kind:`path`,path:x.resolve(y(t.path||n))};throw new r(`INVALID_ARGS`,`record contact-sheet needs an output path when the recording is an uploaded artifact`,{hint:"Pass --out <sheet.png> (CLI) or `out` (Node) to name where the sheet is written."})}function Jt(e){if(e!==void 0&&(!Number.isFinite(e)||e<0||e>1))throw new r(`INVALID_ARGS`,`record contact-sheet needs a changedPixelThreshold between 0 and 1, got ${e}`,{reason:`contact_sheet_threshold_invalid`,changedPixelThreshold:e,hint:`Omit it to use the calibrated default, or pass a share of the frame between 0 and 1.`})}function Yt(e,t){return t?t.kind===`localPath`?t.path:t.clientPath??e:e}const Xt=async(e,t)=>{let n=tn(t.action,`record`),i=n===`start`?e.backend.startRecording:e.backend.stopRecording;if(!i)throw new r(`UNSUPPORTED_OPERATION`,`record ${n} is not supported by this backend`);let a=t.out?await p(e,t.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let r=Qt(t,a?.path);return nn(n,await i.call(e.backend,f(e,t),r),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}},Zt=async(e,t)=>{let n=tn(t.action,`trace`),i=n===`start`?e.backend.startTrace:e.backend.stopTrace;if(!i)throw new r(`UNSUPPORTED_OPERATION`,`trace ${n} is not supported by this backend`);let a=t.out?await p(e,t.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let r=a?.path?{outPath:a.path}:{};return rn(n,await i.call(e.backend,f(e,t),r),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}};function Qt(e,t){let n={};t&&(n.outPath=t);let r=$t(e.fps);r!==void 0&&(n.fps=r);let i=en(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function $t(e){return e===void 0?void 0:m(e,`fps`,1,60)}function en(e){if(e===void 0)return;let t=i(e);if(t===void 0)throw new r(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return t}function tn(e,t){if(e===`start`||e===`stop`)return e;throw new r(`INVALID_ARGS`,`${t} action must be start or stop`)}function nn(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...an(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function rn(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...an(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function an(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...h(e===`start`?r.startMessage:r.stopMessage)}}const on={record:Xt,trace:Zt,contactSheet:Kt},sn=async(e,t={})=>{if(!e.backend.pressBack)throw new r(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let n=t.mode??`in-app`;if(n!==`in-app`&&n!==`system`)throw new r(`INVALID_ARGS`,`system.back mode must be in-app or system`);let i=await e.backend.pressBack(f(e,t),{mode:n}),a=c(i);return{kind:`systemBack`,mode:n,...a?{backendResult:a}:{},...h(`Back`)}},cn=async(e,t={})=>{if(!e.backend.pressHome)throw new r(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let n=await e.backend.pressHome(f(e,t)),i=c(n);return{kind:`systemHome`,...i?{backendResult:i}:{},...h(`Home`)}},ln=async(e,t)=>{if(!e.backend.pressTvRemote)throw new r(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let n=se(t.button),i=t.durationMs===void 0?void 0:m(t.durationMs,`durationMs`,0,1e4),a=await e.backend.pressTvRemote(f(e,t),{button:n,...i===void 0?{}:{durationMs:i}}),o=c(a);return{kind:`tvRemotePressed`,button:n,...i===void 0?{}:{durationMs:i},...o?{backendResult:o}:{},...h(`Pressed TV remote ${n}`)}},un=async(e,t)=>{if(!e.backend.setOrientation)throw new r(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let n=gn(t.orientation),i=await e.backend.setOrientation(f(e,t),n),a=c(i);return{kind:`systemOrientationSet`,orientation:n,...a?{backendResult:a}:{},...h(`Rotated to ${n}`)}},dn=async(e,t={})=>{if(!e.backend.setKeyboard)throw new r(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let n=t.action??`status`;if(!ce(n))throw new r(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let i=await e.backend.setKeyboard(f(e,t),{action:n}),a=c(i),o=Tn(i)?i:{};return n===`enter`||n===`return`?vn(o,a):n===`dismiss`?yn(n,o,a):xn(n,o,a)},fn=async(e,t)=>{if(t.action===`read`){if(!e.backend.getClipboard)throw new r(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let n=await e.backend.getClipboard(f(e,t));return{kind:`clipboardText`,action:`read`,text:typeof n==`string`?n:n.text}}if(t.action!==`write`)throw new r(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new r(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof t.text!=`string`)throw new r(`INVALID_ARGS`,`system.clipboard write requires text`);let n=await e.backend.setClipboard(f(e,t),t.text),i=c(n);return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(t.text).length,...i?{backendResult:i}:{},...h(`Clipboard updated`)}},pn=async(e,t={})=>{if(!e.backend.openSettings)throw new r(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let n=C(t.target,`target`),i=await e.backend.openSettings(f(e,t),n),a=c(i);return{kind:`settingsOpened`,...n?{target:n}:{},...a?{backendResult:a}:{},...h(n?`Opened settings: ${n}`:`Opened settings`)}},mn=async(e,t={})=>{if(!e.backend.handleAlert)throw new r(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let n=t.action??`get`;if(n!==`get`&&n!==`accept`&&n!==`dismiss`&&n!==`wait`)throw new r(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let i=t.timeoutMs===void 0?void 0:m(t.timeoutMs,`timeoutMs`,0,12e4);return _n(n,await e.backend.handleAlert(f(e,t),n,{timeoutMs:i}))},hn=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new r(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let n=await e.backend.openAppSwitcher(f(e,t)),i=c(n);return{kind:`appSwitcherOpened`,...i?{backendResult:i}:{},...h(`Opened app switcher`)}};function gn(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new r(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function _n(e,t){return e===`get`?Sn(t):e===`wait`?Cn(t):wn(e,t)}function vn(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...h(`Keyboard enter pressed`)}}function yn(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...h(bn(t))}}function bn(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function xn(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function Sn(e){if(e.kind!==`alertStatus`)throw new r(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function Cn(e){if(e.kind!==`alertWait`)throw new r(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:e.alert,...e.waitedMs===void 0?{}:{waitedMs:e.waitedMs},...e.timedOut===void 0?{}:{timedOut:e.timedOut},...h(e.alert?`Alert visible`:`Alert wait timed out`)}}function wn(e,t){if(t.kind!==`alertHandled`)throw new r(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...h(t.handled?`Alert ${e}ed`:`No alert handled`)}}function Tn(e){return!!(e&&typeof e==`object`)}const En={back:sn,home:cn,orientation:un,keyboard:dn,clipboard:fn,settings:pn,alert:mn,appSwitcher:hn,tvRemote:ln};function Dn(e){return{capture:ee(e),selectors:d(e),interactions:o(e),system:s(En,e),apps:qe(e),admin:s(Ke,e),recording:s(on,e),observability:s(ft,e)}}function On(e){let t=l(e);return{...t,...Dn(t)}}export{On as createAgentDevice,a as createMemorySessionStore,te as localCommandPolicy,ne as restrictedCommandPolicy};
@@ -1,4 +1,4 @@
1
- import{D as e}from"./sdk-contracts.js";import{D as t}from"./sdk-device.js";import{Yt as n,tn as r}from"./sdk-batch.js";import{n as i}from"./device-shell.js";import{i as a,n as o}from"./recording-stop-observation.js";import{n as s,r as c,t as l}from"./application-lifecycle-runtime.js";import{A as u,B as d,C as f,D as p,G as m,H as h,I as g,J as ee,N as _,V as te,d as ne,h as re,n as ie,o as ae,s as oe,v as se,w as ce,x as le,z as ue}from"./alert-runtime.js";import{n as de}from"./audio-probe-runtime.js";import{n as fe}from"./perf-runtime.js";import{i as pe}from"./touch-runtime.js";import{a as me,n as he}from"./durable-resource.js";import{n as ge}from"./async-lifecycle.js";import{i as _e,l as ve,n as ye,r as be,t as xe}from"./src7.js";import{n as Se}from"./screen-recording-completion.js";import{a as Ce,i as v,o as we,s as Te,t as Ee}from"./stop-sequence.js";import{n as De}from"./screen-recording-runtime.js";import{readAndroidAppStateWithExecutor as Oe}from"./app-state.js";import{ANDROID_CLIPBOARD_SHELL_COMMAND_UNAVAILABLE_HINT as ke}from"./clipboard-shell-response.js";import{i as Ae,t as je}from"./gesture-admission.js";import{t as Me}from"./local-interactor-operation-set.js";import{a as Ne,i as Pe,n as Fe,r as Ie,t as Le}from"./perf-runtime-operation-builder.js";import{t as Re}from"./app-log-runtime.js";import{t as ze}from"./mp4-duration.js";import{n as y,r as Be}from"./managed-device-scope.js";import{a as Ve,i as He,n as Ue,o as We}from"./application-lifecycle-interaction.js";import b from"node:path";function Ge(e){return Ce(e)?Object.freeze({available:!0}):e.kind===`emulator`?Object.freeze({available:!1,reason:`unsupported-device-backend`,hint:`audio probe capture requires a macOS host.`}):Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`audio probe capture is supported for Android emulators on macOS hosts.`})}function Ke(e){let{resolveHost:t,device:n,owner:r}=e;return Object.freeze({...Le({platform:`Android`,expectedProfileKind:`simpleperf`,start:async e=>await t().start(n,r,e),reattach:async e=>await t().reattach(n,e),cleanup:async e=>await t().cleanup(n,e),writeProfileReport:async e=>await t().writeProfileReport(n,e)}),perfFrames:async({appId:e})=>({metric:e?await Pe(t().sampleFrames(n,e)):Fe(`Android`,`package`),sampling:{method:`adb-shell-dumpsys-gfxinfo-framestats`,description:`Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.`,unit:`percent`,primaryField:`droppedFramePercent`,window:`since previous Android gfxinfo reset or app process start`,resetsAfterRead:!0,relatedActionsLimit:12}}),perfMemorySample:async({appId:e})=>({metric:e?await Pe(t().sampleMemory(n,e)):Fe(`Android`,`package`),sampling:{method:`adb-shell-dumpsys-meminfo`,description:`Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.`,unit:`kB`,topConsumerLimit:5}}),perfMemorySnapshot:async({appId:e,kind:r,outPath:i,artifactsDir:a})=>{let o=r??`android-hprof`,s=qe();if(o!==`android-hprof`)return Ne(`Android`,o,s,`Use perf memory snapshot --kind android-hprof for Android Java heap artifacts.`);if(!e)throw Ie();let c=i??b.join(a,`memory-android-hprof-${Je()}.hprof`);return{artifact:await t().captureMemorySnapshot(n,e,c),support:s,sampling:{method:`adb-shell-am-dumpheap`,description:`Java heap dump captured with adb shell am dumpheap, pulled to a local artifact path.`,defaultKind:`android-hprof`,artifactOnly:!0}}}})}function qe(){return{platform:`android`,defaultKind:`android-hprof`,androidHprof:!0,memgraph:!1,heapprofd:!1,heapprofdDecision:`Deferred until Android Perfetto/heapprofd plumbing is available in the perf trace slice.`}}function Je(){return new Date().toISOString().replaceAll(/[:.]/g,`-`)}function Ye(t){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new e(`INVALID_ARGS`,`Invalid Android package name for logs: ${t}`)}const x=Object.freeze({resourceKind:Re,version:1,encode:e=>({...e}),decode:e=>e.transport!==`android-logcat-local`&&e.transport!==`android-logcat-transport-composed`||!Ze(e.outputPath)||!Ze(e.pidPath)?{status:`invalid`,message:`Invalid Android app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:e.transport,outputPath:e.outputPath,pidPath:e.pidPath})}});function Xe(e){let t=x.decode(e.descriptor);if(t.status!==`decoded`)throw TypeError(t.message);return he({resourceKind:Re,sessionId:e.sessionId,device:{id:e.device.id,family:`android`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:me(x,t.descriptor)})}function Ze(e){return typeof e==`string`&&e.trim().length>0}function Qe(e){return be(e,{family:`android`,backend:`android`,label:`Android`,codec:x,startUnavailableHint:`The selected Android transport cannot start a background adb logcat stream.`,cleanupFailureMessage:`Android app-log cleanup did not settle every owned resource`,doctor:async({host:e,device:t,signal:n},r)=>await $e(e,t.id,r,n),validateStart:({input:e})=>Ye(e.appBundleId),process:async({host:e,device:t,input:n})=>({resolvePid:async r=>await _e(e,et(t.id,n.appBundleId),r),command:e=>({kind:`android-adb`,serial:t.id,args:[`logcat`,`-v`,`time`,`--pid`,e],options:{allowFailure:!0}})}),descriptor:({artifacts:e,transport:t})=>({transport:t.mode===`transport-composed`?`android-logcat-transport-composed`:`android-logcat-local`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>Xe({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function $e(e,t,n,r){let a={};return a.adbAvailable=await Te(async()=>we(await e.commands.run({executable:`adb`,args:i(`adb`,`shell`,[`echo`,`ok`],[`-s`,t]),allowFailure:!0,timeoutMs:1e3},r)),r),n&&(a.androidPidVisible=await Te(async()=>!!await _e(e,et(t,n),r),r)),{backend:`android`,checks:a,notes:n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}}function et(e,t){return{executable:`adb`,args:i(`adb`,`shell`,[`pidof`,t],[`-s`,e]),allowFailure:!0,timeoutMs:5e3}}async function tt(e,t,n,r){let i=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),a=ye(i.text,{...n,path:i.path,exists:i.exists,lineNumberOffset:i.skippedLines,backend:`android`}),o=[],s=await rt(e,t,n,r);if(s&&n.appBundleId){Ye(n.appBundleId);let c=await at(e,t,n.appBundleId,r);if(c){let e=ye(c.text,{...n,path:`${i.path} (adb logcat recovery)`,exists:!0,backend:`android`});e.dump.entries.length>0&&(a=xe(e,a,n.maxEntries),o.push(s.reason===`stale-active`?`Session app log stream was still bound to prior Android PID ${s.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`))}}return n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&o.length===0&&o.push(`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):o.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`),a.dump.entries.length===0&&o.push(`No HTTP(s) entries were found in recent session app logs.`),Object.freeze({source:`app-log`,backend:`android`,dump:a.dump,notes:Object.freeze(o)})}async function nt(e,t,n){n.throwIfAborted();try{let r=await e.commands.run(t,n);return n.throwIfAborted(),r}catch{n.throwIfAborted();return}}async function rt(e,t,n,r){if(!n.appBundleId||n.appLogSnapshot?.state===void 0)return;if(n.appLogSnapshot.state!==`active`)return{reason:`inactive`};let i=it(await e.appLogs.readProcessMarker(n.sessionId));if(!i)return;let a=await ot(e,t.id,n.appBundleId,r);if(!(!a||a===i))return{reason:`stale-active`,trackedPid:i}}function it(e){if(e.status===`decoded`)return/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(e.marker.command)?.[1]}async function at(e,t,n,r){let i=await ot(e,t.id,n,r),a=await nt(e,{executable:`adb`,args:[`-s`,t.id,`logcat`,`-d`,`-v`,`time`,`-t`,`4000`],allowFailure:!0,timeoutMs:3e3},r);if(!a||a.exitCode!==0||!a.stdout.trim())return;let o=st(a.stdout,n,i);if(o.length===0)return;let s=new Set(o),c=a.stdout.split(`
1
+ import{O as e}from"./sdk-contracts.js";import{D as t}from"./sdk-device.js";import{Yt as n,tn as r}from"./sdk-batch.js";import{n as i}from"./device-shell.js";import{i as a,n as o}from"./recording-stop-observation.js";import{n as s,r as c,t as l}from"./application-lifecycle-runtime.js";import{A as u,B as d,C as f,D as p,G as m,H as h,I as g,J as ee,N as _,V as te,d as ne,h as re,n as ie,o as ae,s as oe,v as se,w as ce,x as le,z as ue}from"./alert-runtime.js";import{n as de}from"./audio-probe-runtime.js";import{n as fe}from"./perf-runtime.js";import{i as pe}from"./touch-runtime.js";import{a as me,n as he}from"./durable-resource.js";import{n as ge}from"./async-lifecycle.js";import{i as _e,l as ve,n as ye,r as be,t as xe}from"./src7.js";import{n as Se}from"./screen-recording-completion.js";import{a as Ce,i as v,o as we,s as Te,t as Ee}from"./stop-sequence.js";import{n as De}from"./screen-recording-runtime.js";import{readAndroidAppStateWithExecutor as Oe}from"./app-state.js";import{ANDROID_CLIPBOARD_SHELL_COMMAND_UNAVAILABLE_HINT as ke}from"./clipboard-shell-response.js";import{i as Ae,t as je}from"./gesture-admission.js";import{t as Me}from"./local-interactor-operation-set.js";import{a as Ne,i as Pe,n as Fe,r as Ie,t as Le}from"./perf-runtime-operation-builder.js";import{t as Re}from"./app-log-runtime.js";import{t as ze}from"./mp4-duration.js";import{n as y,r as Be}from"./managed-device-scope.js";import{a as Ve,i as He,n as Ue,o as We}from"./application-lifecycle-interaction.js";import b from"node:path";function Ge(e){return Ce(e)?Object.freeze({available:!0}):e.kind===`emulator`?Object.freeze({available:!1,reason:`unsupported-device-backend`,hint:`audio probe capture requires a macOS host.`}):Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`audio probe capture is supported for Android emulators on macOS hosts.`})}function Ke(e){let{resolveHost:t,device:n,owner:r}=e;return Object.freeze({...Le({platform:`Android`,expectedProfileKind:`simpleperf`,start:async e=>await t().start(n,r,e),reattach:async e=>await t().reattach(n,e),cleanup:async e=>await t().cleanup(n,e),writeProfileReport:async e=>await t().writeProfileReport(n,e)}),perfFrames:async({appId:e})=>({metric:e?await Pe(t().sampleFrames(n,e)):Fe(`Android`,`package`),sampling:{method:`adb-shell-dumpsys-gfxinfo-framestats`,description:`Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.`,unit:`percent`,primaryField:`droppedFramePercent`,window:`since previous Android gfxinfo reset or app process start`,resetsAfterRead:!0,relatedActionsLimit:12}}),perfMemorySample:async({appId:e})=>({metric:e?await Pe(t().sampleMemory(n,e)):Fe(`Android`,`package`),sampling:{method:`adb-shell-dumpsys-meminfo`,description:`Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.`,unit:`kB`,topConsumerLimit:5}}),perfMemorySnapshot:async({appId:e,kind:r,outPath:i,artifactsDir:a})=>{let o=r??`android-hprof`,s=qe();if(o!==`android-hprof`)return Ne(`Android`,o,s,`Use perf memory snapshot --kind android-hprof for Android Java heap artifacts.`);if(!e)throw Ie();let c=i??b.join(a,`memory-android-hprof-${Je()}.hprof`);return{artifact:await t().captureMemorySnapshot(n,e,c),support:s,sampling:{method:`adb-shell-am-dumpheap`,description:`Java heap dump captured with adb shell am dumpheap, pulled to a local artifact path.`,defaultKind:`android-hprof`,artifactOnly:!0}}}})}function qe(){return{platform:`android`,defaultKind:`android-hprof`,androidHprof:!0,memgraph:!1,heapprofd:!1,heapprofdDecision:`Deferred until Android Perfetto/heapprofd plumbing is available in the perf trace slice.`}}function Je(){return new Date().toISOString().replaceAll(/[:.]/g,`-`)}function Ye(t){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new e(`INVALID_ARGS`,`Invalid Android package name for logs: ${t}`)}const x=Object.freeze({resourceKind:Re,version:1,encode:e=>({...e}),decode:e=>e.transport!==`android-logcat-local`&&e.transport!==`android-logcat-transport-composed`||!Ze(e.outputPath)||!Ze(e.pidPath)?{status:`invalid`,message:`Invalid Android app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:e.transport,outputPath:e.outputPath,pidPath:e.pidPath})}});function Xe(e){let t=x.decode(e.descriptor);if(t.status!==`decoded`)throw TypeError(t.message);return he({resourceKind:Re,sessionId:e.sessionId,device:{id:e.device.id,family:`android`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:me(x,t.descriptor)})}function Ze(e){return typeof e==`string`&&e.trim().length>0}function Qe(e){return be(e,{family:`android`,backend:`android`,label:`Android`,codec:x,startUnavailableHint:`The selected Android transport cannot start a background adb logcat stream.`,cleanupFailureMessage:`Android app-log cleanup did not settle every owned resource`,doctor:async({host:e,device:t,signal:n},r)=>await $e(e,t.id,r,n),validateStart:({input:e})=>Ye(e.appBundleId),process:async({host:e,device:t,input:n})=>({resolvePid:async r=>await _e(e,et(t.id,n.appBundleId),r),command:e=>({kind:`android-adb`,serial:t.id,args:[`logcat`,`-v`,`time`,`--pid`,e],options:{allowFailure:!0}})}),descriptor:({artifacts:e,transport:t})=>({transport:t.mode===`transport-composed`?`android-logcat-transport-composed`:`android-logcat-local`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>Xe({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function $e(e,t,n,r){let a={};return a.adbAvailable=await Te(async()=>we(await e.commands.run({executable:`adb`,args:i(`adb`,`shell`,[`echo`,`ok`],[`-s`,t]),allowFailure:!0,timeoutMs:1e3},r)),r),n&&(a.androidPidVisible=await Te(async()=>!!await _e(e,et(t,n),r),r)),{backend:`android`,checks:a,notes:n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}}function et(e,t){return{executable:`adb`,args:i(`adb`,`shell`,[`pidof`,t],[`-s`,e]),allowFailure:!0,timeoutMs:5e3}}async function tt(e,t,n,r){let i=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),a=ye(i.text,{...n,path:i.path,exists:i.exists,lineNumberOffset:i.skippedLines,backend:`android`}),o=[],s=await rt(e,t,n,r);if(s&&n.appBundleId){Ye(n.appBundleId);let c=await at(e,t,n.appBundleId,r);if(c){let e=ye(c.text,{...n,path:`${i.path} (adb logcat recovery)`,exists:!0,backend:`android`});e.dump.entries.length>0&&(a=xe(e,a,n.maxEntries),o.push(s.reason===`stale-active`?`Session app log stream was still bound to prior Android PID ${s.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`))}}return n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&o.length===0&&o.push(`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):o.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`),a.dump.entries.length===0&&o.push(`No HTTP(s) entries were found in recent session app logs.`),Object.freeze({source:`app-log`,backend:`android`,dump:a.dump,notes:Object.freeze(o)})}async function nt(e,t,n){n.throwIfAborted();try{let r=await e.commands.run(t,n);return n.throwIfAborted(),r}catch{n.throwIfAborted();return}}async function rt(e,t,n,r){if(!n.appBundleId||n.appLogSnapshot?.state===void 0)return;if(n.appLogSnapshot.state!==`active`)return{reason:`inactive`};let i=it(await e.appLogs.readProcessMarker(n.sessionId));if(!i)return;let a=await ot(e,t.id,n.appBundleId,r);if(!(!a||a===i))return{reason:`stale-active`,trackedPid:i}}function it(e){if(e.status===`decoded`)return/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(e.marker.command)?.[1]}async function at(e,t,n,r){let i=await ot(e,t.id,n,r),a=await nt(e,{executable:`adb`,args:[`-s`,t.id,`logcat`,`-d`,`-v`,`time`,`-t`,`4000`],allowFailure:!0,timeoutMs:3e3},r);if(!a||a.exitCode!==0||!a.stdout.trim())return;let o=st(a.stdout,n,i);if(o.length===0)return;let s=new Set(o),c=a.stdout.split(`
2
2
  `).filter(e=>{if(!e.trim())return!1;if(e.includes(n))return!0;let t=/\(\s*(\d+)\)\s*:/.exec(e)?.[1];return!!(t&&s.has(t))}).join(`
3
3
  `);return c.trim()?{text:c,pids:o}:void 0}async function ot(e,t,n,r){let a=await nt(e,{executable:`adb`,args:i(`adb`,`shell`,[`pidof`,n],[`-s`,t]),allowFailure:!0},r);if(!a)return;let o=a.stdout.trim().split(/\s+/)[0];return o&&/^\d+$/.test(o)?o:void 0}function st(e,t,n){let r=new Set(n?[n]:[]),i=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),a=[RegExp(`\\bStart proc\\s+(\\d+):${i}(?:\\b|/)`,`i`),RegExp(`\\b(\\d+):${i}(?:\\b|/)`,`i`),RegExp(`${i}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,`i`),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${i}`,`i`)];for(let n of e.split(`
4
4
  `))if(n.includes(t))for(let e of a){let t=e.exec(n)?.[1];t&&/^\d+$/.test(t)&&r.add(t)}return Object.freeze([...r])}function S(e,t){if(t===1)return e;let n=b.parse(e);return b.join(n.dir,`${n.name}.part-${String(t).padStart(3,`0`)}${n.ext||`.mp4`}`)}const ct=/^(?:\/sdcard|\/data\/local\/tmp)\/agent-device-recording-\d{1,20}\.mp4$/,lt=/^(?:\/sdcard|\/data\/local\/tmp)\/agent-device-recording-active\.json$/;function ut(e){return pt(e)&&mt(e)&&ht(e)}function dt(e){if(!w(e))return!1;let t=e;return gt(t)&&_t(t)&&vt(t)&&yt(t)&&(t.completion===void 0||Et(t))}function ft(e,t){return Dt(e,t)&&C(e,t.outputPath,t.clientOutputPath)}function pt(e){return e.backend===`adb-screenrecord`&&typeof e.manifestPath==`string`&&lt.test(e.manifestPath)&&typeof e.outputPath==`string`}function mt(e){return kt(e.clientOutputPath)&&v(e)}function ht(e){return Ot(e.transportMode)}function gt(e){return e.version===1&&e.resourceKind===`screen-recording`&&typeof e.fenceToken==`string`&&Number.isInteger(e.fenceGeneration)&&typeof e.sessionId==`string`&&typeof e.deviceId==`string`&&Number.isFinite(e.startedAt)}function _t(e){return typeof e.outputPath==`string`&&kt(e.clientOutputPath)&&v(e)}function vt(e){return Ot(e.transportMode)&&(e.pendingRemotePath===void 0||At(e.pendingRemotePath))}function yt(e){return Array.isArray(e.chunks)&&e.chunks.every(bt)&&(e.chunks.length>0||e.pendingRemotePath!==void 0)&&(e.completion===void 0||xt(e.completion))}function bt(e,t){if(!w(e))return!1;let n=e;return n.index===t+1&&At(n.remotePath)&&jt(n.remotePid)&&jt(n.remoteStartTime)}function xt(e){if(!w(e))return!1;let t=e;return Ct(t)&&wt(t)&&St(t)&&(t.chunks===void 0||t.chunks.every(Tt))}function St(e){return(e.stopObservation===void 0||o(e.stopObservation))&&(e.nativePathDisposition===void 0||a(e.nativePathDisposition))}function Ct(e){return typeof e.backend==`string`&&typeof e.outPath==`string`&&(e.clientOutPath===void 0||typeof e.clientOutPath==`string`)&&Number.isFinite(e.startedAt)&&Number.isFinite(e.completedAt)&&(e.capturedDurationMs===void 0||Number.isFinite(e.capturedDurationMs))}function wt(e){return v(e)}function Tt(e,t){return e.index===t+1&&typeof e.path==`string`&&(e.clientOutPath===void 0||typeof e.clientOutPath==`string`)}function Et(e){let t=e.completion;return t!==void 0&&Dt(t,e)&&t.startedAt===e.startedAt&&C(t,e.outputPath,e.clientOutputPath,e.chunks.length)}function Dt(e,t){return e.backend===`adb screenrecord`&&e.outPath===t.outputPath&&e.clientOutPath===t.clientOutputPath&&e.scope===t.scope&&e.showTouches===t.showTouches&&e.recordOnlySession===t.recordOnlySession&&Mt(e.activeSessionApp,t.activeSessionApp)}function C(e,t,n,r=e.chunks===void 0?1:e.chunks.length){return r===1?e.chunks===void 0:e.chunks?.length===r&&e.chunks.every((e,r)=>e.path===S(t,r+1)&&e.clientOutPath===(n===void 0?void 0:S(n,r+1)))}function w(e){return typeof e==`object`&&!!e}function Ot(e){return e===`local`||e===`transport-composed`}function kt(e){return e===void 0||typeof e==`string`}function At(e){return typeof e==`string`&&ct.test(e)}function jt(e){return typeof e==`string`&&/^\d+$/.test(e)}function Mt(e,t){return JSON.stringify(e)===JSON.stringify(t)}const T=Object.freeze({resourceKind:De,version:1,encode:e=>({...e}),decode:e=>ut(e)?{status:`decoded`,descriptor:Object.freeze({backend:`adb-screenrecord`,manifestPath:e.manifestPath,outputPath:e.outputPath,...e.clientOutputPath===void 0?{}:{clientOutputPath:e.clientOutputPath},scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,transportMode:e.transportMode,...e.activeSessionApp===void 0?{}:{activeSessionApp:e.activeSessionApp},...e.exportQuality===void 0?{}:{exportQuality:e.exportQuality}})}:{status:`invalid`,message:`Invalid Android screen-recording descriptor`}});function E(e,t,n,r,i,a=`local`){return Object.freeze({version:1,resourceKind:`screen-recording`,fenceToken:t.fence.token,fenceGeneration:t.fence.generation,sessionId:t.sessionId,deviceId:e.id,startedAt:n,outputPath:t.outputPath,...t.clientOutputPath===void 0?{}:{clientOutputPath:t.clientOutputPath},scope:t.scope,showTouches:t.showTouches,recordOnlySession:t.recordOnlySession,...t.activeSessionApp===void 0?{}:{activeSessionApp:t.activeSessionApp},...t.exportQuality===void 0?{}:{exportQuality:t.exportQuality},chunks:r,...i===void 0?{}:{pendingRemotePath:i},transportMode:a})}function Nt(e,t){return Object.freeze({...e,completion:t})}function D(e){try{let t=e&&JSON.parse(e);return dt(t)?t:void 0}catch{return}}function Pt(e,t,n){return e.deviceId===t.id&&e.deviceId===n.device.id&&e.fenceToken===n.fence.token&&e.fenceGeneration===n.fence.generation&&e.sessionId===n.sessionId}function Ft(e,t){return e.outputPath===t.outputPath&&e.clientOutputPath===t.clientOutputPath&&e.scope===t.scope&&e.showTouches===t.showTouches&&e.recordOnlySession===t.recordOnlySession&&JSON.stringify(e.activeSessionApp)===JSON.stringify(t.activeSessionApp)&&e.exportQuality===t.exportQuality&&e.transportMode===t.transportMode&&(e.completion===void 0||ft(e.completion,t))}function O(e){switch(e){case`missing`:case`ownership-lost`:case`foreign-writer`:return!0;case`owned-alive`:case`uncertain`:return!1}}function It(e){switch(e){case`missing`:case`ownership-lost`:return!0;case`foreign-writer`:case`owned-alive`:case`uncertain`:return!1}}const Lt=1e4,Rt=1e3;var k=class extends Error{constructor(e){super(`Android screenrecord launch rollback could not be confirmed`,{cause:e})}};function A(e,t=Date.now()){return[...new Set(e?[e,`/sdcard`,`/data/local/tmp`]:[`/sdcard`,`/data/local/tmp`])].map(e=>`${e}/agent-device-recording-${t}.mp4`)}async function zt(e,t,n,r){let i;try{if(i=(await e.start({remotePath:t,quality:n.exportQuality??`medium`},r)).process,!/^\d+$/.test(i.pid)||!/^\d+$/.test(i.startTime)||i.remotePath!==t)throw Error(`Android screenrecord returned an invalid process identity`);if(!await Gt(e,t,i,r))throw Error(`Android screenrecord did not begin producing frames`);return{index:1,remotePath:t,remotePid:i.pid,remoteStartTime:i.startTime}}catch(t){throw i&&Bt(i)&&!await Kt(e,i)?new k(t):r?.aborted?r.reason:t}}function Bt(e){return/^\d+$/.test(e.pid)&&/^\d+$/.test(e.startTime)&&e.remotePath.length>0}async function j(e,t){let n=t.at(-1),r=!1,i;for(let a of[...t].reverse())try{let t=await N(e,a);a===n&&(r=t)}catch(e){i??=e}if(i)throw i;return r}async function Vt(e,t){for(let n of t){let t;for(let r=0;r<3;r+=1){let i=await e.size(n.remotePath);if(typeof i==`number`&&i>0&&i===t)break;if(t=typeof i==`number`&&i>0?i:void 0,r===2)throw Error(`Android recording artifact is not stable: ${n.remotePath}`);await new Promise(e=>setTimeout(e,250))}}}async function Ht(e,t,n){for(let[r,i]of t.entries())await qt(e,i.remotePath,S(n,r+1))}async function M(e,t){let n;for(let r of t)try{if(!await e.remove(r.remotePath))throw Error(`failed to remove Android recording artifact: ${r.remotePath}`)}catch(e){n??=e}if(n)throw n}async function Ut(e,t){for(let n of t)if(await e.exists(n.remotePath)!==!1)return`retirable`;return`retired`}async function Wt(e,t){try{await j(e,t)}finally{await M(e,t)}}async function Gt(e,t,n,r){for(let i=0;i<3;i+=1){if(r?.throwIfAborted(),await e.exists(t,r)===!0)return!0;if(await e.inspect(n,r)!==`owned-alive`)return!1;i<2&&await new Promise(e=>setTimeout(e,250))}return!0}async function Kt(e,t){try{let n=await e.stop(t,{force:!0});return(n===`stopped`||n===`already-missing`)&&await e.remove(t.remotePath)}catch{return!1}}async function N(e,t){if(!t)return!1;let n={pid:t.remotePid,remotePath:t.remotePath,startTime:t.remoteStartTime},r=await e.stop(n);if(r===`already-missing`)return!0;if(r===`ownership-lost`)throw Error(`Android screenrecord ownership could not be confirmed for pid ${t.remotePid}`);if(await Jt(e,n))return!1;let i=await e.stop(n,{force:!0});if(i===`stopped`||i===`already-missing`)return!1;throw Error(`failed to stop Android screenrecord pid ${t.remotePid}`)}async function qt(e,t,n){for(let r=0;r<3;r+=1){let i=await e.pullPlayable({remotePath:t,outputPath:n});if(i.exitCode===0&&i.playable)return;r+1<3&&await Yt(1e3)}throw Error(`failed to retrieve playable Android recording`)}async function Jt(e,t){for(let n=0;n<=Lt;n+=Rt){let r=await e.inspect(t);if(r===`missing`)return!0;if(O(r))throw Error(`Android screenrecord ownership could not be confirmed for pid ${t.pid}`);n<Lt&&await Yt(Rt)}return!1}function Yt(e){return new Promise(t=>setTimeout(t,e))}async function P(e,t,n,r){await e.writeManifest({manifestPath:t,contents:JSON.stringify(n)},r)}async function F(e,t){if(!await e.removeManifest(t))throw Error(`failed to remove Android recording manifest: ${t}`)}async function Xt(e,t){let n=(await Zt(e)).flatMap(n=>Qt(n,t,e.mode));for(let t of n)await en(e,t.evidence,t.manifestPath)}async function Zt(e){return await Promise.all(A(void 0).map(async t=>{let n=e.manifestPathFor(t);return{manifestPath:n,read:await e.readManifest(n)}}))}function Qt(e,t,n){if(e.read.status===`missing`)return[];if(e.read.status!==`read`)throw rn(e.manifestPath,e.read.message);let r=D(e.read.contents);if(r===void 0)throw an(e.manifestPath);if(r.transportMode!==n)throw on(e.manifestPath,r,n);if(!$t(r,t))throw sn(e.manifestPath,r,t);return[{manifestPath:e.manifestPath,evidence:r}]}function $t(e,t){return e.completion!==void 0||e.deviceId!==t.id}async function en(e,t,n){if(await tn(e,t),await M(e,t.chunks),await nn(e,t),await F(e,n),(await e.readManifest(n)).status!==`missing`)throw un(n)}async function tn(e,t){for(let n of t.chunks){let t=await e.inspect({pid:n.remotePid,remotePath:n.remotePath,startTime:n.remoteStartTime});if(!It(t))throw t===`uncertain`?dn(n.remotePath):cn(n.remotePath,t===`owned-alive`?`named-recorder`:`other-recorder`)}let n=t.pendingRemotePath;if(n===void 0)return;let r=await e.probeRunningWriters(n);if(r.writers.length>0)throw cn(n,`other-recorder`);if(!r.conclusive)throw dn(n)}async function nn(e,t){let n=t.pendingRemotePath;if(n!==void 0&&!await e.remove(n))throw ln(n)}function rn(t,n){return new e(`COMMAND_FAILED`,`Android screenrecord native recovery evidence is unavailable: ${t}`,{reason:`native_recovery_evidence_unavailable`,manifestPath:t,hint:`Confirm the device is online and its storage readable, then run record start again.`},Error(n))}function an(t){return new e(`COMMAND_FAILED`,`Android screenrecord native recovery evidence is unreadable: ${t}`,{reason:`native_recovery_evidence_unreadable`,manifestPath:t,hint:I(t)})}function on(t,n,r){return new e(`COMMAND_FAILED`,`Android screenrecord native recovery evidence was written by the ${n.transportMode} transport, not this ${r} one: ${t}`,{reason:`native_recovery_evidence_transport_mismatch`,manifestPath:t,evidenceTransportMode:n.transportMode,hint:I(t)})}function sn(t,n,r){return new e(`DEVICE_IN_USE`,`Android screenrecord native recovery evidence already exists: ${t} (open recording of session "${n.sessionId}" on ${r.id})`,{reason:`native_recovery_evidence_open`,manifestPath:t,sessionId:n.sessionId,retriable:!1,hint:`Run record stop --session ${n.sessionId} to retire it, or close that session. If it is already closed, ${I(t)}`})}function cn(t,n){let r=n===`named-recorder`;return new e(`DEVICE_IN_USE`,`Android screenrecord recovery evidence is retained: ${r?`its recorder`:`another recorder`} is writing ${t}`,{reason:`native_recording_artifact_claimed`,remotePath:t,writer:n,...r?{retriable:!1}:{},hint:r?`Run record stop for the session that owns that recording before starting another.`:`Android ends any recorder after 180 seconds. Run record start again once that recorder has stopped.`})}function ln(t){return new e(`COMMAND_FAILED`,`Android screenrecord recovery evidence could not remove ${t}`,{reason:`native_recording_artifact_removal_failed`,remotePath:t,hint:`Confirm the device is online and run record start again.`})}function un(t){return new e(`COMMAND_FAILED`,`Android screenrecord recovery evidence removal could not be confirmed: ${t}`,{reason:`native_recovery_evidence_retirement_unconfirmed`,manifestPath:t,hint:`Run record start again; the marker is retired from the beginning.`})}function dn(t){return new e(`COMMAND_FAILED`,`Android screenrecord recovery evidence cannot be safely retired: ${t}`,{reason:`native_recording_recorder_unproven`,remotePath:t,hint:`Confirm the device is online and run record start again.`})}function I(e){return`no recording session can retire this marker; remove it on the device with \`adb shell rm -f ${e}\`.`}async function fn(e){let{transport:t,device:n,input:r,startedAt:i,signal:a,prepareOutput:o}=e;await Xt(t,n),await o();let s;for(let e of A(void 0)){let o=t.manifestPathFor(e);await P(t,o,E(n,r,i,[],e,t.mode),a);let c,l;try{l=Date.now(),c=await zt(t,e,r,a)}catch(e){if(a.aborted)throw await pn(t,o,e),a.reason;await gn(t,o,e),s=e;continue}try{await P(t,o,E(n,r,i,[c],void 0,t.mode),a)}catch(e){throw await mn(t,o,c),e}return{chunk:c,manifestPath:o,startedAtMs:l}}throw s??Error(`Android screenrecord did not begin producing frames`)}async function pn(e,t,n){n instanceof k||await F(e,t).catch(()=>{})}async function mn(e,t,n){try{await Wt(e,[n])}catch{return}await F(e,t).catch(()=>{})}async function hn(e){let{transport:t,device:n,input:r,startedAt:i,chunks:a,manifestPath:o,preferredDir:s}=e,c;for(let e of A(s)){await P(t,o,E(n,r,i,a,e,t.mode));try{return await zt(t,e,r)}catch(e){if(e instanceof k)throw e;try{await P(t,o,E(n,r,i,a,void 0,t.mode))}catch{throw new k(e)}c=e}}throw c??Error(`failed to start next Android recording chunk`)}async function gn(e,t,n){if(n instanceof k)throw n;try{await F(e,t)}catch{throw new k(n)}}function _n(e,t){return Object.freeze({backend:`adb screenrecord`,outPath:e.outputPath,...e.clientOutputPath?{clientOutPath:e.clientOutputPath}:{},startedAt:t,scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,...e.activeSessionApp?{activeSessionApp:e.activeSessionApp}:{},...e.exportQuality?{exportQuality:e.exportQuality}:{},gestureEvents:[]})}function vn(e){let t=yn(e.chunkPaths);if(t===void 0)return{};let n=e.stoppedAtMs-e.startedAtMs;return n-t<2e3?{capturedDurationMs:t}:{capturedDurationMs:t,idleTailWarning:`Android screenrecord encodes a frame only when the screen changes, so this video ends at the last frame it encoded: it covers ${bn(t)}s of the ${bn(n)}s recording window.`}}function yn(e){let t=0;for(let n of e){let e=ze(n);if(e===void 0)return;t+=e}return t}function bn(e){return(e/1e3).toFixed(1)}async function xn(e){let{host:t,transport:n,evidence:r,recording:i,startedAtMs:a,progress:o}=e,s=e.reachedLimit===!0;return await En(e,await Ee({snapshot:i,progress:o,steps:{stop:async()=>(s=await j(n,r.chunks)||s,await Vt(n,r.chunks),{observation:{recorder:`confirmed`},...s?{warning:`Android adb screenrecord stopped before record stop, likely after reaching the 180s platform limit. The MP4 may be truncated; final interactions after the limit are not in the video.`}:{}}),collect:e=>Ht(n,r.chunks,e),finalize:({collectedPath:e,exportPath:n,stoppedAtMs:o})=>Sn({host:t,evidence:r,recording:i,startedAtMs:a,stoppedAtMs:o,collectedPath:e,exportPath:n}),discard:e=>wn(t,e,r.chunks.length)}}))}async function Sn(e){let{host:t,evidence:n,recording:r,collectedPath:i,exportPath:a}=e,o=Dn({collectedPath:i,exportPath:a,exportClientPath:r.clientOutPath,count:n.chunks.length}),s=o.length>1,c;try{await Cn(t,o),c=await t.screenRecording.finalize.complete({outputPath:a,showTouches:!s&&r.showTouches,gestureEvents:r.gestureEvents,exportQuality:r.exportQuality??`medium`,targetLabel:`Android recording`})}catch(e){for(let{served:e}of o)await t.screenRecording.outputs.remove(e.path);throw e}let l=vn({chunkPaths:o.map(({collected:e})=>e.path),startedAtMs:e.startedAtMs,stoppedAtMs:e.stoppedAtMs});return Tn({finalization:c,captured:l,recording:r,chunked:s,files:o})}async function Cn(e,t){for(let{collected:n,served:r}of t)await e.screenRecording.outputs.copy({from:n.path,to:r.path})}async function wn(e,t,n){for(let r=1;r<=n;r+=1)await e.screenRecording.outputs.remove(S(t,r))}function Tn(e){let{finalization:t,captured:n,recording:r,chunked:i,files:a}=e,o=[t.warning,...i?[`Android adb screenrecord is capped at 180s, so this recording was split into multiple MP4 chunks.`]:[],n.idleTailWarning].filter(e=>e!==void 0&&e.length>0);return{...t.telemetryPath===void 0?{}:{telemetryPath:t.telemetryPath},...o.length===0?{}:{warning:o.join(` `)},...i&&r.showTouches&&r.gestureEvents.length>0?{overlayWarning:`touch overlay burn-in is skipped for chunked Android recordings; returning raw chunks plus gesture telemetry`}:{},...n.capturedDurationMs===void 0?{}:{capturedDurationMs:n.capturedDurationMs},...i?{chunks:a.map(e=>e.served)}:{},nativePathDisposition:`retirable`}}async function En(e,t){let{transport:n,evidence:r,manifestPath:i}=e;return await P(n,i,Nt(r,t.result)),await M(n,r.chunks),{status:`completed`,result:{...t.result,nativePathDisposition:await Ut(n,r.chunks)}}}function Dn(e){return Object.freeze(Array.from({length:e.count},(t,n)=>({collected:Object.freeze({index:n+1,path:S(e.collectedPath,n+1)}),served:Object.freeze({index:n+1,path:S(e.exportPath,n+1),...e.exportClientPath===void 0?{}:{clientOutPath:S(e.exportClientPath,n+1)}})})))}async function On(e,t,n){try{let r=t.pendingRemotePath;if(await j(e,[...t.chunks,...await kn(e,t)]),await M(e,t.chunks),r!==void 0&&!await e.remove(r))throw Error(`failed to remove Android recording artifact: ${r}`);return await F(e,n),{status:`cleaned`}}catch(e){return An(e)}}async function kn(e,t){let n=t.pendingRemotePath;if(n===void 0)return[];let r=await e.probeRunningWriters(n);if(!r.conclusive)throw Error(`cannot list every recorder writing Android artifact: ${n}`);return r.writers.map((e,r)=>({index:t.chunks.length+1+r,remotePath:n,remotePid:e.pid,remoteStartTime:e.startTime}))}function An(e){return{status:`cleanup-pending`,reason:`transport-failed`,message:e instanceof Error?e.message:String(e)}}async function jn(e){let{transport:t,device:n,envelope:r,descriptor:i}=e;if(i.transportMode!==t.mode)return{status:`transport-unavailable`};let a=await t.readManifest(i.manifestPath);if(a.status===`unavailable`)return{status:`transport-unavailable`};let o=a.status===`read`?D(a.contents):void 0;return o&&Pt(o,n,r)&&Ft(o,i)?{status:`matched`,evidence:o}:{status:`ownership-lost`}}async function Mn(e){let t=await e.transport.readManifest(e.manifestPath);if(t.status!==`read`)return;let n=D(t.contents);return n&&Nn(n,e)?n:void 0}function Nn(e,t){return e.deviceId===t.deviceId&&e.sessionId===t.sessionId&&e.fenceToken===t.fence.token&&e.fenceGeneration===t.fence.generation}async function Pn(e){let{host:t,transport:n,device:r,input:i}=e,a=T.decode(i.envelope.descriptor.body);if(a.status!==`decoded`)return R(`descriptor-invalid`);let o=await jn({transport:n,device:r,envelope:i.envelope,descriptor:a.descriptor});return o.status===`matched`?await Fn({host:t,transport:n,device:r,input:i,descriptor:a.descriptor,evidence:o.evidence}):R(o.status===`transport-unavailable`?`transport-not-reattachable`:`ownership-fence-lost`)}async function L(e){let t=T.decode(e.input.envelope.descriptor.body);if(t.status!==`decoded`)return{status:`cleanup-pending`,reason:`manual-recovery-required`};let n=await jn({transport:e.transport,device:e.device,envelope:e.input.envelope,descriptor:t.descriptor});return n.status===`matched`?await On(e.transport,n.evidence,t.descriptor.manifestPath):n.status===`transport-unavailable`?{status:`cleanup-pending`,reason:`owner-unavailable`}:{status:`cleanup-pending`,reason:`ownership-fence-lost`}}async function Fn(e){let{host:t,transport:n,device:r,input:i,descriptor:a,evidence:o}=e;if(o.completion!==void 0){let e=await In(n,o);return e.status===`terminal`?{status:`completed`,result:{...o.completion,nativePathDisposition:e.nativePathDisposition}}:R(`ownership-fence-lost`,`Android recording completed evidence still names a live or unverifiable recorder.`)}if(o.pendingRemotePath!==void 0)return R(`transport-not-reattachable`,`Android recording launch was interrupted before its process identity was committed.`);let s=o.chunks.at(-1);if(!s)return{status:`missing`};let c=await n.inspect({pid:s.remotePid,remotePath:s.remotePath,startTime:s.remoteStartTime});if(c!==`owned-alive`&&await n.exists(s.remotePath)===!1)return R(`transport-not-reattachable`,`Android recording process ended before its artifact could be recovered.`);let l=Ln(i.envelope.sessionId,i.envelope.fence,a),u=!1;return{status:`active`,handle:Se(_n(l,o.startedAt),{finish:async(e,r)=>{let i=await xn({host:t,transport:n,evidence:o,manifestPath:a.manifestPath,recording:e,startedAtMs:o.startedAt,reachedLimit:O(c),progress:r});return u=!0,i},forceCleanup:async()=>u?{status:`cleaned`}:await L({transport:n,device:r,input:i})})}}async function In(e,t){try{for(let n of t.chunks)if(!O(await e.inspect({pid:n.remotePid,remotePath:n.remotePath,startTime:n.remoteStartTime})))return{status:`retained`};return{status:`terminal`,nativePathDisposition:await Ut(e,t.chunks)}}catch{return{status:`retained`}}}function Ln(e,t,n){return{sessionId:e,outputPath:n.outputPath,...n.clientOutputPath===void 0?{}:{clientOutputPath:n.clientOutputPath},scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:!1,recordOnlySession:n.recordOnlySession,...n.activeSessionApp===void 0?{}:{activeSessionApp:n.activeSessionApp},...n.exportQuality===void 0?{}:{exportQuality:n.exportQuality},fence:t}}function R(e,t){return{status:`unreattachable`,reason:e,...t===void 0?{}:{message:t}}}async function Rn(e){let{host:t,device:n,owner:r,signal:i}=e,a=await t.screenRecording.android.resolve(n);return Object.freeze({screenRecordingStart:async e=>await zn({host:t,transport:a,device:n,owner:r,input:e,signal:i}),screenRecordingReattach:async e=>await Pn({host:t,transport:a,device:n,input:e}),screenRecordingCleanup:async e=>await L({transport:a,device:n,input:e})})}async function zn(e){let{host:n,transport:r,device:i,owner:a,input:o,signal:s}=e;s.throwIfAborted();let c=Date.now(),l=await fn({transport:r,device:i,input:o,startedAt:c,signal:s,prepareOutput:async()=>await n.screenRecording.outputs.prepare(o.outputPath)}),u=l.manifestPath,d=[l.chunk],f,p,m,h=!1,g=()=>{f=setTimeout(()=>{p=ee().catch(e=>{m=e})},17e4),f.unref?.()},ee=async()=>{let e=d.at(-1);if(!e)throw Error(`Android recording has no active chunk`);let t=!1,n;try{n=await hn({transport:r,device:i,input:o,startedAt:c,chunks:d,manifestPath:u,preferredDir:b.posix.dirname(e.remotePath)})}catch(a){await N(r,e),t=!0;try{n=await hn({transport:r,device:i,input:o,startedAt:c,chunks:d,manifestPath:u,preferredDir:b.posix.dirname(e.remotePath)})}catch(e){throw e instanceof Error?e:a}}let a=[...d,{...n,index:d.length+1}];try{await P(r,u,E(i,o,c,a,void 0,r.mode))}catch(a){if(await Wt(r,[n]).catch(()=>{}),t)await P(r,u,E(i,o,c,d,n.remotePath,r.mode)).catch(()=>{});else try{await P(r,u,E(i,o,c,d,void 0,r.mode))}catch{await N(r,e).catch(()=>{}),await P(r,u,E(i,o,c,d,n.remotePath,r.mode)).catch(()=>{})}throw a}d=a,t||await N(r,e),g()};g();let _=Se(_n(o,c),{finish:async(e,t)=>{if(f&&clearTimeout(f),await p,m)throw m;let a=await xn({host:n,transport:r,evidence:E(i,o,c,d,void 0,r.mode),manifestPath:u,recording:e,startedAtMs:l.startedAtMs,progress:t});return h=!0,a},forceCleanup:async()=>{if(f&&clearTimeout(f),h)return{status:`cleaned`};try{await p}catch(e){m=e}let e=await Mn({transport:r,deviceId:i.id,sessionId:o.sessionId,fence:o.fence,manifestPath:u});return e?await On(r,e,u):{status:`cleanup-pending`,reason:`ownership-fence-lost`}}});return Object.freeze({pendingHandle:new ge(_),envelope:he({resourceKind:De,sessionId:o.sessionId,device:t(i),owner:a,fence:o.fence,lifecycle:`open`,descriptor:me(T,{backend:`adb-screenrecord`,manifestPath:u,outputPath:o.outputPath,...o.clientOutputPath===void 0?{}:{clientOutputPath:o.clientOutputPath},scope:o.scope,showTouches:o.showTouches,recordOnlySession:o.recordOnlySession,...o.activeSessionApp===void 0?{}:{activeSessionApp:o.activeSessionApp},...o.exportQuality===void 0?{}:{exportQuality:o.exportQuality},transportMode:r.mode})})})}const z=12e4,Bn=1e3;async function B(e,t,n,r){return r.throwIfAborted(),await Be(t)?{...t,booted:!0}:t.kind===`emulator`&&(t.booted!==!0||!V(t))?await Vn(e,t,n,r):(t.booted!==!0&&await Gn(e,t.id,z,r),{...t,booted:!0})}async function Vn(e,t,n,r){await Hn(e);let i=Kn(n),a=Un(await e.deviceReadiness.androidEmulator.discover(i,r),t.name,n.serial),o=V(a)?a:void 0,s=o?void 0:e.deviceReadiness.androidEmulator.launch(a.name,n.headless);try{let t=o??await Wn(e,a.name,i,n.serial,r);return await Gn(e,t.id,z,r),{...(await e.deviceReadiness.androidEmulator.discover(i,r)).find(e=>e.id===t.id)??t,name:a.name,booted:!0}}catch(t){throw s!==void 0&&r.aborted&&await e.deviceReadiness.androidEmulator.terminate(s),r.throwIfAborted(),t}}async function Hn(t){if(await t.toolchains.prepare(`android`),!await t.commands.which(`adb`))throw new e(`TOOL_MISSING`,`adb not found in PATH`);if(!await t.commands.which(`emulator`))throw new e(`TOOL_MISSING`,`emulator not found in PATH`)}function Un(t,n,r){let i=qn(t,n,r);if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No Android emulator AVD named ${n}`,{requestedAvdName:n,availableAvds:t.map(e=>e.name),hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."})}async function Wn(t,n,r,i,a){let o=t.clock.now()+z;for(;t.clock.now()<o;){let e=qn(await t.deviceReadiness.androidEmulator.discover(r,a),n,i);if(e&&V(e))return e;await t.clock.sleep(Bn,a)}throw new e(`COMMAND_FAILED`,`Android emulator did not appear in time`,{avdName:n,serial:i,timeoutMs:z})}async function Gn(t,n,r,a){let o=t.clock.now()+r;for(;t.clock.now()<o;){if((await t.commands.run({executable:`adb`,args:i(`adb`,`shell`,[`getprop`,`sys.boot_completed`],[`-s`,n]),allowFailure:!0,timeoutMs:Math.min(1e4,Math.max(1e3,o-t.clock.now()))},a)).stdout.trim()===`1`)return;await t.clock.sleep(Bn,a)}throw new e(`COMMAND_FAILED`,`Android device failed to finish booting`,{serial:n,timeoutMs:r,reason:`ANDROID_BOOT_TIMEOUT`})}function Kn(e){return{platform:`android`,kind:`emulator`,...e.serial?{serial:e.serial}:{},...e.androidSerialAllowlist?{androidSerialAllowlist:[...e.androidSerialAllowlist]}:{}}}function qn(e,t,n){let r=Jn(t);return e.find(e=>e.platform===`android`&&e.kind===`emulator`&&Jn(e.name)===r&&(!n||!V(e)||e.id===n))}function V(e){return e.id.startsWith(`emulator-`)}function Jn(e){return e.toLowerCase().replaceAll(`_`,` `).replaceAll(/\s+/g,` `).trim()}function Yn(e){let{host:t,device:n,signal:r}=e,i=Ue({device:n,signal:r,resolveInteractor:t.localInteractors.resolve});return Object.freeze({resolveOpenTarget:async e=>await t.androidApplications.resolveOpenTarget(n,e),prepareApplicationOpen:async e=>{await B(t,n,{headless:!1},r)},openApplication:async e=>await Xn(t,i,e),applyRuntimeHints:async e=>await t.androidApplications.applyRuntimeHints(n,e),clearRuntimeHints:async e=>await t.androidApplications.clearRuntimeHints(n,e),closeApplication:async e=>{e.ensureReady&&await B(t,n,{headless:!1},r),await Ve({device:n,interactor:await i.resolveInteractor(e.execution,e.appBundleId),positionals:e.positionals})},finalizeApplicationClose:async e=>{await t.androidApplications.restoreTestIme(n,{stateDir:e.stateDir});let i=e.shutdownTarget&&n.kind===`emulator`?await t.deviceShutdown.android.shutdownTarget(n,r):void 0;return i===void 0?{}:{shutdown:i}},prepareAppleRunner:Zn,configureProviderPortReverse:Zn})}async function Xn(t,n,r){let i={};if(r.relaunch&&r.target){let e=Date.now();await Ve({device:n.device,interactor:await n.resolveInteractor(r.execution,r.appBundleId),positionals:[r.appBundleId??r.target]}),i.relaunchCloseDurationMs=H(e)}if(c(r.runtimeHints)){if(!r.applyRuntimeHints)throw new e(`COMMAND_FAILED`,`Runtime hint operation was not admitted for this open.`,{reason:`runtime-hints-operation-missing`});let t=Date.now();await r.applyRuntimeHints({appId:r.appBundleId,values:r.runtimeHints}),i.runtimeHintsDurationMs=H(t)}let a=Date.now();await We({device:n.device,interactor:await n.resolveInteractor(r.execution,r.appBundleId),positionals:r.positionals,appBundleId:r.appBundleId,execution:r.execution}),i.openDispatchDurationMs=H(a),r.enableTestIme&&await t.androidApplications.activateTestIme(n.device,{stateDir:r.stateDir});let o=He(r);if(o){let e=Date.now();await We({device:n.device,interactor:await n.resolveInteractor({...r.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0},r.appBundleId),positionals:[o],appBundleId:r.appBundleId,execution:{...r.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0}}),i.launchUrlDurationMs=H(e)}else i.launchUrlDurationMs=0;let s=await t.androidApplications.inferOpenedAppBundleId(n.device,r.target,r.appBundleId);return s&&await t.androidApplications.resetFramePerfStats(n.device,s),i.postOpenSettleDurationMs=0,{appBundleId:s,timing:i}}function H(e){return Math.max(0,Date.now()-e)}async function Zn(){throw new e(`UNSUPPORTED_OPERATION`,`This lifecycle operation is unavailable for Android.`)}async function U(e,t,n,r,i){W(n);let a=r?void 0:await nr(e,t,i);if(b.extname(n).toLowerCase()===`.aab`?await tr(e,t,n,i):K(await e.androidTools.installPackage(t,n,{replace:!0},i),`adb install failed`),r)return r;let o=[...await nr(e,t,i)].filter(e=>!a?.has(e));return o.length===1?o[0]:void 0}function W(t){if(y()&&b.extname(t).toLowerCase()===`.aab`)throw new e(`UNSUPPORTED_OPERATION`,`Managed Android deployment does not support app bundles.`,{reason:`managed-bundle-install-unavailable`,hint:`Install an APK on this managed device.`})}async function Qn(e,t,n,r){let i=await G(e,t,[`uninstall`,n],r);if(i.exitCode===0)return;let a=`${i.stdout}\n${i.stderr}`.toLowerCase();a.includes(`unknown package`)||a.includes(`not installed`)||K(i,`adb uninstall failed for ${n}`)}async function $n(t,n,r,a){let o=r.payload,s=typeof o.action==`string`&&o.action.trim()?o.action.trim():`${r.appId}.TEST_PUSH`,c=[`am`,`broadcast`,`-a`,s,`-p`,r.appId];typeof o.receiver==`string`&&o.receiver.trim()&&c.push(`-n`,o.receiver.trim());let l=o.extras??{};if(typeof l!=`object`||!l||Array.isArray(l))throw new e(`INVALID_ARGS`,`Android push payload extras must be an object`);let u=0;for(let[e,t]of Object.entries(l))e&&(rr(c,e,t),u+=1);return K(await G(t,n,i(`adb`,`shell`,c),a),`adb push broadcast failed`),{action:s,extrasCount:u}}function er(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(/[._-]+/).map(e=>e.trim().toLowerCase()).filter(Boolean),r=[...n].reverse().find(e=>!t.has(e))??n.at(-1)??e;return r.charAt(0).toUpperCase()+r.slice(1)}async function tr(t,n,r,i){if(await t.androidTools.installBundle(n,r,`universal`,i))return;let a=await t.commands.which(`bundletool`),o=t.androidDeployment.bundletoolJar;if(!a&&!o)throw new e(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR.`);let s=a?`bundletool`:`java`,c=a?[]:[`-jar`,o],l=await t.temporaryFiles.create({prefix:`agent-device-aab-`,suffix:`.apks`}),u=l.path;try{K(await t.commands.run({executable:s,args:[...c,`build-apks`,`--bundle`,r,`--output`,u,`--mode`,`universal`]},i),`bundletool build-apks failed`),K(await t.commands.run({executable:s,args:[...c,`install-apks`,`--apks`,u,`--device-id`,n.id]},i),`bundletool install-apks failed`)}finally{await l[Symbol.asyncDispose]()}}async function nr(e,t,n){let r=await G(e,t,i(`adb`,`shell`,[`pm`,`list`,`packages`]),n);return K(r,`adb package inventory failed`),new Set(r.stdout.split(`
@@ -1 +1 @@
1
- import{L as e}from"./sdk-contracts.js";function t(e){return Object.freeze({canShutdownTarget:n,shutdownTarget:async(t,n)=>await r(e.commands,t,n)})}function n(e){return e.platform===`android`&&e.kind===`emulator`}async function r(t,n,r){if(n.booted===!1)return i();r.throwIfAborted();try{let e=await t.run({executable:`adb`,args:[`-s`,n.id,`emu`,`kill`],allowFailure:!0,timeoutMs:15e3},r);r.throwIfAborted();let i=e.exitCode??-1;return{success:i===0,exitCode:i,stdout:e.stdout,stderr:e.stderr}}catch(t){r.throwIfAborted();let n=e(t);return{success:!1,exitCode:-1,stdout:``,stderr:n.message,error:n}}}function i(){return{success:!0,exitCode:0,stdout:``,stderr:``}}export{t as createAndroidShutdownRuntime};
1
+ import{R as e}from"./sdk-contracts.js";function t(e){return Object.freeze({canShutdownTarget:n,shutdownTarget:async(t,n)=>await r(e.commands,t,n)})}function n(e){return e.platform===`android`&&e.kind===`emulator`}async function r(t,n,r){if(n.booted===!1)return i();r.throwIfAborted();try{let e=await t.run({executable:`adb`,args:[`-s`,n.id,`emu`,`kill`],allowFailure:!0,timeoutMs:15e3},r);r.throwIfAborted();let i=e.exitCode??-1;return{success:i===0,exitCode:i,stdout:e.stdout,stderr:e.stderr}}catch(t){r.throwIfAborted();let n=e(t);return{success:!1,exitCode:-1,stdout:``,stderr:n.message,error:n}}}function i(){return{success:!0,exitCode:0,stdout:``,stderr:``}}export{t as createAndroidShutdownRuntime};