agent-device 0.20.7 → 0.20.9

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 (209) hide show
  1. package/README.md +94 -31
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.apk → agent-device-android-ime-helper-0.20.9.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.manifest.json → agent-device-android-ime-helper-0.20.9.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.apk → agent-device-android-snapshot-helper-0.20.9.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.manifest.json → agent-device-android-snapshot-helper-0.20.9.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +3 -0
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +13 -7
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +4 -112
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +5 -1
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +9 -1
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +90 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +4 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +46 -10
  16. package/dist/src/agent-browser-tool.js +1 -1
  17. package/dist/src/agent-device-client.js +2 -2
  18. package/dist/src/android-adb.d.ts +5 -5
  19. package/dist/src/android-adb.js +1 -1
  20. package/dist/src/android.js +1 -1
  21. package/dist/src/app-helpers.js +1 -1
  22. package/dist/src/app-lifecycle.js +6 -7
  23. package/dist/src/app-lifecycle2.js +2 -2
  24. package/dist/src/app-log-reconnect.js +1 -1
  25. package/dist/src/app-log-runtime.js +3 -3
  26. package/dist/src/app-resolution.js +2 -2
  27. package/dist/src/app-state.js +2 -0
  28. package/dist/src/appearance.js +1 -0
  29. package/dist/src/apps.js +5 -5
  30. package/dist/src/artifacts.d.ts +1 -1
  31. package/dist/src/audio-probe.js +1 -1
  32. package/dist/src/backend-snapshot-options.js +1 -0
  33. package/dist/src/boot-diagnostics.js +2 -2
  34. package/dist/src/bounds.js +1 -0
  35. package/dist/src/byte-limit-stream.js +1 -0
  36. package/dist/src/cancel.js +1 -0
  37. package/dist/src/cli-config.js +1 -1
  38. package/dist/src/cli-help.js +25 -20
  39. package/dist/src/cli.js +6 -6
  40. package/dist/src/client-metro.js +1 -1
  41. package/dist/src/command-catalog.js +1 -0
  42. package/dist/src/command-metadata.js +1 -1
  43. package/dist/src/command-schema.js +1 -1
  44. package/dist/src/command-surface.js +1 -1
  45. package/dist/src/config.js +1 -0
  46. package/dist/src/connection-runtime.js +1 -1
  47. package/dist/src/connection.js +3 -3
  48. package/dist/src/contracts.js +1 -1
  49. package/dist/src/debug-symbols.js +1 -1
  50. package/dist/src/device-claim-inspection.js +1 -1
  51. package/dist/src/device-input-state.js +1 -1
  52. package/dist/src/device-ready.js +1 -0
  53. package/dist/src/device2.js +2 -2
  54. package/dist/src/dispatch.js +1 -0
  55. package/dist/src/entities.js +1 -1
  56. package/dist/src/find.js +1 -1
  57. package/dist/src/finders.js +1 -1
  58. package/dist/src/generic-settle.js +1 -1
  59. package/dist/src/generic.js +1 -1
  60. package/dist/src/handler-utils.js +1 -0
  61. package/dist/src/harmonyos.js +1 -1
  62. package/dist/src/hdc.js +1 -0
  63. package/dist/src/helper-package-install.js +1 -0
  64. package/dist/src/helper.js +2 -2
  65. package/dist/src/host-process.js +3 -2
  66. package/dist/src/ime-lifecycle.js +2 -9
  67. package/dist/src/ime-recovery-marker.js +1 -0
  68. package/dist/src/index.d.ts +35 -26
  69. package/dist/src/index.js +1 -1
  70. package/dist/src/input-actions.js +3 -3
  71. package/dist/src/input-actions2.js +1 -1
  72. package/dist/src/input-actions3.js +1 -1
  73. package/dist/src/install-artifact.js +1 -1
  74. package/dist/src/install-artifact2.js +1 -1
  75. package/dist/src/install-source2.js +1 -1
  76. package/dist/src/interaction-common.js +1 -0
  77. package/dist/src/interaction-runtime.js +1 -1
  78. package/dist/src/interaction-snapshot.js +1 -1
  79. package/dist/src/interaction.js +1 -1
  80. package/dist/src/interaction2.js +1 -0
  81. package/dist/src/interactor.js +2 -2
  82. package/dist/src/interactor2.js +1 -1
  83. package/dist/src/interactors.js +1 -0
  84. package/dist/src/internal/bin.js +1 -1
  85. package/dist/src/internal/daemon.js +4 -29
  86. package/dist/src/internal/png-worker.js +1 -1
  87. package/dist/src/inventory.js +1 -1
  88. package/dist/src/inventory2.js +1 -1
  89. package/dist/src/keyed-lock.js +1 -0
  90. package/dist/src/lease-context.js +1 -1
  91. package/dist/src/lease.js +1 -1
  92. package/dist/src/limrun-runtime-dependencies.js +1 -1
  93. package/dist/src/limrun.d.ts +3 -1
  94. package/dist/src/limrun.js +1 -1
  95. package/dist/src/linux.js +1 -1
  96. package/dist/src/location-coordinates.js +1 -0
  97. package/dist/src/logcat.js +1 -1
  98. package/dist/src/manifest.js +1 -1
  99. package/dist/src/observability.js +1 -0
  100. package/dist/src/output-path.js +1 -0
  101. package/dist/src/owner-identity.js +1 -1
  102. package/dist/src/perf.js +4 -0
  103. package/dist/src/physical-device-control.js +1 -1
  104. package/dist/src/platform-runtime-app-log-process.js +1 -1
  105. package/dist/src/platform-runtime-host.js +1 -1
  106. package/dist/src/platform-runtime-open-target.js +1 -0
  107. package/dist/src/platform-runtime-operation-host.js +4 -4
  108. package/dist/src/platform-runtime-runtime-hints.js +2 -0
  109. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -0
  110. package/dist/src/platform-runtime-screen-recording-apple-host.js +1 -0
  111. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -0
  112. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -0
  113. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -0
  114. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -0
  115. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -0
  116. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -0
  117. package/dist/src/platform-runtime-screen-recording-output-host.js +1 -0
  118. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -0
  119. package/dist/src/platform-runtime.js +1 -1
  120. package/dist/src/platform-runtime2.js +1 -0
  121. package/dist/src/plist.js +1 -1
  122. package/dist/src/png-resize.js +1 -0
  123. package/dist/src/png-worker-contract.js +1 -1
  124. package/dist/src/prepare-kind.js +13 -13
  125. package/dist/src/process-lock.js +1 -1
  126. package/dist/src/project-runtime.js +1 -0
  127. package/dist/src/provider-webdriver.js +1 -1
  128. package/dist/src/provider.js +1 -1
  129. package/dist/src/proxy.js +1 -1
  130. package/dist/src/react-native.js +1 -1
  131. package/dist/src/record-runtime.js +1 -0
  132. package/dist/src/record-trace.js +1 -1
  133. package/dist/src/recording-export-quality.js +1 -0
  134. package/dist/src/recording-telemetry.js +1 -0
  135. package/dist/src/registry.js +29 -26
  136. package/dist/src/replay.js +2 -2
  137. package/dist/src/reporting.js +3 -3
  138. package/dist/src/rolldown-runtime.js +1 -0
  139. package/dist/src/runner-client.js +1 -1
  140. package/dist/src/runner-disposal.js +1 -1
  141. package/dist/src/runner-lease.js +1 -1
  142. package/dist/src/runner-sequence.js +1 -1
  143. package/dist/src/runtime-transport.js +1 -1
  144. package/dist/src/runtime.js +3 -3
  145. package/dist/src/runtime2.js +4 -3
  146. package/dist/src/runtime3.js +1 -3
  147. package/dist/src/runtime4.js +3 -1
  148. package/dist/src/runtime5.js +1 -1
  149. package/dist/src/runtime6.js +1 -1
  150. package/dist/src/runtime7.js +1 -1
  151. package/dist/src/runtime8.js +1 -0
  152. package/dist/src/runtime9.js +1 -0
  153. package/dist/src/scoped-provider.js +1 -0
  154. package/dist/src/screenshot-density.js +1 -0
  155. package/dist/src/screenshot-geometry.js +1 -0
  156. package/dist/src/screenshot-result.js +4 -4
  157. package/dist/src/screenshot.js +1 -1
  158. package/dist/src/sdk-android-adb.d.ts +20 -2
  159. package/dist/src/sdk-android-adb.js +4 -4
  160. package/dist/src/sdk-batch-runner.js +3 -3
  161. package/dist/src/sdk-contracts.d.ts +3 -3
  162. package/dist/src/sdk-contracts.js +2 -2
  163. package/dist/src/sdk-device.js +1 -1
  164. package/dist/src/sdk-finders.js +1 -1
  165. package/dist/src/sdk-io.js +1 -1
  166. package/dist/src/sdk-selectors.d.ts +24 -20
  167. package/dist/src/sdk-selectors.js +1 -1
  168. package/dist/src/sdk.js +1 -0
  169. package/dist/src/selector-runtime.js +1 -1
  170. package/dist/src/selectors.d.ts +1 -1
  171. package/dist/src/selectors.js +1 -1
  172. package/dist/src/server.js +2 -2
  173. package/dist/src/session-target-evidence.js +1 -1
  174. package/dist/src/session.js +1 -30
  175. package/dist/src/session2.js +28 -0
  176. package/dist/src/setting-state.js +1 -1
  177. package/dist/src/shared.js +1 -1
  178. package/dist/src/simctl.js +1 -0
  179. package/dist/src/simulator-state.js +1 -0
  180. package/dist/src/simulator.js +1 -1
  181. package/dist/src/snapshot-runtime.js +1 -1
  182. package/dist/src/snapshot-session.js +1 -1
  183. package/dist/src/snapshot.js +8 -1
  184. package/dist/src/snapshot2.js +1 -1
  185. package/dist/src/snapshot3.js +1 -0
  186. package/dist/src/src.js +1 -1
  187. package/dist/src/src2.js +1 -2
  188. package/dist/src/src3.js +2 -1
  189. package/dist/src/string-enum.js +1 -0
  190. package/dist/src/tool-provider.js +3 -3
  191. package/dist/src/tool-provider2.js +1 -1
  192. package/dist/src/update-check.js +1 -1
  193. package/dist/src/verdict.js +1 -0
  194. package/dist/src/verified-file.js +1 -0
  195. package/dist/src/version.js +1 -1
  196. package/dist/src/video.js +23 -0
  197. package/package.json +8 -6
  198. package/server.json +3 -3
  199. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +0 -1
  200. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +0 -1
  201. package/dist/src/context.js +0 -1
  202. package/dist/src/interaction-touch-reference-frame.js +0 -1
  203. package/dist/src/notifications.js +0 -1
  204. package/dist/src/platform-runtime-toolchain-host.js +0 -1
  205. package/dist/src/runner-provider.js +0 -1
  206. package/dist/src/text-surface.js +0 -1
  207. package/dist/src/tool-provider3.js +0 -1
  208. package/skills/agent-device/SKILL.md +0 -20
  209. package/skills/dogfood/SKILL.md +0 -27
@@ -925,7 +925,7 @@ extension RunnerTests {
925
925
  return rect.intersects(viewport)
926
926
  }
927
927
 
928
- private func isVisibleInRegularSnapshot(
928
+ func isVisibleInRegularSnapshot(
929
929
  _ rect: CGRect,
930
930
  viewport: CGRect,
931
931
  scrollContainerAnchor: (index: Int, rect: CGRect)?
@@ -956,13 +956,33 @@ extension RunnerTests {
956
956
  for snapshot: XCUIElementSnapshot,
957
957
  visible: Bool,
958
958
  nodeIndex: Int?
959
+ ) -> (index: Int, rect: CGRect)? {
960
+ return scrollContainerAnchor(
961
+ for: snapshot.elementType,
962
+ hasChildren: !snapshot.children.isEmpty,
963
+ visible: visible,
964
+ frame: snapshot.frame,
965
+ nodeIndex: nodeIndex
966
+ )
967
+ }
968
+
969
+ func scrollContainerAnchor(
970
+ for elementType: XCUIElement.ElementType,
971
+ hasChildren: Bool,
972
+ visible: Bool,
973
+ frame: CGRect,
974
+ nodeIndex: Int?
959
975
  ) -> (index: Int, rect: CGRect)? {
960
976
  guard let nodeIndex else { return nil }
961
- if !isScrollableContainer(snapshot, visible: visible) { return nil }
962
- return (nodeIndex, snapshot.frame)
977
+ if !isScrollableContainer(
978
+ elementType: elementType,
979
+ hasChildren: hasChildren,
980
+ visible: visible
981
+ ) { return nil }
982
+ return (nodeIndex, frame)
963
983
  }
964
984
 
965
- private func rememberHiddenContentHint(
985
+ func rememberHiddenContentHint(
966
986
  for frame: CGRect,
967
987
  relativeTo scrollContainerAnchor: (index: Int, rect: CGRect),
968
988
  hints: inout [Int: (above: Bool, below: Bool)]
@@ -979,7 +999,7 @@ extension RunnerTests {
979
999
  hints[scrollContainerAnchor.index] = hint
980
1000
  }
981
1001
 
982
- private func applyHiddenContentHints(
1002
+ func applyHiddenContentHints(
983
1003
  _ hints: [Int: (above: Bool, below: Bool)],
984
1004
  to nodes: [SnapshotNode]
985
1005
  ) -> [SnapshotNode] {
@@ -1002,7 +1022,8 @@ extension RunnerTests {
1002
1022
  depth: node.depth,
1003
1023
  parentIndex: node.parentIndex,
1004
1024
  hiddenContentAbove: hiddenContentAbove,
1005
- hiddenContentBelow: hiddenContentBelow
1025
+ hiddenContentBelow: hiddenContentBelow,
1026
+ actions: node.actions
1006
1027
  )
1007
1028
  }
1008
1029
  }
@@ -1266,7 +1287,12 @@ extension RunnerTests {
1266
1287
  valueText: valueText,
1267
1288
  visible: visible
1268
1289
  )
1269
- if !flatSnapshotFilterDecision(filterNode, options: options, insideMatchedScope: false).include {
1290
+ if !flatSnapshotFilterDecision(
1291
+ filterNode,
1292
+ options: options,
1293
+ visibilityPolicy: .interactiveOnly,
1294
+ insideMatchedScope: false
1295
+ ).include {
1270
1296
  return
1271
1297
  }
1272
1298
 
@@ -1295,8 +1321,18 @@ extension RunnerTests {
1295
1321
  }
1296
1322
 
1297
1323
  private func isScrollableContainer(_ snapshot: XCUIElementSnapshot, visible: Bool) -> Bool {
1298
- if !visible { return false }
1299
- if !Self.scrollContainerTypes.contains(snapshot.elementType) { return false }
1300
- return !snapshot.children.isEmpty
1324
+ return isScrollableContainer(
1325
+ elementType: snapshot.elementType,
1326
+ hasChildren: !snapshot.children.isEmpty,
1327
+ visible: visible
1328
+ )
1329
+ }
1330
+
1331
+ private func isScrollableContainer(
1332
+ elementType: XCUIElement.ElementType,
1333
+ hasChildren: Bool,
1334
+ visible: Bool
1335
+ ) -> Bool {
1336
+ return visible && hasChildren && Self.scrollContainerTypes.contains(elementType)
1301
1337
  }
1302
1338
  }
@@ -1 +1 @@
1
- import{o as e}from"./png-worker-contract.js";import{_ as t,v as n}from"./sdk-contracts.js";import{A as r,_ as i,w as a}from"./sdk-android-adb.js";import{a as o,l as s,s as c,t as l}from"./host-process.js";import{t as u}from"./process-lock.js";import d from"node:path";import f from"node:crypto";import p from"node:fs";import m from"node:os";const h=new Map;function g(e){let t=f.createHash(`sha256`);return t.update(d.resolve(e.stateDir)),t.update(`\0`),t.update(d.resolve(e.installDir)),`--agent-device-managed-web=${t.digest(`hex`).slice(0,16)}`}function _(e,t){let n=g(t),r=e?.trim();return r?T(r).includes(n)?r:`${r},${n}`:n}function v(e){return E(e.AGENT_BROWSER_IDLE_TIMEOUT_MS)??E(e.AGENT_DEVICE_WEB_IDLE_TIMEOUT_MS)??3e5}function y(e,t){if(e.pid!==process.pid&&D(e.command)){if(e.command.includes(g(t)))return{process:e,reason:`launch-marker`};if(O(t).some(t=>j(e,t)))return{process:e,reason:`managed-browser-home`}}}function b(e,t){let n=e.flatMap(e=>{let n=y(e,t);return n?[n]:[]});return{count:n.length,pids:n.map(e=>e.process.pid),processes:n}}async function x(e){return b(await w(),e)}async function S(e,t,n={}){let i=k([...n.openWebSessionNames??[]]);if(i.length>0)return A(`open-web-session`,{openWebSessionNames:i});let a=v(process.env),o=N(e);if(o!==void 0&&Date.now()-o<a)return A(`recent-browser-activity`,{idleTimeoutMs:a,latestActivityMs:o});let c=await w(),u=b(c,e),d=l(u.processes.map(e=>e.process.pid),c).map(e=>e.pid),f={...u,signalPids:d};return u.count===0?f:(r({level:`warn`,phase:`web_agent_browser_orphan_cleanup`,data:{reason:t,count:u.count,pids:u.pids,signalPids:d,stateDir:e.stateDir,installDir:e.installDir,matchReasons:u.processes.map(e=>e.reason)}}),await s({pids:d,termTimeoutMs:1500,killTimeoutMs:1e3}),f)}async function C(e,t={}){let n=Date.now(),r=d.resolve(e.stateDir),i=h.get(r);if(!(i!==void 0&&n-i<3e4))return h.set(r,n),await S(e,`provider-startup`,t)}async function w(){return await a(async()=>await o({timeoutMs:1500}))}function T(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function E(e){if(e===void 0||e.trim()===``)return;let t=Number.parseInt(e,10);return Number.isInteger(t)&&t>0?t:void 0}function D(e){return/\b(?:Google Chrome for Testing|Chrome for Testing|Chromium|chrome|chrome\.exe|chromium|chromium-browser|headless_shell)\b/i.test(e)}function O(e){return k([d.join(e.homeDir,`.agent-browser`,`browsers`),d.join(e.runtimeHomeDir,`.agent-browser`,`browsers`)])}function k(e){return[...new Set(e.filter(e=>e.length>0))]}function A(e,t){return{count:0,pids:[],processes:[],signalPids:[],skipped:{reason:e,...t}}}function j(e,t){let n=M(e.command),r=`${M(d.resolve(t)).replace(/\/+$/,``)}/`;return n.includes(r)}function M(e){return e.replace(/\\/g,`/`)}function N(e){let t=ee(e.socketDir).map(e=>P(e)).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function ee(e){try{return p.readdirSync(e).map(t=>d.join(e,t))}catch{return[]}}function P(e){try{return p.statSync(e).mtimeMs}catch{return}}var F=e({doctorManagedAgentBrowser:()=>H,getManagedAgentBrowserStatus:()=>U,mapManagedAgentBrowserError:()=>$,resolveAgentBrowserTool:()=>B,setupManagedAgentBrowser:()=>V});const I=`0.27.1`,L=`agent-browser`,R=5*6e4,z=6e4;async function B(e){let t=U(e);if(t.installed)return W(t);throw Q(t)}async function V(e){let t=U(e);te(t.nodeMajor);let n=await u({lockDirPath:d.join(t.installDir,`..`,`.agent-browser-install.lock`),owner:{pid:process.pid,startTime:c(process.pid),acquiredAtMs:Date.now()},timeoutMs:R,description:`managed agent-browser setup`});try{let t=U(e);return t.installed?t:(p.mkdirSync(t.installDir,{recursive:!0}),await G(t),await K(t,[`install`],{timeoutMs:R}),await K(t,[`doctor`,`--offline`,`--quick`],{timeoutMs:z}),Y(t),U(e))}finally{await n()}}async function H(e){let t=U(e);if(!t.installed)throw Q(t);return{status:t,...await K(t,[`doctor`,`--offline`,`--quick`],{timeoutMs:z,allowFailure:!0})}}function U(e){let t=e.stateDir??process.env.AGENT_DEVICE_STATE_DIR??oe(),n=d.join(t,`tools`,`agent-browser`,I),r=Z(n),i=d.join(n,`home`),a=ne(n),o=re(n),s=ae(r)&&X(n),c=Number.parseInt(process.versions.node.split(`.`)[0]??`0`,10);return{version:I,stateDir:t,installDir:n,binaryPath:r,homeDir:i,runtimeHomeDir:a,socketDir:o,installed:s,nodeMajor:c,nodeSupported:c>=24}}function W(e){if(!e.installed)throw Q(e);return{command:e.binaryPath,env:q(e,process.env)}}async function G(e){let t=d.join(e.installDir,`package`);p.mkdirSync(t,{recursive:!0}),await i(`npm`,[`install`,`--prefix`,t,`--no-audit`,`--no-fund`,`--no-save`,`${L}@${I}`],{env:process.env,timeoutMs:R})}async function K(e,t,n){return await i(e.binaryPath,t,{allowFailure:n.allowFailure,env:q(e,process.env),timeoutMs:n.timeoutMs})}function q(e,t){return p.mkdirSync(e.homeDir,{recursive:!0}),J(e),p.mkdirSync(e.socketDir,{recursive:!0}),{...t,HOME:e.runtimeHomeDir,AGENT_BROWSER_SOCKET_DIR:e.socketDir,AGENT_BROWSER_IDLE_TIMEOUT_MS:String(v(t)),AGENT_BROWSER_ARGS:_(t.AGENT_BROWSER_ARGS,e)}}function J(e){if(e.runtimeHomeDir!==e.homeDir){p.mkdirSync(d.dirname(e.runtimeHomeDir),{recursive:!0});try{let t=p.lstatSync(e.runtimeHomeDir);if(t.isSymbolicLink()&&p.readlinkSync(e.runtimeHomeDir)===e.homeDir||t.isDirectory())return;t.isSymbolicLink()&&p.unlinkSync(e.runtimeHomeDir)}catch(e){if(!ie(e))throw e}try{p.symlinkSync(e.homeDir,e.runtimeHomeDir,`dir`)}catch{p.mkdirSync(e.runtimeHomeDir,{recursive:!0})}}}function Y(e){p.writeFileSync(d.join(e.installDir,`manifest.json`),JSON.stringify({package:L,version:I,node:process.version,installedAt:new Date().toISOString()},null,2),`utf8`)}function X(e){return p.existsSync(d.join(e,`manifest.json`))}function Z(e){let t=d.join(e,`package`);return d.join(t,`node_modules`,`.bin`,process.platform===`win32`?`agent-browser.cmd`:`agent-browser`)}function Q(e){return new t(`TOOL_MISSING`,`Managed web browser backend is not installed.`,{version:I,installDir:e.installDir,hint:e.nodeSupported===!1?`Web automation requires Node 24+; current Node is ${process.version}.`:"Run `agent-device web setup` to install the managed web backend."})}function te(e){if(!(e>=24))throw new t(`UNSUPPORTED_OPERATION`,`Web automation requires Node 24 or newer.`,{currentNode:process.version,requiredNodeMajor:24,hint:`Run agent-device with Node 24+ for web setup and web automation.`})}function ne(e){if(process.platform===`win32`)return d.join(e,`home`);let t=f.createHash(`sha1`).update(e).digest(`hex`).slice(0,12);return d.join(m.tmpdir(),`agent-device-web`,t)}function re(e){let t=f.createHash(`sha1`).update(e).digest(`hex`).slice(0,12);return d.join(m.tmpdir(),`adw`,t)}function ie(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function ae(e){try{return p.accessSync(e,p.constants.X_OK),!0}catch{return!1}}function oe(){return d.join(process.env.HOME??process.cwd(),`.agent-device`)}function $(e){let r=n(e);return r.code===`TOOL_MISSING`?new t(r.code,r.message,{...r.details??{},hint:typeof r.details?.hint==`string`?r.details.hint:"Run `agent-device web setup` to install the managed web backend."}):r}export{S as a,B as i,U as n,C as o,$ as r,x as s,F as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n}from"./sdk-contracts.js";import{A as r,_ as i,w as a}from"./sdk-android-adb.js";import{a as o,c as s,t as c,u as l}from"./host-process.js";import{t as u}from"./process-lock.js";import d from"node:path";import f from"node:crypto";import p from"node:fs";import m from"node:os";const h=new Map;function g(e){let t=f.createHash(`sha256`);return t.update(d.resolve(e.stateDir)),t.update(`\0`),t.update(d.resolve(e.installDir)),`--agent-device-managed-web=${t.digest(`hex`).slice(0,16)}`}function _(e,t){let n=g(t),r=e?.trim();return r?T(r).includes(n)?r:`${r},${n}`:n}function v(e){return E(e.AGENT_BROWSER_IDLE_TIMEOUT_MS)??E(e.AGENT_DEVICE_WEB_IDLE_TIMEOUT_MS)??3e5}function y(e,t){if(e.pid!==process.pid&&D(e.command)){if(e.command.includes(g(t)))return{process:e,reason:`launch-marker`};if(O(t).some(t=>j(e,t)))return{process:e,reason:`managed-browser-home`}}}function b(e,t){let n=e.flatMap(e=>{let n=y(e,t);return n?[n]:[]});return{count:n.length,pids:n.map(e=>e.process.pid),processes:n}}async function x(e){return b(await w(),e)}async function S(e,t,n={}){let i=k([...n.openWebSessionNames??[]]);if(i.length>0)return A(`open-web-session`,{openWebSessionNames:i});let a=v(process.env),o=N(e);if(o!==void 0&&Date.now()-o<a)return A(`recent-browser-activity`,{idleTimeoutMs:a,latestActivityMs:o});let s=await w(),u=b(s,e),d=c(u.processes.map(e=>e.process.pid),s).map(e=>e.pid),f={...u,signalPids:d};return u.count===0?f:(r({level:`warn`,phase:`web_agent_browser_orphan_cleanup`,data:{reason:t,count:u.count,pids:u.pids,signalPids:d,stateDir:e.stateDir,installDir:e.installDir,matchReasons:u.processes.map(e=>e.reason)}}),await l({pids:d,termTimeoutMs:1500,killTimeoutMs:1e3}),f)}async function C(e,t={}){let n=Date.now(),r=d.resolve(e.stateDir),i=h.get(r);if(!(i!==void 0&&n-i<3e4))return h.set(r,n),await S(e,`provider-startup`,t)}async function w(){return await a(async()=>await o({timeoutMs:1500}))}function T(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function E(e){if(e===void 0||e.trim()===``)return;let t=Number.parseInt(e,10);return Number.isInteger(t)&&t>0?t:void 0}function D(e){return/\b(?:Google Chrome for Testing|Chrome for Testing|Chromium|chrome|chrome\.exe|chromium|chromium-browser|headless_shell)\b/i.test(e)}function O(e){return k([d.join(e.homeDir,`.agent-browser`,`browsers`),d.join(e.runtimeHomeDir,`.agent-browser`,`browsers`)])}function k(e){return[...new Set(e.filter(e=>e.length>0))]}function A(e,t){return{count:0,pids:[],processes:[],signalPids:[],skipped:{reason:e,...t}}}function j(e,t){let n=M(e.command),r=`${M(d.resolve(t)).replace(/\/+$/,``)}/`;return n.includes(r)}function M(e){return e.replace(/\\/g,`/`)}function N(e){let t=ee(e.socketDir).map(e=>P(e)).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function ee(e){try{return p.readdirSync(e).map(t=>d.join(e,t))}catch{return[]}}function P(e){try{return p.statSync(e).mtimeMs}catch{return}}var F=e({doctorManagedAgentBrowser:()=>H,getManagedAgentBrowserStatus:()=>U,mapManagedAgentBrowserError:()=>$,resolveAgentBrowserTool:()=>B,setupManagedAgentBrowser:()=>V});const I=`0.27.1`,L=`agent-browser`,R=5*6e4,z=6e4;async function B(e){let t=U(e);if(t.installed)return W(t);throw Q(t)}async function V(e){let t=U(e);te(t.nodeMajor);let n=await u({lockDirPath:d.join(t.installDir,`..`,`.agent-browser-install.lock`),owner:{pid:process.pid,startTime:s(process.pid),acquiredAtMs:Date.now()},timeoutMs:R,description:`managed agent-browser setup`});try{let t=U(e);return t.installed?t:(p.mkdirSync(t.installDir,{recursive:!0}),await G(t),await K(t,[`install`],{timeoutMs:R}),await K(t,[`doctor`,`--offline`,`--quick`],{timeoutMs:z}),Y(t),U(e))}finally{await n()}}async function H(e){let t=U(e);if(!t.installed)throw Q(t);return{status:t,...await K(t,[`doctor`,`--offline`,`--quick`],{timeoutMs:z,allowFailure:!0})}}function U(e){let t=e.stateDir??process.env.AGENT_DEVICE_STATE_DIR??oe(),n=d.join(t,`tools`,`agent-browser`,I),r=Z(n),i=d.join(n,`home`),a=ne(n),o=re(n),s=ae(r)&&X(n),c=Number.parseInt(process.versions.node.split(`.`)[0]??`0`,10);return{version:I,stateDir:t,installDir:n,binaryPath:r,homeDir:i,runtimeHomeDir:a,socketDir:o,installed:s,nodeMajor:c,nodeSupported:c>=24}}function W(e){if(!e.installed)throw Q(e);return{command:e.binaryPath,env:q(e,process.env)}}async function G(e){let t=d.join(e.installDir,`package`);p.mkdirSync(t,{recursive:!0}),await i(`npm`,[`install`,`--prefix`,t,`--no-audit`,`--no-fund`,`--no-save`,`${L}@${I}`],{env:process.env,timeoutMs:R})}async function K(e,t,n){return await i(e.binaryPath,t,{allowFailure:n.allowFailure,env:q(e,process.env),timeoutMs:n.timeoutMs})}function q(e,t){return p.mkdirSync(e.homeDir,{recursive:!0}),J(e),p.mkdirSync(e.socketDir,{recursive:!0}),{...t,HOME:e.runtimeHomeDir,AGENT_BROWSER_SOCKET_DIR:e.socketDir,AGENT_BROWSER_IDLE_TIMEOUT_MS:String(v(t)),AGENT_BROWSER_ARGS:_(t.AGENT_BROWSER_ARGS,e)}}function J(e){if(e.runtimeHomeDir!==e.homeDir){p.mkdirSync(d.dirname(e.runtimeHomeDir),{recursive:!0});try{let t=p.lstatSync(e.runtimeHomeDir);if(t.isSymbolicLink()&&p.readlinkSync(e.runtimeHomeDir)===e.homeDir||t.isDirectory())return;t.isSymbolicLink()&&p.unlinkSync(e.runtimeHomeDir)}catch(e){if(!ie(e))throw e}try{p.symlinkSync(e.homeDir,e.runtimeHomeDir,`dir`)}catch{p.mkdirSync(e.runtimeHomeDir,{recursive:!0})}}}function Y(e){p.writeFileSync(d.join(e.installDir,`manifest.json`),JSON.stringify({package:L,version:I,node:process.version,installedAt:new Date().toISOString()},null,2),`utf8`)}function X(e){return p.existsSync(d.join(e,`manifest.json`))}function Z(e){let t=d.join(e,`package`);return d.join(t,`node_modules`,`.bin`,process.platform===`win32`?`agent-browser.cmd`:`agent-browser`)}function Q(e){return new t(`TOOL_MISSING`,`Managed web browser backend is not installed.`,{version:I,installDir:e.installDir,hint:e.nodeSupported===!1?`Web automation requires Node 24+; current Node is ${process.version}.`:"Run `agent-device web setup` to install the managed web backend."})}function te(e){if(!(e>=24))throw new t(`UNSUPPORTED_OPERATION`,`Web automation requires Node 24 or newer.`,{currentNode:process.version,requiredNodeMajor:24,hint:`Run agent-device with Node 24+ for web setup and web automation.`})}function ne(e){if(process.platform===`win32`)return d.join(e,`home`);let t=f.createHash(`sha1`).update(e).digest(`hex`).slice(0,12);return d.join(m.tmpdir(),`agent-device-web`,t)}function re(e){let t=f.createHash(`sha1`).update(e).digest(`hex`).slice(0,12);return d.join(m.tmpdir(),`adw`,t)}function ie(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function ae(e){try{return p.accessSync(e,p.constants.X_OK),!0}catch{return!1}}function oe(){return d.join(process.env.HOME??process.cwd(),`.agent-device`)}function $(e){let r=n(e);return r.code===`TOOL_MISSING`?new t(r.code,r.message,{...r.details??{},hint:typeof r.details?.hint==`string`?r.details.hint:"Run `agent-device web setup` to install the managed web backend."}):r}export{S as a,B as i,U as n,C as o,$ as r,x as s,F as t};
@@ -1,3 +1,3 @@
1
- import{o as e}from"./png-worker-contract.js";import{S as t,T as n,_ as r,a as i,w as a}from"./sdk-contracts.js";import{Ct as o,n as s,t as c,vt as l}from"./version.js";import{$n as u,Jn as d,Qn as f,Un as p,Wn as m,Xn as ee,Yn as h,Zn as te,qn as ne,tr as re,w as ie}from"./sdk-batch-runner.js";import{f as ae,o as oe,p as se,s as ce}from"./sdk-device.js";import{Dn as le,Sn as ue,Xt as g,Yt as _,an as v,i as de,in as fe,kn as pe,xn as me}from"./prepare-kind.js";import{S as he,_ as y,a as ge,d as b,f as _e,ft as x,gt as S,ht as ve,i as ye,l as be,lt as xe,m as Se,mt as Ce,n as we,nt as Te,st as Ee,u as De,v as Oe,vt as ke,y as Ae}from"./screenshot-result.js";import{b as je,c as Me,i as Ne,p as Pe,y as Fe}from"./registry.js";import{t as C}from"./command-metadata.js";import{A as w,F as Ie,S as Le,_ as Re,b as ze,k as Be}from"./sdk-android-adb.js";import{n as Ve,t as He}from"./shell-quote.js";import{t as T}from"./timeouts.js";import{n as Ue,t as We}from"./client-metro.js";import E from"node:path";import{createHash as Ge,randomUUID as Ke}from"node:crypto";import D from"node:fs";import qe from"node:os";import{pipeline as O}from"node:stream/promises";import{Transform as Je,Writable as Ye}from"node:stream";import k from"node:net";function Xe(e,t){let n=h(e,`bundleId`),r=h(e,`package`);return{app:u(e,`app`),appPath:u(e,`appPath`),platform:f(e,`platform`),appId:n??r,bundleId:n,package:r,identifiers:fe({session:t,bundleId:n,packageName:r})}}function Ze(e,t){let n=h(e,`bundleId`),i=h(e,`packageName`),a=n??i??h(e,`appId`),o=h(e,`launchTarget`)??i??n??a;if(!o)throw new r(`COMMAND_FAILED`,`Daemon response is missing "launchTarget".`,{response:e});return{appName:h(e,`appName`),appId:a,bundleId:n,packageName:i,launchTarget:o,installablePath:h(e,`installablePath`),archivePath:h(e,`archivePath`),materializationId:h(e,`materializationId`),materializationExpiresAt:h(e,`materializationExpiresAt`),identifiers:fe({session:t,bundleId:n,packageName:i,appId:a})}}function Qe(e){return{released:e.released===!0,materializationId:u(e,`materializationId`),identifiers:{}}}function $e(e){let{record:t,platform:n,id:r,name:i,target:a}=nt(e,`name`),o=tt(t);return{platform:n,target:a,kind:ee(t,`kind`),id:r,name:i,booted:typeof t.booted==`boolean`?t.booted:void 0,...ce(n)&&o?{appleOs:o}:{},identifiers:v(n,r,i),...A(n,r)}}function et(e){let{record:t,platform:n,id:r,name:i,target:a}=nt(e,`name`),o=u(t,`device`),s=tt(t),c={session:i,...v(n,r,o)};return{name:i,createdAt:te(t,`createdAt`),sessionStateDir:h(t,`sessionStateDir`),runnerLogPath:h(t,`runnerLogPath`),device:{platform:n,target:a,id:r,name:o,...s?{appleOs:s}:{},identifiers:c,...A(n,r,{simulatorSetPath:d(t,`ios_simulator_device_set`)})},identifiers:c}}function tt(e){let t=e.appleOs;return oe(t)?t:void 0}function nt(e,t){let n=p(e);return{record:n,platform:f(n,`platform`),id:u(n,`id`),name:u(n,t),target:ne(n,`target`)}}function A(e,t,n={}){if(e===`ios`)return{ios:{udid:t,...n.simulatorSetPath===void 0?{}:{simulatorSetPath:n.simulatorSetPath}}};if(!se(e))return{};let r=n.serial??t;return e===`android`?{android:{serial:r}}:e===`harmonyos`?{harmonyos:{serial:r}}:{vega:{serial:r}}}function rt(e){if(!m(e))return;let t=e.platform,n=h(e,`metroHost`),r=typeof e.metroPort==`number`?e.metroPort:void 0,i=h(e,`bundleUrl`),a=h(e,`launchUrl`);return{platform:t===`ios`||t===`android`?t:void 0,metroHost:n,metroPort:r,bundleUrl:i,launchUrl:a}}function it(e){let t=e.platform,n=h(e,`id`),r=h(e,`device`);if(!ae(t)||!n||!r)return;let i=ne(e,`target`),a=se(t)?h(e,`serial`)??n:void 0;return{platform:t,target:i,id:n,name:r,identifiers:{...v(t,n,r),...a?{serial:a}:{}},...A(t,t===`ios`?h(e,`device_udid`)??n:n,{simulatorSetPath:d(e,`ios_simulator_device_set`),serial:a})}}function at(e){if(m(e)&&!(typeof e.durationMs!=`number`||typeof e.measuredAt!=`string`||typeof e.method!=`string`))return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:h(e,`appTarget`),appBundleId:h(e,`appBundleId`)}}function ot(e){if(!m(e)||typeof e.success!=`boolean`||typeof e.exitCode!=`number`||typeof e.stdout!=`string`||typeof e.stderr!=`string`)return;let t=ct(e.error);return{success:e.success,exitCode:e.exitCode,stdout:e.stdout,stderr:e.stderr,...t?{error:t}:{}}}const st=[`hint`,`diagnosticId`,`logPath`,`supportedOn`];function ct(e){if(!m(e)||typeof e.code!=`string`||typeof e.message!=`string`)return;let t={code:e.code,message:e.message};for(let n of st){let r=e[n];typeof r==`string`&&(t[n]=r)}return m(e.details)&&(t.details=e.details),typeof e.retriable==`boolean`&&(t.retriable=e.retriable),t}function lt(e){let t=ct(e.initialSnapshotError);return{...e.snapshot&&typeof e.snapshot==`object`?{snapshot:e.snapshot}:{},...t?{initialSnapshotError:t}:{}}}function ut(e){return Array.isArray(e)?e:[]}function dt(e){let t=me(e);return re({requestId:e.requestId,cwd:e.cwd,sessionExplicit:e.session!==void 0,debug:e.debug,includeCost:e.cost,responseLevel:e.responseLevel,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,...pe(t),sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function j(e){return e??`default`}const ft={...Ne(),batch:Pe(pt)};function pt(e,t,n){let i=ft[e];if(!i)throw Error(`Missing daemon writer for batch command: ${e}`);let a=C(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return ht(i,a,a.readInput(t))}catch(t){throw new r(`INVALID_ARGS`,`Batch step ${n} ${e} input is invalid: ${t instanceof Error?t.message:String(t)}`,void 0,t)}}function mt(e,t){let n=ft[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return ht(n,C(e),t)}function ht(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:je(t,r.options)}:{}}}async function gt(e,t){let n=D.statSync(e),r=E.basename(e),i=n.isDirectory(),a=yt(t)??vt(e,n),o=[];try{let t=i?await _t(e,o):e,n=D.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await xt(t),sizeBytes:n.size,cleanup:()=>bt(o)}}catch(e){throw bt(o),e}}async function _t(e,t){let n=D.mkdtempSync(E.join(qe.tmpdir(),`agent-device-upload-${Ke()}-`));t.push(n);let r=E.join(n,`${E.basename(e)}.tar.gz`);return await Re(`tar`,[`czf`,r,`-C`,E.dirname(e),E.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function vt(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function yt(e){return e===`ios`||e===`android`?e:void 0}function bt(e){for(let t of e)D.rmSync(t,{recursive:!0,force:!0})}async function xt(e){let t=Ge(`sha256`),n=new Ye({write(e,n,r){t.update(e),r()}});return await O(D.createReadStream(e),n).catch(e=>{throw new r(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),t.digest(`hex`)}function St(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=Tt(i),c=Math.min(i,r+s);return new Je({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function Ct(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${wt(e)}\n`)}}function wt(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${M(e.totalBytes)}) via ${Et(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${M(e.transferredBytes)} of ${M(e.totalBytes)}`;case`progress`:return`Uploaded ${M(e.transferredBytes)} of ${M(e.totalBytes)} (${Dt(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${Et(e.to)} upload`}}function Tt(e){return Math.max(8388608,Math.ceil(e*.05))}function Et(e){return e===`direct`?`direct`:`legacy`}function Dt(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function M(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const Ot=300*1e3,kt=`uploadStreamRetryable`;async function At(e){return await N({...e,url:e.url,redirectCount:0,startOffset:0})}function jt(e){return e instanceof r&&e.details?.[kt]===!0}async function N(e){let t=await S(e.url.protocol),n=D.statSync(e.payloadPath).size,i=Pt(e.headers,e.startOffset,n);return Nt(e.progress,e.startOffset,n),await new Promise((a,o)=>{let s=!1,c=t.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:i},t=>{s=!0,ke(t).then(i=>{clearTimeout(l);let s=t.statusCode??500,c=t.headers.location;if(c&&Ft(s)){if(e.redirectCount>=5){o(new r(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let t=new URL(c,e.url);N({...e,url:t,redirectCount:e.redirectCount+1}).then(a,o);return}let u=It(s)?Lt(t.headers,n):void 0;if(u!==void 0){if(u>=n){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new r(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}N({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:t.statusMessage,body:i})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new r(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:Ot,...e.timeoutHint?{hint:e.timeoutHint}:{},...Mt(e)}))},Ot);c.on(`error`,t=>{s||(clearTimeout(l),o(new r(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...Mt(e)},t)))}),c.on(`close`,()=>clearTimeout(l)),O(D.createReadStream(e.payloadPath,{start:e.startOffset}),St({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??E.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:n,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new r(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function Mt(e){return e.retryable===!0?{[kt]:!0}:{}}function Nt(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function Pt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Ft(e){return[301,302,303,307,308].includes(e)}function It(e){return e===308}function Lt(e,t){let n=Rt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=zt(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function Rt(e){let t=zt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function zt(e){return Array.isArray(e)?e[0]:e}const Bt=30*1e3;async function Vt(e){let t=await gt(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=Ke();try{let i=await Gt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Ht({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await Wt({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Wt({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function Ht(e){let t=async t=>(await Jt(e.artifact,t,e.onProgress),await Yt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Ut(n))return;let r=await Gt({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId});if(r?.kind===`cache-hit`)return r.uploadId;if(r?.kind===`direct-upload`)try{return await t(r)}catch{return}return}}function Ut(e){return e instanceof r?jt(e):!0}async function Wt(e){let{normalizedBase:t,token:n,artifact:i}=e,a=new URL(`upload`,t),o={"content-type":i.contentType,"x-artifact-type":i.artifactType,"x-artifact-filename":i.fileName,"x-artifact-hash":i.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,x(n));let s=await At({url:a,method:`POST`,headers:o,payloadPath:i.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,progress:{stage:`legacy`,fileName:i.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new r(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof r?e:new r(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Gt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,x(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(Bt),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return Kt(await r.json().catch(()=>void 0))}function Kt(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(qt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function qt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function Jt(e,t,n){let i=await At({url:new URL(t.url),method:`PUT`,headers:t.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,progress:{stage:`direct`,fileName:e.fileName,onProgress:n}});if(i.statusCode<200||i.statusCode>=300)throw new r(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:i.statusCode,statusMessage:i.statusMessage})}async function Yt(e){let t=new URL(`upload/finalize`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,x(e.token));let i=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(Bt),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new r(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!i.ok)throw new r(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:i.status,statusText:i.statusText});let a=await i.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new r(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Xt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=Ct();if(!pn(t))return tn({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Qt(e,n,r,a);let c=await nn(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Zt(e,t,n,s)??o),tn({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Zt(e,t,n,r){let i=n.length===1?0:1,a=n[i];if(a===void 0)return;if(a.startsWith(`remote:`)){n[i]=a.slice(7);return}let o=en(a,e.meta?.cwd);if(o)return await Vt({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Qt(e,t,n,r){let i=rn(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=$t(n,i.flagPath);return r[i.field]=i.localPath,a}function $t(e,t){return t===void 0?e:{...e??{},out:t}}function en(e,t){let n=E.isAbsolute(e)?e:E.resolve(t??process.cwd(),e);return D.existsSync(n)?n:void 0}function tn(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function nn(e,t,n){let r=e.meta?.installSource;if(e.command!==`install_source`||!r||r.kind!==`path`)return null;let i=r.path.trim();if(!i)return{installSource:r};if(i.startsWith(`remote:`))return{installSource:{...r,path:i.slice(7)}};let a=E.isAbsolute(i)?i:E.resolve(e.meta?.cwd??process.cwd(),i);if(!D.existsSync(a))return{installSource:{...r,path:a}};let o=await Vt({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function rn(e,t){if(e.command===`screenshot`){let n=cn(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:F(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:F(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!on(e)&&e.flags?.platform===void 0)return null;let t=an(e),n=sn(cn(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:F(`recording`,E.extname(n)||t)}}return null}function an(e){return xe(e.flags?.platform)}function on(e){return P(e.positionals?.[1])||P(e.flags?.out)}function sn(e,t){return t.flags?.platform===`web`?Ee(e,an(t)):e}function cn(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=P(i)?i:a;return E.isAbsolute(o)?o:E.resolve(e.meta?.cwd??process.cwd(),o)}function P(e){return typeof e==`string`&&e.trim().length>0}function F(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return E.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function ln(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=un(n,t);await dn({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function un(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return E.resolve(t.meta?.cwd??process.cwd(),r)}async function dn(e){let t=new URL(fn(e.baseUrl,e.artifactId)),n=await S(t.protocol);await D.promises.mkdir(E.dirname(e.destinationPath),{recursive:!0}),await new Promise((i,a)=>{let o=!1,s=e.timeoutMs??9e4,c=t=>{if(!o){if(o=!0,clearTimeout(u),t){D.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}i()}},l=n.request({protocol:t.protocol,host:t.hostname,port:t.port,method:`GET`,path:t.pathname+t.search,headers:{...x(e.token),...Ce(e.requestScope?.tenantId)}},t=>{if((t.statusCode??500)>=400){let n=``;t.setEncoding(`utf8`),t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{c(new r(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestScope?.requestId,body:n}))});return}t.on(`aborted`,()=>{c(new r(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId}))}),O(t,D.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let t=new r(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s});c(t),l.destroy(t)},s);l.on(`error`,t=>{if(t instanceof r){c(t);return}c(new r(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s},t instanceof Error?t:void 0))}),l.end()})}function fn(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function pn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const mn=3e3,hn=1e3;function I(e){let t=wn(e);if(!t||typeof t!=`object`)return null;let n=t,r=gn(n);if(!r)return null;let i=_n(n);return i?{token:r,...i,transport:vn(n.transport),pid:R(n.pid)??0,version:L(n.version),codeSignature:L(n.codeSignature),processStartTime:L(n.processStartTime)}:null}function gn(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function _n(e){let t=R(e.port),n=R(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function vn(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function L(e){return typeof e==`string`?e:void 0}function R(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function z(e){let t=wn(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function B(e){Tn(e)}function V(e){Tn(e)}function yn(e){let t=U(e);if(!t.hasLock||t.hasInfo)return;let n=z(e.lockPath);if(!n){V(e.lockPath);return}b(n.pid,n.processStartTime)||V(e.lockPath)}async function H(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=D.existsSync(e.infoPath),n=I(e.infoPath);if(n){let t=b(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await W(n),i.stoppedInfoProcess=!0),B(e.infoPath),i.removedInfo=!0)}else t&&(B(e.infoPath),i.removedInfo=!0);let a=D.existsSync(e.lockPath),o=z(e.lockPath);if(o){let t=b(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await _e(o.pid,{termTimeoutMs:mn,killTimeoutMs:hn,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),V(e.lockPath),i.removedLock=!0)}else a&&(V(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return w({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function U(e){return{hasInfo:D.existsSync(e.infoPath),hasLock:D.existsSync(e.lockPath)}}async function bn(e){let t=U(e);if(!t.hasLock||t.hasInfo)return!1;let n=z(e.lockPath);return!n||!b(n.pid,n.processStartTime)?(V(e.lockPath),!0):!1}async function W(e){await _e(e.pid,{termTimeoutMs:mn,killTimeoutMs:hn,expectedStartTime:e.processStartTime})}function xn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function Sn(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){let n=Cn(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function Cn(e){return`rm -f ${He(e.infoPath)} ${He(e.lockPath)}`}function wn(e){if(!D.existsSync(e))return null;try{return JSON.parse(D.readFileSync(e,`utf8`))}catch{return null}}function Tn(e){try{D.existsSync(e)&&D.unlinkSync(e)}catch{}}function En(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&de(),process.stderr.write(`${e.message}\n`))}function G(e,t,n){return new r(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:t},n instanceof Error?n:void 0)}function Dn(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(G(e.req,n,r))}if(ye(r))try{return En(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return ge(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(G(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function On(e,t){return be(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function kn(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=Dn({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=De(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function An(e,t){let{req:n,handleResponseBody:i,reject:a,clearTimeout:o}=t,s=``,c=!1,l=Dn({req:n,onProgress:t.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),i(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=De(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(G(n,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new r(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0)))})}function jn(e,t){let{info:n,req:i,resolve:a,reject:o}=t;try{let t=Mn(e);if(t.error){o(Nn(t.error,i.meta?.requestId));return}if(!t.result||typeof t.result!=`object`){o(new r(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:i.meta?.requestId}));return}Pn(n,i,t.result,a,o)}catch(t){o(new r(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:i.meta?.requestId,line:e},t instanceof Error?t:void 0))}}function Mn(e){return JSON.parse(e)}function Nn(e,t){let i=e.data??{};return new r(n(i.code==null?void 0:String(i.code),`COMMAND_FAILED`),String(i.message??e.message??`Daemon RPC request failed`),{...typeof i.details==`object`&&i.details?i.details:{},hint:typeof i.hint==`string`?i.hint:void 0,diagnosticId:typeof i.diagnosticId==`string`?i.diagnosticId:void 0,logPath:typeof i.logPath==`string`?i.logPath:void 0,retriable:typeof i.retriable==`boolean`?i.retriable:void 0,supportedOn:typeof i.supportedOn==`string`?i.supportedOn:void 0,requestId:t})}async function Pn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await ln(e,t,n):n)}catch(e){i(e)}}function Fn(e,t){let n=e.meta?.requestId??Be();return In(e.command)?{jsonrpc:`2.0`,id:n,method:Ln(e.command),params:Rn(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function In(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function Ln(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function Rn(e,t,n){return le(ue(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const zn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`];function Bn(e){let t=ie(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Vn(n,e.positionals??[])??Hn(n,e.flags)??n.envelopeMs}function Vn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:Wn(e,n)}function Hn(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Un(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Un(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Gn(e,r):e.envelopeMs}function Wn(e,t){return Math.max(e.envelopeMs,t+Zn)}function Gn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Zn)}function Kn(e,t,n,i,a,o){let s=a?{terminated:0}:Yn(),c=!a&&qn(i),l=c?Xn(e,t):{forcedKill:!1};return w({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:n,command:i,timedOutRunnerPidsTerminated:s.terminated,timedOutRunnerCleanupError:s.error,daemonPidReset:c?e.pid:void 0,daemonPidForceKilled:c?l.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!c,daemonBaseUrl:e.baseUrl}}),new r(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:n,hint:Jn({remote:a,resetDaemon:c,command:i})})}function qn(e){return ie(e).onTimeout===`reset-daemon`}function Jn(e){let{remote:t,resetDaemon:n,command:r}=e;if(t)return`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=r===g.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled and Apple runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.${e}`}return`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`}function Yn(){let e=0;try{for(let t of zn)Le(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function Xn(e,t){let n=!1;try{b(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{W(e)}finally{B(t.infoPath),V(t.lockPath)}return{forcedKill:n}}const Zn=3e4,Qn=`Daemon HTTP endpoint is unavailable`,$n=`Daemon socket endpoint is unavailable`;async function er(e,t){let n=lr(e,t);if(await tr(e,n))return!0;let r=ur(e,t,n);return r?await tr(e,r):!1}async function tr(e,t){return t===`http`?await rr(e):await nr(e.port)}function nr(e){return e?new Promise(t=>{let n=!1,r=k.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function rr(e){return ar(e).then(e=>e.reachable)}async function ir(e){let t=await ar(e);if(!e.baseUrl||!t.reachable)return t;if(typeof t.rpcProtocolVersion==`number`&&t.rpcProtocolVersion!==2)throw new r(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:s(),remoteVersion:t.version,remoteService:t.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:t.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return t}async function ar(e){let t=e.baseUrl?ve(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!t)return{reachable:!1};let n=new URL(t),r=await S(n.protocol),i=e.baseUrl?3e3:500;return await new Promise(t=>{let a=e.baseUrl?x(e.token):{},o=r.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:`GET`,timeout:i,headers:a},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...or(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function or(e){try{let t=JSON.parse(e);return{service:typeof t.service==`string`?t.service:void 0,version:typeof t.version==`string`?t.version:void 0,rpcProtocolVersion:typeof t.rpcProtocolVersion==`number`?t.rpcProtocolVersion:void 0}}catch{return{}}}async function sr(e,t,n,r,i,a={}){let o=lr(e,n);try{return await cr(e,t,r,i,o,a)}catch(s){let c=ur(e,n,o);if(!c||!dr(s,o))throw s;return await cr(e,t,r,i,c,a)}}async function cr(e,t,n,r,i,a){return i===`http`?await hr(e,t,n,r,a):await mr(e,t,n,r,a)}function lr(e,t){if(e.baseUrl){if(t===`socket`)throw new r(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(t===`http`||t===`socket`)return fr(e,t);let n=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>K(e,t));if(n)return n;throw new r(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function K(e,t){return t===`http`?!!e.httpPort:!!e.port}function ur(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return K(e,r)?r:null}function dr(e,t){return t===`socket`&&e instanceof r&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function fr(e,t){if(K(e,t))return t;throw new r(`COMMAND_FAILED`,t===`http`?Qn:$n)}function pr(e,t,n,i={}){return w({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new r(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...i,requestId:t,hint:n?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function mr(e,t,n,i,a){let o=e.port;if(!o)throw new r(`COMMAND_FAILED`,$n);return new Promise((r,s)=>{let c=!1,l=k.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(t)}\n`)}),u=!1,d=typeof i==`number`?setTimeout(()=>{u=!0,l.destroy(),s(Kn(e,n,t.meta?.requestId,t.command,!1,i))},i):void 0;kn(l,{req:t,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,r(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(pr(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function hr(e,t,n,i,a){let o=e.baseUrl?new URL(ve(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new r(`COMMAND_FAILED`,Qn);let s=JSON.stringify(Fn(t,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};e.baseUrl&&Object.assign(c,x(e.token));let l=await S(o.protocol);return await new Promise((u,d)=>{let f=l.request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},n=>{if(On(t,n.headers?.[`content-type`])){An(n,{req:t,onProgress:a.onProgress,reject:d,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:n=>jn(n,{info:e,req:t,resolve:u,reject:d})});return}ke(n).then(n=>{m&&clearTimeout(m),jn(n,{info:e,req:t,resolve:u,reject:d})}).catch(e=>{m&&clearTimeout(m),d(new r(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:t.meta?.requestId},e instanceof Error?e:void 0))})}),p=xn(e),m=typeof i==`number`?setTimeout(()=>{f.destroy(),d(Kn(e,n,t.meta?.requestId,t.command,p,i))},i):void 0;f.on(`error`,e=>{m&&clearTimeout(m),d(pr(e,t.meta?.requestId,p))}),f.write(s),f.end()})}const q=15e3,J=new k.BlockList;J.addSubnet(`127.0.0.0`,8,`ipv4`),J.addAddress(`::1`,`ipv6`),J.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function gr(e,t){let n=_r(e),r=vr(e,t),i=yr(e,r.remoteBaseUrl),a=br(e,n,r.rawBaseUrl);return{paths:y(a?xr():n),transportPreference:i.preference,serverMode:i.serverMode,ownedStateDir:a,remoteBaseUrl:r.remoteBaseUrl,remoteAuthToken:r.authToken}}function _r(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function vr(e,t){let n=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,r=Wr(n),i=t??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Gr(r,i),{rawBaseUrl:n,remoteBaseUrl:r,authToken:i}}function yr(e,t){let n=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,i=Ae(n);if(t&&i===`socket`)throw new r(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:t});return{preference:i,serverMode:Oe(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(n===`dual`?`dual`:void 0))}}function br(e,t,n){return Fr(e.command)&&!t&&!n}function xr(){return D.mkdtempSync(E.join(qe.tmpdir(),`agent-device-replay-daemon-`))}async function Sr(e){if(e.remoteBaseUrl)return await Cr(e);let t=await wr(e);return t?{info:t,startedByClient:!1}:(yn(e.paths),await Ar(e))}async function Cr(e){let t={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await ir(t)).reachable)return{info:t,startedByClient:!1};throw new r(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function wr(e){let t=I(e.paths.infoPath);if(!t)return null;let n=await Tr(t,e.transportPreference);return Dr(t,n)?t:(Or(t,n,e.paths.baseDir),await W(t),B(e.paths.infoPath),null)}async function Tr(e,t){try{return await er(e,t)}catch(e){if(Er(e))return!1;throw e}}function Er(e){return e instanceof r&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function Dr(e,t){return e.version===s()&&e.codeSignature===Vr()&&t}function Or(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=kr(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function kr(e,t){return e.version===s()?e.codeSignature===Vr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${s()})`}async function Ar(e){let t=0,n=[],i,a;for(let r=1;r<=2;r+=1){let o;try{o=zr(e),a={pid:o.pid}}catch(t){if(i=t instanceof Error?t.message:String(t),n.push(await H(e.paths,`start_error`)),r<2){await T(150);continue}break}let s=await Rr(q,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,i=Hr(s.exit),n.push(await H(e.paths,`start_error`)),r<2){await T(150);continue}break}if(await bn(e.paths)){t+=1;continue}let c=U(e.paths),l=r<2,u=await H(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(n.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await Rr(q,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,i=Hr(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await T(150)}let o=U(e.paths),s=Ur(e.paths.logPath);throw new r(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:e.paths.baseDir,infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,logPath:e.paths.logPath,startupTimeoutMs:q,startupAttempts:2,lockRecoveryCount:t,cleanupResults:n,startError:i,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:Sn(o,e.paths)})}async function jr(e,t,n,r){if(!Fr(e.command)||!t.startedByClient&&!n.ownedStateDir||xn(t.info)||Nr(r)||Ir(e,r))return r;let i={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0},a=r;try{await W(t.info)}catch(e){i.error=e instanceof Error?e.message:String(e)}finally{let e=D.existsSync(n.paths.infoPath);B(n.paths.infoPath),i.removedInfo=e&&!D.existsSync(n.paths.infoPath);let t=D.existsSync(n.paths.lockPath);if(V(n.paths.lockPath),i.removedLock=t&&!D.existsSync(n.paths.lockPath),n.ownedStateDir){let e=he(n.paths.sessionsDir);e?a=Mr(r,e):(D.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),i.removedStateDir=!D.existsSync(n.paths.baseDir))}}return w({level:i.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:i}),a}function Mr(e,n){if(e&&!e.ok)return e;let{sessionName:i,tombstone:a}=n,o=a.sourcePath?`re-run: replay ${a.sourcePath} --save-script`:`re-run your replay <script> --save-script from the start`;return{ok:!1,error:t(new r(`REPAIR_COMMIT_FAILED`,`The repair transaction for session "${i}" completed, but committing its healed script failed at teardown: ${a.commitFailure.message}. ${o}.`))}}function Nr(e){if(!e||e.ok||e.error.code!==`REPLAY_DIVERGENCE`)return!1;let t=e.error.details?.divergence;if(!t||typeof t!=`object`)return!1;let n=t.resume;return!n||typeof n!=`object`?!1:n.repairSessionHeld===!0}function Pr(e,t){let n=`This repair session's daemon was kept alive to continue the repair; pass --state-dir ${t} on your next command (press, replay --from, or close --save-script) to reach it.`,r=e.error.hint;return{...e,error:{...e.error,hint:r?`${r} ${n}`:n}}}function Fr(e){return e===g.replay||e===g.test}function Ir(e,t){return e.command!==g.replay||!t||!t.ok?!1:t.data?.sessionActive===!0}function Lr(e,t){let n=e.data??{},r=typeof n.session==`string`?n.session:void 0,i=[...t?[`--state-dir ${Ve(t)}`]:[],...r?[`--session ${Ve(r)}`]:[]];if(i.length===0)return e;let a=`This session's daemon was kept alive because its script left the session active; pass ${i.join(` `)} on your next command to reach it.`,o=typeof n.message==`string`?n.message:void 0;return{...e,data:{...n,hint:a,message:o?`${o} ${a}`:a}}}async function Rr(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){if(i)return{kind:`early_exit`,exit:i};let e=I(t.paths.infoPath);if(e&&await er(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await T(100)}return{kind:`timeout`}}function zr(e){let t=Br(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};D.mkdirSync(e.paths.baseDir,{recursive:!0});let i=D.openSync(e.paths.logPath,`a`),a=D.openSync(e.paths.logPath,`a`);try{return ze(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{D.closeSync(i),D.closeSync(a)}}function Br(){let e=c(),t=[E.join(e,`dist`,`src`,`internal`,`daemon.js`),E.join(e,`dist`,`src`,`daemon.js`)],n=t[0];if(n===void 0)throw new r(`COMMAND_FAILED`,`Daemon dist path list is empty`);let i=t.find(e=>D.existsSync(e))??n,a=E.join(e,`src`,`daemon.ts`),o=t.some(e=>D.existsSync(e)),s=D.existsSync(a);if(!o&&!s)throw new r(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:t,srcPath:a});return{root:e,distPath:i,distPaths:t,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function Vr(){let e=Br();return Se(e.useSrc?e.srcPath:e.distPath,e.root)}function Hr(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function Ur(e){try{if(!D.existsSync(e))return;let t=D.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=D.openSync(e,`r`);try{let e=Buffer.alloc(n);D.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{D.closeSync(r)}}catch{return}}function Wr(e){if(!e)return;let t;try{t=new URL(e)}catch(t){throw new r(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},t instanceof Error?t:void 0)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new r(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return t.toString().replace(/\/+$/,``)}function Gr(e,t){if(!e)return;let n=new URL(e).hostname;if(!Kr(n)&&!(typeof t==`string`&&t.trim().length>0))throw new r(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:e,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function Kr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:k.isIPv4(t)?J.check(t,`ipv4`):k.isIPv6(t)?J.check(t,`ipv6`):!1}async function qr(e,t={}){let n=e.meta?.requestId??Be(),r=!!(e.meta?.debug||e.flags?.verbose),i=e.flags,{daemonAuthToken:a,...o}=i??{},s=i?{...e,flags:o}:e,c=gr(s,t.authToken??a),l=Bn(s),u=await Ie(`daemon_startup`,async()=>await Sr(c),{requestId:n,session:e.session}),d=u.info,f=await Xt(s,d);ti(s.command);let p=Jr(s,f,d.token,n,r);return w({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:s.command,session:s.session}}),await Qr(s,u,c,async()=>ei($r(await Ie(`daemon_request`,async()=>await sr(d,p,c.transportPreference,c.paths,l,t.onProgress?{onProgress:t.onProgress}:void 0),{requestId:n,command:e.command}),c),s,c))}function Jr(e,t,n,r,i){return{...e,positionals:t.positionals,flags:t.flags,token:n,meta:Yr(e,t,r,i)}}function Yr(e,t,n,r){let i=e.meta??{};return{...i,requestId:n,debug:r,...Xr(i,e.flags),...Zr(t)}}function Xr(e,t){return{includeCost:e.includeCost,cwd:e.cwd,sessionExplicit:e.sessionExplicit,tenantId:e.tenantId??t?.tenant,runId:e.runId??t?.runId,leaseId:e.leaseId??t?.leaseId,sessionIsolation:e.sessionIsolation??t?.sessionIsolation,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform}}function Zr(e){return{...e.uploadedArtifactId?{uploadedArtifactId:e.uploadedArtifactId}:{},...e.clientArtifactPaths?{clientArtifactPaths:e.clientArtifactPaths}:{},...e.installSource?{installSource:e.installSource}:{}}}async function Qr(e,t,n,i){let a,o=!1,s;try{a=await i()}catch(e){o=!0,s=e}let c=await jr(e,t,n,a);if(o)throw s;if(!c)throw new r(`COMMAND_FAILED`,`Daemon request produced no response after cleanup`);return c}function $r(e,t){return e.ok||!t.ownedStateDir||!Nr(e)?e:Pr(e,t.paths.baseDir)}function ei(e,t,n){return!e.ok||!Ir(t,e)?e:Lr(e,n.ownedStateDir?n.paths.baseDir:void 0)}function ti(e){!ni(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===g.reinstall?`Reinstalling...
1
+ import{n as e}from"./rolldown-runtime.js";import{C as t,E as n,T as r,_ as i,a}from"./sdk-contracts.js";import{h as o,u as s}from"./location-coordinates.js";import{Br as c,Fr as l,Ir as u,Lr as d,Mr as f,Nr as p,Or as m,Pr as h,Rr as g,kr as _,x as ee}from"./sdk-batch-runner.js";import{f as te,o as ne,p as re,s as ie}from"./sdk-device.js";import{At as v,Kt as ae,Qt as oe,en as se,i as ce,kt as le,qt as ue}from"./prepare-kind.js";import{S as de,_ as y,a as fe,ct as b,d as x,dt as pe,f as me,ft as S,i as he,l as ge,m as _e,mt as ve,n as ye,nt as be,u as xe,ut as Se,v as Ce,y as we}from"./screenshot-result.js";import{n as C,t as w}from"./command-catalog.js";import{b as Te,c as Ee,i as De,p as Oe,y as ke}from"./registry.js";import{t as Ae}from"./command-metadata.js";import{A as T,F as je,S as Me,_ as Ne,b as Pe,k as Fe}from"./sdk-android-adb.js";import{r as Ie,t as Le}from"./output-path.js";import{n as E,t as Re}from"./version.js";import{n as ze,t as Be}from"./shell-quote.js";import{t as D}from"./timeouts.js";import{n as Ve,t as He}from"./client-metro.js";import O from"node:path";import{createHash as Ue,randomUUID as We}from"node:crypto";import k from"node:fs";import Ge from"node:os";import{pipeline as A}from"node:stream/promises";import{Transform as Ke,Writable as qe}from"node:stream";import j from"node:net";function Je(e,t){let n=h(e,`bundleId`),r=h(e,`package`);return{app:g(e,`app`),appPath:g(e,`appPath`),platform:d(e,`platform`),appId:n??r,bundleId:n,package:r,identifiers:le({session:t,bundleId:n,packageName:r})}}function Ye(e,t){let n=h(e,`bundleId`),r=h(e,`packageName`),a=n??r??h(e,`appId`),o=h(e,`launchTarget`)??r??n??a;if(!o)throw new i(`COMMAND_FAILED`,`Daemon response is missing "launchTarget".`,{response:e});return{appName:h(e,`appName`),appId:a,bundleId:n,packageName:r,launchTarget:o,installablePath:h(e,`installablePath`),archivePath:h(e,`archivePath`),materializationId:h(e,`materializationId`),materializationExpiresAt:h(e,`materializationExpiresAt`),identifiers:le({session:t,bundleId:n,packageName:r,appId:a})}}function Xe(e){return{released:e.released===!0,materializationId:g(e,`materializationId`),identifiers:{}}}function Ze(e){let{record:t,platform:n,id:r,name:i,target:a}=et(e,`name`),o=$e(t);return{platform:n,target:a,kind:l(t,`kind`),id:r,name:i,booted:typeof t.booted==`boolean`?t.booted:void 0,...ie(n)&&o?{appleOs:o}:{},identifiers:v(n,r,i),...M(n,r)}}function Qe(e){let{record:t,platform:n,id:r,name:i,target:a}=et(e,`name`),o=g(t,`device`),s=$e(t),c={session:i,...v(n,r,o)};return{name:i,createdAt:u(t,`createdAt`),sessionStateDir:h(t,`sessionStateDir`),runnerLogPath:h(t,`runnerLogPath`),device:{platform:n,target:a,id:r,name:o,...s?{appleOs:s}:{},identifiers:c,...M(n,r,{simulatorSetPath:p(t,`ios_simulator_device_set`)})},identifiers:c}}function $e(e){let t=e.appleOs;return ne(t)?t:void 0}function et(e,t){let n=m(e);return{record:n,platform:d(n,`platform`),id:g(n,`id`),name:g(n,t),target:f(n,`target`)}}function M(e,t,n={}){if(e===`ios`)return{ios:{udid:t,...n.simulatorSetPath===void 0?{}:{simulatorSetPath:n.simulatorSetPath}}};if(!re(e))return{};let r=n.serial??t;return e===`android`?{android:{serial:r}}:e===`harmonyos`?{harmonyos:{serial:r}}:{vega:{serial:r}}}function tt(e){if(!_(e))return;let t=e.platform,n=h(e,`metroHost`),r=typeof e.metroPort==`number`?e.metroPort:void 0,i=h(e,`bundleUrl`),a=h(e,`launchUrl`);return{platform:t===`ios`||t===`android`?t:void 0,metroHost:n,metroPort:r,bundleUrl:i,launchUrl:a}}function nt(e){let t=e.platform,n=h(e,`id`),r=h(e,`device`);if(!te(t)||!n||!r)return;let i=f(e,`target`),a=re(t)?h(e,`serial`)??n:void 0;return{platform:t,target:i,id:n,name:r,identifiers:{...v(t,n,r),...a?{serial:a}:{}},...M(t,t===`ios`?h(e,`device_udid`)??n:n,{simulatorSetPath:p(e,`ios_simulator_device_set`),serial:a})}}function rt(e){if(_(e)&&!(typeof e.durationMs!=`number`||typeof e.measuredAt!=`string`||typeof e.method!=`string`))return{durationMs:e.durationMs,measuredAt:e.measuredAt,method:e.method,appTarget:h(e,`appTarget`),appBundleId:h(e,`appBundleId`)}}function it(e){if(!_(e)||typeof e.success!=`boolean`||typeof e.exitCode!=`number`||typeof e.stdout!=`string`||typeof e.stderr!=`string`)return;let t=ot(e.error);return{success:e.success,exitCode:e.exitCode,stdout:e.stdout,stderr:e.stderr,...t?{error:t}:{}}}const at=[`hint`,`diagnosticId`,`logPath`,`supportedOn`];function ot(e){if(!_(e)||typeof e.code!=`string`||typeof e.message!=`string`)return;let t={code:e.code,message:e.message};for(let n of at){let r=e[n];typeof r==`string`&&(t[n]=r)}return _(e.details)&&(t.details=e.details),typeof e.retriable==`boolean`&&(t.retriable=e.retriable),t}function st(e){let t=ot(e.initialSnapshotError);return{...e.snapshot&&typeof e.snapshot==`object`?{snapshot:e.snapshot}:{},...t?{initialSnapshotError:t}:{}}}function ct(e){return Array.isArray(e)?e:[]}function lt(e){let t=ae(e);return c({requestId:e.requestId,cwd:e.cwd,sessionExplicit:e.session!==void 0,debug:e.debug,includeCost:e.cost,responseLevel:e.responseLevel,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform,...se(t),sessionIsolation:e.sessionIsolation,installSource:e.installSource,retainMaterializedPaths:e.retainMaterializedPaths,materializedPathRetentionMs:e.materializedPathRetentionMs,materializationId:e.materializationId})}function ut(e){return e??`default`}const dt={...De(),batch:Oe(ft)};function ft(e,t,n){let r=dt[e];if(!r)throw Error(`Missing daemon writer for batch command: ${e}`);let a=Ae(e);if(!a)throw Error(`Missing command metadata for batch command: ${e}`);try{return mt(r,a,a.readInput(t))}catch(t){throw new i(`INVALID_ARGS`,`Batch step ${n} ${e} input is invalid: ${t instanceof Error?t.message:String(t)}`,void 0,t)}}function pt(e,t){let n=dt[e];if(!n)throw Error(`Missing daemon writer for command: ${e}`);return mt(n,Ae(e),t)}function mt(e,t,n){let r=e(n);return{...r,...t?{metadataFlags:Te(t,r.options)}:{}}}async function ht(e,t){let n=k.statSync(e),r=O.basename(e),i=n.isDirectory(),a=vt(t)??_t(e,n),o=[];try{let t=i?await gt(e,o):e,n=k.statSync(t);return{payloadPath:t,fileName:r,artifactType:i?`app-bundle`:`file`,platform:a,contentType:i?`application/gzip`:`application/octet-stream`,sha256:await bt(t),sizeBytes:n.size,cleanup:()=>yt(o)}}catch(e){throw yt(o),e}}async function gt(e,t){let n=k.mkdtempSync(O.join(Ge.tmpdir(),`agent-device-upload-${We()}-`));t.push(n);let r=O.join(n,`${O.basename(e)}.tar.gz`);return await Ne(`tar`,[`czf`,r,`-C`,O.dirname(e),O.basename(e)],{env:{...process.env,COPYFILE_DISABLE:`1`}}),r}function _t(e,t){let n=e.toLowerCase();if(t.isDirectory()&&n.endsWith(`.app`)||n.endsWith(`.ipa`))return`ios`;if(n.endsWith(`.apk`)||n.endsWith(`.aab`))return`android`}function vt(e){return e===`ios`||e===`android`?e:void 0}function yt(e){for(let t of e)k.rmSync(t,{recursive:!0,force:!0})}async function bt(e){let t=Ue(`sha256`),n=new qe({write(e,n,r){t.update(e),r()}});return await A(k.createReadStream(e),n).catch(e=>{throw new i(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:void 0)}),t.digest(`hex`)}function xt(e){let{stage:t,fileName:n,startOffset:r,totalBytes:i,onProgress:a}=e,o=r,s=wt(i),c=Math.min(i,r+s);return new Ke({transform(e,r,l){o=Math.min(i,o+e.byteLength),o>=c&&(a?.({type:`progress`,stage:t,fileName:n,transferredBytes:o,totalBytes:i}),c=Math.min(i,o+s)),l(null,e)}})}function St(){if(!(process.stderr.isTTY!==!0||process.env.CI))return e=>{process.stderr.write(`${Ct(e)}\n`)}}function Ct(e){switch(e.type){case`start`:return`Uploading ${e.fileName} (${N(e.totalBytes)}) via ${Tt(e.stage)} upload`;case`resume`:return`Resuming ${e.fileName} at ${N(e.transferredBytes)} of ${N(e.totalBytes)}`;case`progress`:return`Uploaded ${N(e.transferredBytes)} of ${N(e.totalBytes)} (${Et(e.transferredBytes,e.totalBytes)})`;case`fallback`:return`Direct upload did not complete; retrying ${e.fileName} with ${Tt(e.to)} upload`}}function wt(e){return Math.max(8388608,Math.ceil(e*.05))}function Tt(e){return e===`direct`?`direct`:`legacy`}function Et(e,t){return t<=0?`100%`:`${Math.min(100,Math.floor(e/t*100))}%`}function N(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KiB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MiB`:`${(n/1024).toFixed(1)} GiB`}const Dt=300*1e3,Ot=`uploadStreamRetryable`;async function kt(e){return await P({...e,url:e.url,redirectCount:0,startOffset:0})}function At(e){return e instanceof i&&e.details?.[Ot]===!0}async function P(e){let t=await S(e.url.protocol),n=k.statSync(e.payloadPath).size,r=Nt(e.headers,e.startOffset,n);return Mt(e.progress,e.startOffset,n),await new Promise((a,o)=>{let s=!1,c=t.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:r},t=>{s=!0,ve(t).then(r=>{clearTimeout(l);let s=t.statusCode??500,c=t.headers.location;if(c&&Pt(s)){if(e.redirectCount>=5){o(new i(`COMMAND_FAILED`,`Artifact upload exceeded redirect limit`,{maxRedirects:5,url:e.url.toString()}));return}let t=new URL(c,e.url);P({...e,url:t,redirectCount:e.redirectCount+1}).then(a,o);return}let u=Ft(s)?It(t.headers,n):void 0;if(u!==void 0){if(u>=n){a({statusCode:200,statusMessage:`Upload already complete`,body:``});return}if(u<=e.startOffset){o(new i(`COMMAND_FAILED`,`Artifact upload resume did not advance`,{offset:u,previousOffset:e.startOffset,url:e.url.toString()}));return}P({...e,startOffset:u}).then(a,o);return}a({statusCode:s,statusMessage:t.statusMessage,body:r})}).catch(o)}),l=setTimeout(()=>{c.destroy(),o(new i(`COMMAND_FAILED`,e.timeoutMessage,{timeoutMs:Dt,...e.timeoutHint?{hint:e.timeoutHint}:{},...jt(e)}))},Dt);c.on(`error`,t=>{s||(clearTimeout(l),o(new i(`COMMAND_FAILED`,e.errorMessage,{...e.errorHint?{hint:e.errorHint}:{},...jt(e)},t)))}),c.on(`close`,()=>clearTimeout(l)),A(k.createReadStream(e.payloadPath,{start:e.startOffset}),xt({stage:e.progress?.stage??`legacy`,fileName:e.progress?.fileName??O.basename(e.payloadPath),startOffset:e.startOffset,totalBytes:n,onProgress:e.progress?.onProgress}),c).catch(e=>{s||(c.destroy(),o(new i(`COMMAND_FAILED`,`Failed to read local artifact`,{},e instanceof Error?e:Error(String(e)))))})})}function jt(e){return e.retryable===!0?{[Ot]:!0}:{}}function Mt(e,t,n){e?.onProgress?.({type:t>0?`resume`:`start`,stage:e.stage,fileName:e.fileName,transferredBytes:t,totalBytes:n})}function Nt(e,t,n){return t<=0?e:{...e,"content-length":Math.max(n-t,0),"content-range":`bytes ${t}-${n-1}/${n}`}}function Pt(e){return[301,302,303,307,308].includes(e)}function Ft(e){return e===308}function It(e,t){let n=Lt(e[`x-upload-offset`]??e[`upload-offset`]);if(n!==void 0)return Math.min(n,t);let r=Rt(e.range)?.match(/^bytes=0-(\d+)$/);if(!r)return;let i=Number(r[1]);if(!(!Number.isSafeInteger(i)||i<0))return Math.min(i+1,t)}function Lt(e){let t=Rt(e);if(t===void 0)return;let n=Number(t);return Number.isSafeInteger(n)&&n>=0?n:void 0}function Rt(e){return Array.isArray(e)?e[0]:e}const zt=30*1e3;async function Bt(e){let t=await ht(e.localPath,e.platform),n=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,r=We();try{let i=await Wt({normalizedBase:n,token:e.token,artifact:t,uploadAttemptId:r});return i?.kind===`cache-hit`?i.uploadId:i?.kind===`direct-upload`?await Vt({normalizedBase:n,token:e.token,artifact:t,preflight:i,uploadAttemptId:r,onProgress:e.onProgress})||(e.onProgress?.({type:`fallback`,from:`direct`,to:`legacy`,fileName:t.fileName}),await Ut({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})):await Ut({normalizedBase:n,token:e.token,artifact:t,onProgress:e.onProgress})}finally{t.cleanup()}}async function Vt(e){let t=async t=>(await qt(e.artifact,t,e.onProgress),await Jt({normalizedBase:e.normalizedBase,token:e.token,uploadId:t.uploadId}));try{return await t(e.preflight)}catch(n){if(!Ht(n))return;let r=await Wt({normalizedBase:e.normalizedBase,token:e.token,artifact:e.artifact,uploadAttemptId:e.uploadAttemptId});if(r?.kind===`cache-hit`)return r.uploadId;if(r?.kind===`direct-upload`)try{return await t(r)}catch{return}return}}function Ht(e){return e instanceof i?At(e):!0}async function Ut(e){let{normalizedBase:t,token:n,artifact:r}=e,a=new URL(`upload`,t),o={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":`sha256`,"transfer-encoding":`chunked`};Object.assign(o,b(n));let s=await kt({url:a,method:`POST`,headers:o,payloadPath:r.payloadPath,timeoutMessage:`Artifact upload timed out`,timeoutHint:`The upload to the remote daemon exceeded the 5-minute timeout.`,errorMessage:`Failed to upload artifact to remote daemon`,errorHint:`Verify the remote daemon is reachable and supports artifact uploads.`,progress:{stage:`legacy`,fileName:r.fileName,onProgress:e.onProgress}});try{let e=JSON.parse(s.body);if(!e.ok||!e.uploadId)throw new i(`COMMAND_FAILED`,`Upload failed: ${s.body}`);return e.uploadId}catch(e){throw e instanceof i?e:new i(`COMMAND_FAILED`,`Invalid upload response: ${s.body}`)}}async function Wt(e){let t=new URL(`upload/preflight`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,b(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(zt),body:JSON.stringify({uploadAttemptId:e.uploadAttemptId,sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return Gt(await r.json().catch(()=>void 0))}function Gt(e){if(!e||typeof e!=`object`)return;let t=e;if(t.ok!==!0||typeof t.uploadId!=`string`)return;if(t.cacheHit===!0)return{kind:`cache-hit`,uploadId:t.uploadId};let n=t.upload;if(!n||typeof n.url!=`string`)return;let r=n.headers??{};if(Kt(r))return{kind:`direct-upload`,uploadId:t.uploadId,url:n.url,headers:r}}function Kt(e){return!e||typeof e!=`object`||Array.isArray(e)?!1:Object.values(e).every(e=>typeof e==`string`)}async function qt(e,t,n){let r=await kt({url:new URL(t.url),method:`PUT`,headers:t.headers,payloadPath:e.payloadPath,timeoutMessage:`Direct artifact upload timed out`,timeoutHint:`The direct upload ticket did not accept the artifact within the timeout.`,errorMessage:`Failed to upload artifact with direct upload ticket`,retryable:!0,progress:{stage:`direct`,fileName:e.fileName,onProgress:n}});if(r.statusCode<200||r.statusCode>=300)throw new i(`COMMAND_FAILED`,`Direct artifact upload failed`,{statusCode:r.statusCode,statusMessage:r.statusMessage})}async function Jt(e){let t=new URL(`upload/finalize`,e.normalizedBase),n={"content-type":`application/json`};Object.assign(n,b(e.token));let r=await fetch(t,{method:`POST`,headers:n,signal:AbortSignal.timeout(zt),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new i(`COMMAND_FAILED`,`Failed to finalize direct artifact upload`,{},e)});if(!r.ok)throw new i(`COMMAND_FAILED`,`Direct artifact upload finalize failed`,{status:r.status,statusText:r.statusText});let a=await r.json().catch(()=>void 0);if(!a?.ok||!a.uploadId)throw new i(`COMMAND_FAILED`,`Invalid upload finalize response`);return a.uploadId}async function Yt(e,t){let n=[...e.positionals??[]],r=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,a={},o,s=St();if(!fn(t))return en({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a});r=Zt(e,n,r,a);let c=await tn(e,t,s);return c&&(i=c.installSource,o=c.uploadedArtifactId??o),e.command!==`install`&&e.command!==`reinstall`||(o=await Xt(e,t,n,s)??o),en({positionals:n,flags:r,installSource:i,uploadedArtifactId:o,clientArtifactPaths:a})}async function Xt(e,t,n,r){let i=n.length===1?0:1,a=n[i];if(a===void 0)return;if(a.startsWith(`remote:`)){n[i]=a.slice(7);return}let o=$t(a,e.meta?.cwd);if(o)return await Bt({localPath:o,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:r})}function Zt(e,t,n,r){let i=nn(e,t);if(!i)return n;i.positionalPath!==void 0&&(t[i.positionalIndex]=i.positionalPath);let a=Qt(n,i.flagPath);return r[i.field]=i.localPath,a}function Qt(e,t){return t===void 0?e:{...e??{},out:t}}function $t(e,t){let n=O.isAbsolute(e)?e:O.resolve(t??process.cwd(),e);return k.existsSync(n)?n:void 0}function en(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function tn(e,t,n){let r=e.meta?.installSource;if(e.command!==`install_source`||!r||r.kind!==`path`)return null;let i=r.path.trim();if(!i)return{installSource:r};if(i.startsWith(`remote:`))return{installSource:{...r,path:i.slice(7)}};let a=O.isAbsolute(i)?i:O.resolve(e.meta?.cwd??process.cwd(),i);if(!k.existsSync(a))return{installSource:{...r,path:a}};let o=await Bt({localPath:a,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform,onProgress:n});return{installSource:{...r,path:a},uploadedArtifactId:o}}function nn(e,t){if(e.command===`screenshot`){let n=sn(e,`path`,`.png`);return t[0]?{field:`path`,localPath:n,positionalIndex:0,positionalPath:I(`screenshot`,`.png`)}:{field:`path`,localPath:n,positionalIndex:0,flagPath:I(`screenshot`,`.png`)}}if(e.command===`record`&&(t[0]??``).toLowerCase()===`start`){if(!an(e)&&e.flags?.platform===void 0)return null;let t=rn(e),n=on(sn(e,`outPath`,t,1),e);return{field:`outPath`,localPath:n,positionalIndex:1,positionalPath:I(`recording`,O.extname(n)||t)}}return null}function rn(e){return Ie(e.flags?.platform)}function an(e){return F(e.positionals?.[1])||F(e.flags?.out)}function on(e,t){return t.flags?.platform===`web`?Le(e,rn(t)):e}function sn(e,t,n,r=0){let i=e.positionals?.[r]??e.flags?.out,a=`${t===`path`?`screenshot`:`recording`}-${Date.now()}${n}`,o=F(i)?i:a;return O.isAbsolute(o)?o:O.resolve(e.meta?.cwd??process.cwd(),o)}function F(e){return typeof e==`string`&&e.trim().length>0}function I(e,t){let n=t.startsWith(`.`)?t:`.${t}`;return O.posix.join(`/tmp`,`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${n}`)}async function cn(e,t,n){let r=Array.isArray(n.data?.artifacts)?n.data.artifacts:[];if(r.length===0||!e.baseUrl)return n;let i=n.data?{...n.data}:{},a=[];for(let n of r){if(!n||typeof n!=`object`||typeof n.artifactId!=`string`){a.push(n);continue}let r=ln(n,t);await un({baseUrl:e.baseUrl,token:e.token,artifactId:n.artifactId,destinationPath:r,requestScope:t.meta}),i[n.field]=r,a.push({...n,localPath:r})}return i.artifacts=a,{ok:!0,data:i}}function ln(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let n=t.meta?.clientArtifactPaths?.[e.field];if(n&&n.trim().length>0)return n;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return O.resolve(t.meta?.cwd??process.cwd(),r)}async function un(e){let t=new URL(dn(e.baseUrl,e.artifactId)),n=await S(t.protocol);await k.promises.mkdir(O.dirname(e.destinationPath),{recursive:!0}),await new Promise((r,a)=>{let o=!1,s=e.timeoutMs??9e4,c=t=>{if(!o){if(o=!0,clearTimeout(u),t){k.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(t));return}r()}},l=n.request({protocol:t.protocol,host:t.hostname,port:t.port,method:`GET`,path:t.pathname+t.search,headers:{...b(e.token),...Se(e.requestScope?.tenantId)}},t=>{if((t.statusCode??500)>=400){let n=``;t.setEncoding(`utf8`),t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{c(new i(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestScope?.requestId,body:n}))});return}t.on(`aborted`,()=>{c(new i(`COMMAND_FAILED`,`Remote artifact download was interrupted`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId}))}),A(t,k.createWriteStream(e.destinationPath)).then(()=>c(),e=>c(e instanceof Error?e:Error(String(e))))}),u=setTimeout(()=>{let t=new i(`COMMAND_FAILED`,`Remote artifact download timed out`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s});c(t),l.destroy(t)},s);l.on(`error`,t=>{if(t instanceof i){c(t);return}c(new i(`COMMAND_FAILED`,`Failed to download remote artifact`,{artifactId:e.artifactId,requestId:e.requestScope?.requestId,timeoutMs:s},t instanceof Error?t:void 0))}),l.end()})}function dn(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(`artifacts/${encodeURIComponent(t)}`,n).toString()}function fn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}const pn=3e3,mn=1e3;function L(e){let t=Cn(e);if(!t||typeof t!=`object`)return null;let n=t,r=hn(n);if(!r)return null;let i=gn(n);return i?{token:r,...i,transport:_n(n.transport),pid:z(n.pid)??0,version:R(n.version),codeSignature:R(n.codeSignature),processStartTime:R(n.processStartTime)}:null}function hn(e){return typeof e.token==`string`&&e.token.length>0?e.token:null}function gn(e){let t=z(e.port),n=z(e.httpPort);return t===void 0&&n===void 0?null:{port:t,httpPort:n}}function _n(e){return e===`socket`||e===`http`||e===`dual`?e:void 0}function R(e){return typeof e==`string`?e:void 0}function z(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function B(e){let t=Cn(e);if(!t||typeof t!=`object`)return null;let n=t;return Number.isInteger(n.pid)&&Number(n.pid)>0?{pid:Number(n.pid),processStartTime:typeof n.processStartTime==`string`?n.processStartTime:void 0,startedAt:typeof n.startedAt==`number`?n.startedAt:void 0}:null}function V(e){wn(e)}function H(e){wn(e)}function vn(e){let t=W(e);if(!t.hasLock||t.hasInfo)return;let n=B(e.lockPath);if(!n){H(e.lockPath);return}x(n.pid,n.processStartTime)||H(e.lockPath)}async function U(e,t,n={}){let r=n.stopLiveProcesses??!0,i={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{let t=k.existsSync(e.infoPath),n=L(e.infoPath);if(n){let t=x(n.pid,n.processStartTime);t&&!r?i.retainedInfoProcess=!0:(t&&(await G(n),i.stoppedInfoProcess=!0),V(e.infoPath),i.removedInfo=!0)}else t&&(V(e.infoPath),i.removedInfo=!0);let a=k.existsSync(e.lockPath),o=B(e.lockPath);if(o){let t=x(o.pid,o.processStartTime);t&&!r?i.retainedLockProcess=!0:(t&&(await me(o.pid,{termTimeoutMs:pn,killTimeoutMs:mn,expectedStartTime:o.processStartTime}),i.stoppedLockProcess=!0),H(e.lockPath),i.removedLock=!0)}else a&&(H(e.lockPath),i.removedLock=!0)}catch(e){i.error=e instanceof Error?e.message:String(e)}return T({level:i.error?`warn`:`info`,phase:`daemon_startup_metadata_cleanup`,data:i}),i}function W(e){return{hasInfo:k.existsSync(e.infoPath),hasLock:k.existsSync(e.lockPath)}}async function yn(e){let t=W(e);if(!t.hasLock||t.hasInfo)return!1;let n=B(e.lockPath);return!n||!x(n.pid,n.processStartTime)?(H(e.lockPath),!0):!1}async function G(e){await me(e.pid,{termTimeoutMs:pn,killTimeoutMs:mn,expectedStartTime:e.processStartTime})}function bn(e){return typeof e.baseUrl==`string`&&e.baseUrl.length>0}function xn(e,t=y(process.env.AGENT_DEVICE_STATE_DIR)){let n=Sn(t);return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists after confirming no agent-device daemon process is running, run: ${n}`:e.hasInfo?`agent-device did not observe reachable daemon metadata after retrying, and ${t.infoPath} still remains. Stale metadata was cleaned automatically when safe; retry with --debug. If this persists after confirming no agent-device daemon process is running, run: ${n}`:`agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs. If stale metadata returns after confirming no agent-device daemon process is running, run: ${n}`}function Sn(e){return`rm -f ${Be(e.infoPath)} ${Be(e.lockPath)}`}function Cn(e){if(!k.existsSync(e))return null;try{return JSON.parse(k.readFileSync(e,`utf8`))}catch{return null}}function wn(e){try{k.existsSync(e)&&k.unlinkSync(e)}catch{}}function Tn(e,t){if(t.onProgress){t.onProgress(e);return}e.type===`command`&&(t.req.command===`doctor`&&ce(),process.stderr.write(`${e.message}\n`))}function K(e,t,n){return new i(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:e.meta?.requestId,line:t},n instanceof Error?n:void 0)}function En(e){let t=t=>(e.onError(t),!0);return{handleLine(n){let r;try{r=JSON.parse(n)}catch(r){return t(K(e.req,n,r))}if(he(r))try{return Tn(r.event,{req:e.req,onProgress:e.onProgress}),!1}catch(e){return t(e)}return fe(r)?(e.onResponse(r.response),!0):e.responseFormat===`socket-legacy`?(e.onResponse(r),!0):t(K(e.req,n,Error(`Missing daemon progress response envelope`)))}}}function Dn(e,t){return ge(e)&&String(Array.isArray(t)?t.join(`,`):t??``).includes(`application/x-ndjson`)}function On(e,t){let{req:n,isSettled:r,resolve:i,reject:a,clearTimeout:o}=t,s=``,c=En({req:n,onProgress:t.onProgress,responseFormat:`socket-legacy`,onResponse(t){o(),i(t),e.end()},onError(e){o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(r())return;let t=xe(s,e);s=t.buffer;for(let e of t.lines)if(c.handleLine(e))return})}function kn(e,t){let{req:n,handleResponseBody:r,reject:a,clearTimeout:o}=t,s=``,c=!1,l=En({req:n,onProgress:t.onProgress,responseFormat:`ndjson-envelope`,onResponse(e){c=!0,o(),r(JSON.stringify(e))},onError(e){c=!0,o(),a(e)}});e.setEncoding(`utf8`),e.on(`data`,e=>{if(c)return;let t=xe(s,e);s=t.buffer;for(let e of t.lines)if(e&&l.handleLine(e))return}),e.on(`end`,()=>{if(c)return;let e=s.trim();e&&l.handleLine(e)||(c=!0,o(),a(K(n,e)))}),e.on(`error`,e=>{c||(c=!0,o(),a(new i(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:n.meta?.requestId},e instanceof Error?e:void 0)))})}function An(e,t){let{info:n,req:r,resolve:a,reject:o}=t;try{let t=jn(e);if(t.error){o(Mn(t.error,r.meta?.requestId));return}if(!t.result||typeof t.result!=`object`){o(new i(`COMMAND_FAILED`,`Invalid daemon RPC response`,{requestId:r.meta?.requestId}));return}Nn(n,r,t.result,a,o)}catch(t){o(new i(`COMMAND_FAILED`,`Invalid daemon response`,{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}function jn(e){return JSON.parse(e)}function Mn(e,t){let r=e.data??{};return new i(n(r.code==null?void 0:String(r.code),`COMMAND_FAILED`),String(r.message??e.message??`Daemon RPC request failed`),{...typeof r.details==`object`&&r.details?r.details:{},hint:typeof r.hint==`string`?r.hint:void 0,diagnosticId:typeof r.diagnosticId==`string`?r.diagnosticId:void 0,logPath:typeof r.logPath==`string`?r.logPath:void 0,retriable:typeof r.retriable==`boolean`?r.retriable:void 0,supportedOn:typeof r.supportedOn==`string`?r.supportedOn:void 0,requestId:t})}async function Nn(e,t,n,r,i){try{r(e.baseUrl&&n.ok?await cn(e,t,n):n)}catch(e){i(e)}}function Pn(e,t){let n=e.meta?.requestId??Fe();return Fn(e.command)?{jsonrpc:`2.0`,id:n,method:In(e.command),params:Ln(e,e.command,t)}:{jsonrpc:`2.0`,id:n,method:`agent_device.command`,params:e}}function Fn(e){return e===`lease_allocate`||e===`lease_heartbeat`||e===`lease_release`}function In(e){switch(e){case`lease_allocate`:return`agent_device.lease.allocate`;case`lease_heartbeat`:return`agent_device.lease.heartbeat`;case`lease_release`:return`agent_device.lease.release`}}function Ln(e,t,n){return oe(ue(e),t,{includeTokenParam:n.includeTokenParam,token:e.token,session:e.session})}const Rn=[`xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand`,`xcodebuild .*AgentDeviceRunner\\.env\\.session-`,`xcodebuild build-for-testing .*apple/runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj`],zn=new Set([`apple`,`ios`,`macos`]);function Bn(e){return e!==void 0&&zn.has(e)}function Vn(e){let t=ee(e.command);if(t.envelopeMs===`unbounded`)return;let n={...t,envelopeMs:t.envelopeMs};return Hn(n,e.positionals??[])??Un(n,e.flags)??n.envelopeMs}function Hn(e,t){if(e.budget.source!==`positional-parser`)return;let n=e.budget.parser(t);return n===null?void 0:Gn(e,n)}function Un(e,t){if(e.budget.source===`flag`)return e.budget.envelope===`widen`?Wn(e,e.budget,t):typeof t?.timeoutMs==`number`?t.timeoutMs:e.envelopeMs}function Wn(e,t,n){if(n?.settle!==!0)return e.envelopeMs;let r=typeof n.timeoutMs==`number`?n.timeoutMs:t.defaultBudgetMs;return typeof r==`number`?Kn(e,r):e.envelopeMs}function Gn(e,t){return Math.max(e.envelopeMs,t+Qn)}function Kn(e,t){return Math.max(e.envelopeMs,e.envelopeMs+t+Qn)}function qn(e,t,n,r,a,o,s){let c=a?{terminated:0}:Xn(),l=!a&&Jn(r),u=l?Zn(e,t):{forcedKill:!1},d=Bn(s)||c.terminated>0;return T({level:`error`,phase:`daemon_request_timeout`,data:{timeoutMs:o,requestId:n,command:r,timedOutRunnerPidsTerminated:c.terminated,timedOutRunnerCleanupError:c.error,daemonPidReset:l?e.pid:void 0,daemonPidForceKilled:l?u.forcedKill:void 0,daemonPreservedAfterTimeout:!a&&!l,daemonBaseUrl:e.baseUrl}}),new i(`COMMAND_FAILED`,`Daemon request timed out`,{timeoutMs:o,requestId:n,hint:Yn({remote:a,resetDaemon:l,command:r,appleCleanupEvidence:d})})}function Jn(e){return ee(e).onTimeout===`reset-daemon`}function Yn(e){let{remote:t,resetDaemon:n,command:r,appleCleanupEvidence:i}=e;if(t)return`Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.`;if(!n){let e=i&&r===C.snapshot?` If this was the first Apple-platform snapshot on the device, run agent-device prepare ios-runner with the same --platform before snapshot/test so runner startup is handled explicitly.`:``;return`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??`request`} request was canceled${i?` and Apple runner work was aborted when detected`:``}; the daemon was kept alive so the session can still be closed or inspected.${e}`}return i?`Retry with --debug and check daemon diagnostics logs. Timed-out Apple runner xcodebuild processes were terminated when detected.`:`Retry with --debug and check daemon diagnostics logs. The daemon was reset after the timeout.`}function Xn(){let e=0;try{for(let t of Rn)Me(`pkill`,[`-f`,t],{allowFailure:!0}).exitCode===0&&(e+=1);return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}function Zn(e,t){let n=!1;try{x(e.pid,e.processStartTime)&&(process.kill(e.pid,`SIGKILL`),n=!0)}catch{G(e)}finally{V(t.infoPath),H(t.lockPath)}return{forcedKill:n}}const Qn=3e4,$n=`Daemon HTTP endpoint is unavailable`,er=`Daemon socket endpoint is unavailable`;async function tr(e,t){let n=ur(e,t);if(await nr(e,n))return!0;let r=dr(e,t,n);return r?await nr(e,r):!1}async function nr(e,t){return t===`http`?await ir(e):await rr(e.port)}function rr(e){return e?new Promise(t=>{let n=!1,r=j.createConnection({host:`127.0.0.1`,port:e},()=>{i(!0)}),i=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(500),r.on(`timeout`,()=>{i(!1)}),r.on(`error`,()=>{i(!1)})}):Promise.resolve(!1)}function ir(e){return or(e).then(e=>e.reachable)}async function ar(e){let t=await or(e);if(!e.baseUrl||!t.reachable)return t;if(typeof t.rpcProtocolVersion==`number`&&t.rpcProtocolVersion!==2)throw new i(`COMMAND_FAILED`,`Remote daemon RPC protocol is incompatible`,{daemonBaseUrl:e.baseUrl,clientVersion:E(),remoteVersion:t.version,remoteService:t.service,supportedRpcProtocolVersion:2,remoteRpcProtocolVersion:t.rpcProtocolVersion,hint:`Upgrade agent-device on the client or remote host so both support the same daemon RPC protocol.`});return t}async function or(e){let t=e.baseUrl?pe(e.baseUrl,`health`):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!t)return{reachable:!1};let n=new URL(t),r=await S(n.protocol),i=e.baseUrl?3e3:500;return await new Promise(t=>{let a=e.baseUrl?b(e.token):{},o=r.request({protocol:n.protocol,host:n.hostname,port:n.port,path:n.pathname+n.search,method:`GET`,timeout:i,headers:a},e=>{let n=``;e.setEncoding(`utf8`),e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{let r=e.statusCode??500;t({reachable:r<500,statusCode:r,...sr(n)})})});o.on(`timeout`,()=>{o.destroy(),t({reachable:!1})}),o.on(`error`,()=>{t({reachable:!1})}),o.end()})}function sr(e){try{let t=JSON.parse(e);return{service:typeof t.service==`string`?t.service:void 0,version:typeof t.version==`string`?t.version:void 0,rpcProtocolVersion:typeof t.rpcProtocolVersion==`number`?t.rpcProtocolVersion:void 0}}catch{return{}}}async function cr(e,t,n,r,i,a={}){let o=ur(e,n);try{return await lr(e,t,r,i,o,a)}catch(s){let c=dr(e,n,o);if(!c||!fr(s,o))throw s;return await lr(e,t,r,i,c,a)}}async function lr(e,t,n,r,i,a){return i===`http`?await gr(e,t,n,r,a):await hr(e,t,n,r,a)}function ur(e,t){if(e.baseUrl){if(t===`socket`)throw new i(`COMMAND_FAILED`,`Remote daemon endpoint only supports HTTP transport`,{daemonBaseUrl:e.baseUrl});return`http`}if(t===`http`||t===`socket`)return pr(e,t);let n=(e.transport===`socket`||e.transport===`dual`?[`socket`,`http`]:[`http`,`socket`]).find(t=>q(e,t));if(n)return n;throw new i(`COMMAND_FAILED`,`Daemon metadata has no reachable transport`)}function q(e,t){return t===`http`?!!e.httpPort:!!e.port}function dr(e,t,n){if(t!==`auto`||e.baseUrl)return null;let r=n===`socket`?`http`:`socket`;return q(e,r)?r:null}function fr(e,t){return t===`socket`&&e instanceof i&&e.code===`COMMAND_FAILED`&&e.message===`Failed to communicate with daemon`&&e.details?.daemonSocketRequestWritten===!1}function pr(e,t){if(q(e,t))return t;throw new i(`COMMAND_FAILED`,t===`http`?$n:er)}function mr(e,t,n,r={}){return T({level:`error`,phase:`daemon_request_socket_error`,data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new i(`COMMAND_FAILED`,`Failed to communicate with daemon`,{...r,requestId:t,hint:n?`Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.`:`Retry command. If this persists, clean stale daemon metadata and start a fresh session.`},e instanceof Error?e:void 0)}async function hr(e,t,n,r,a){let o=e.port;if(!o)throw new i(`COMMAND_FAILED`,er);return new Promise((i,s)=>{let c=!1,l=j.createConnection({host:`127.0.0.1`,port:o},()=>{c=!0,l.write(`${JSON.stringify(t)}\n`)}),u=!1,d=typeof r==`number`?setTimeout(()=>{u=!0,l.destroy(),s(qn(e,n,t.meta?.requestId,t.command,!1,r,t.flags?.platform))},r):void 0;On(l,{req:t,onProgress:a.onProgress,isSettled:()=>u,clearTimeout:()=>{d&&clearTimeout(d)},resolve:e=>{u=!0,i(e)},reject:e=>{u=!0,s(e)}}),l.on(`error`,e=>{u||(u=!0,d&&clearTimeout(d),s(mr(e,t.meta?.requestId,!1,{daemonSocketRequestWritten:c})))})})}async function gr(e,t,n,r,a){let o=e.baseUrl?new URL(pe(e.baseUrl,`rpc`)):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!o)throw new i(`COMMAND_FAILED`,$n);let s=JSON.stringify(Pn(t,{includeTokenParam:!e.baseUrl})),c={"content-type":`application/json`,"content-length":Buffer.byteLength(s)};e.baseUrl&&Object.assign(c,b(e.token));let l=await S(o.protocol);return await new Promise((u,d)=>{let f=l.request({protocol:o.protocol,host:o.hostname,port:o.port,method:`POST`,path:o.pathname+o.search,headers:c},n=>{if(Dn(t,n.headers?.[`content-type`])){kn(n,{req:t,onProgress:a.onProgress,reject:d,clearTimeout:()=>{m&&clearTimeout(m)},handleResponseBody:n=>An(n,{info:e,req:t,resolve:u,reject:d})});return}ve(n).then(n=>{m&&clearTimeout(m),An(n,{info:e,req:t,resolve:u,reject:d})}).catch(e=>{m&&clearTimeout(m),d(new i(`COMMAND_FAILED`,`Failed to read daemon response`,{requestId:t.meta?.requestId},e instanceof Error?e:void 0))})}),p=bn(e),m=typeof r==`number`?setTimeout(()=>{f.destroy(),d(qn(e,n,t.meta?.requestId,t.command,p,r,t.flags?.platform))},r):void 0;f.on(`error`,e=>{m&&clearTimeout(m),d(mr(e,t.meta?.requestId,p))}),f.write(s),f.end()})}const J=15e3,Y=new j.BlockList;Y.addSubnet(`127.0.0.0`,8,`ipv4`),Y.addAddress(`::1`,`ipv6`),Y.addSubnet(`::ffff:127.0.0.0`,104,`ipv6`);function _r(e,t){let n=vr(e),r=yr(e,t),i=br(e,r.remoteBaseUrl),a=xr(e,n,r.rawBaseUrl);return{paths:y(a?Sr():n),transportPreference:i.preference,serverMode:i.serverMode,ownedStateDir:a,remoteBaseUrl:r.remoteBaseUrl,remoteAuthToken:r.authToken}}function vr(e){return e.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR}function yr(e,t){let n=e.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL,r=Gr(n),i=t??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN;return Kr(r,i),{rawBaseUrl:n,remoteBaseUrl:r,authToken:i}}function br(e,t){let n=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=we(n);if(t&&r===`socket`)throw new i(`INVALID_ARGS`,`Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.`,{daemonBaseUrl:t});return{preference:r,serverMode:Ce(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??(n===`dual`?`dual`:void 0))}}function xr(e,t,n){return Ir(e.command)&&!t&&!n}function Sr(){return k.mkdtempSync(O.join(Ge.tmpdir(),`agent-device-replay-daemon-`))}async function Cr(e){if(e.remoteBaseUrl)return await wr(e);let t=await Tr(e);return t?{info:t,startedByClient:!1}:(vn(e.paths),await jr(e))}async function wr(e){let t={transport:`http`,token:e.remoteAuthToken??``,pid:0,baseUrl:e.remoteBaseUrl};if((await ar(t)).reachable)return{info:t,startedByClient:!1};throw new i(`COMMAND_FAILED`,`Remote daemon is unavailable`,{daemonBaseUrl:e.remoteBaseUrl,hint:`Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc. If this CLI was connected with connect proxy, run agent-device disconnect to return to the local daemon.`})}async function Tr(e){let t=L(e.paths.infoPath);if(!t)return null;let n=await Er(t,e.transportPreference);return Or(t,n)?t:(kr(t,n,e.paths.baseDir),await G(t),V(e.paths.infoPath),null)}async function Er(e,t){try{return await tr(e,t)}catch(e){if(Dr(e))return!1;throw e}}function Dr(e){return e instanceof i&&e.code===`COMMAND_FAILED`&&(e.message===`Daemon HTTP endpoint is unavailable`||e.message===`Daemon socket endpoint is unavailable`)}function Or(e,t){return e.version===E()&&e.codeSignature===Hr()&&t}function kr(e,t,n){try{let r=e.version?`pid ${e.pid}, v${e.version}`:`pid ${e.pid}`,i=Ar(e,t);process.stderr.write(`Replacing daemon (${r}) in ${n}: ${i}\n`)}catch{}}function Ar(e,t){return e.version===E()?e.codeSignature===Hr()?t?`not reusable`:`unreachable`:`code-signature mismatch`:`version mismatch (client v${E()})`}async function jr(e){let t=0,n=[],r,a;for(let i=1;i<=2;i+=1){let o;try{o=Br(e),a={pid:o.pid}}catch(t){if(r=t instanceof Error?t.message:String(t),n.push(await U(e.paths,`start_error`)),i<2){await D(150);continue}break}let s=await zr(J,e,o);if(s.kind===`ready`)return{info:s.info,startedByClient:!0};if(s.kind===`early_exit`){if(a=s.exit,r=Ur(s.exit),n.push(await U(e.paths,`start_error`)),i<2){await D(150);continue}break}if(await yn(e.paths)){t+=1;continue}let c=W(e.paths),l=i<2,u=await U(e.paths,`startup_timeout`,{stopLiveProcesses:!1});if(n.push(u),u.retainedInfoProcess||u.retainedLockProcess){let t=await zr(J,e,o);if(t.kind===`ready`)return{info:t.info,startedByClient:!0};t.kind===`early_exit`&&(a=t.exit,r=Ur(t.exit));break}if(!l)break;!c.hasInfo&&!c.hasLock&&await D(150)}let o=W(e.paths),s=Wr(e.paths.logPath);throw new i(`COMMAND_FAILED`,`Failed to start daemon`,{kind:`daemon_startup_failed`,stateDir:e.paths.baseDir,infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,logPath:e.paths.logPath,startupTimeoutMs:J,startupAttempts:2,lockRecoveryCount:t,cleanupResults:n,startError:r,daemonProcess:a,...s?{daemonLogTail:s}:{},metadataState:o,hint:xn(o,e.paths)})}async function Mr(e,t,n,r){if(!Ir(e.command)||!t.startedByClient&&!n.ownedStateDir||bn(t.info)||Pr(r)||Lr(e,r))return r;let i={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0},a=r;try{await G(t.info)}catch(e){i.error=e instanceof Error?e.message:String(e)}finally{let e=k.existsSync(n.paths.infoPath);V(n.paths.infoPath),i.removedInfo=e&&!k.existsSync(n.paths.infoPath);let t=k.existsSync(n.paths.lockPath);if(H(n.paths.lockPath),i.removedLock=t&&!k.existsSync(n.paths.lockPath),n.ownedStateDir){let e=de(n.paths.sessionsDir);e?a=Nr(r,e):(k.rmSync(n.paths.baseDir,{recursive:!0,force:!0}),i.removedStateDir=!k.existsSync(n.paths.baseDir))}}return T({level:i.error?`warn`:`info`,phase:`daemon_replay_cleanup`,data:i}),a}function Nr(e,n){if(e&&!e.ok)return e;let{sessionName:r,tombstone:a}=n,o=a.sourcePath?`re-run: replay ${a.sourcePath} --save-script`:`re-run your replay <script> --save-script from the start`;return{ok:!1,error:t(new i(`REPAIR_COMMIT_FAILED`,`The repair transaction for session "${r}" completed, but committing its healed script failed at teardown: ${a.commitFailure.message}. ${o}.`))}}function Pr(e){if(!e||e.ok||e.error.code!==`REPLAY_DIVERGENCE`)return!1;let t=e.error.details?.divergence;if(!t||typeof t!=`object`)return!1;let n=t.resume;return!n||typeof n!=`object`?!1:n.repairSessionHeld===!0}function Fr(e,t){let n=`This repair session's daemon was kept alive to continue the repair; pass --state-dir ${t} on your next command (press, replay --from, or close --save-script) to reach it.`,r=e.error.hint;return{...e,error:{...e.error,hint:r?`${r} ${n}`:n}}}function Ir(e){return e===C.replay||e===C.test}function Lr(e,t){return e.command!==C.replay||!t||!t.ok?!1:t.data?.sessionActive===!0}function Rr(e,t){let n=e.data??{},r=typeof n.session==`string`?n.session:void 0,i=[...t?[`--state-dir ${ze(t)}`]:[],...r?[`--session ${ze(r)}`]:[]];if(i.length===0)return e;let a=`This session's daemon was kept alive because its script left the session active; pass ${i.join(` `)} on your next command to reach it.`,o=typeof n.message==`string`?n.message:void 0;return{...e,data:{...n,hint:a,message:o?`${o} ${a}`:a}}}async function zr(e,t,n){let r=Date.now(),i;for(n.exited.then(e=>{i=e});Date.now()-r<e;){if(i)return{kind:`early_exit`,exit:i};let e=L(t.paths.infoPath);if(e&&await tr(e,t.transportPreference))return{kind:`ready`,info:e};if(i)return{kind:`early_exit`,exit:i};await D(100)}return{kind:`timeout`}}function Br(e){let t=Vr(),n=t.useSrc?[`--experimental-strip-types`,t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};k.mkdirSync(e.paths.baseDir,{recursive:!0});let i=k.openSync(e.paths.logPath,`a`),a=k.openSync(e.paths.logPath,`a`);try{return Pe(process.execPath,n,{env:r,stdio:[`ignore`,i,a]})}finally{k.closeSync(i),k.closeSync(a)}}function Vr(){let e=Re(),t=[O.join(e,`dist`,`src`,`internal`,`daemon.js`),O.join(e,`dist`,`src`,`daemon.js`)],n=t[0];if(n===void 0)throw new i(`COMMAND_FAILED`,`Daemon dist path list is empty`);let r=t.find(e=>k.existsSync(e))??n,a=O.join(e,`src`,`daemon.ts`),o=t.some(e=>k.existsSync(e)),s=k.existsSync(a);if(!o&&!s)throw new i(`COMMAND_FAILED`,`Daemon entry not found`,{distPaths:t,srcPath:a});return{root:e,distPath:r,distPaths:t,srcPath:a,useSrc:(process.execArgv.includes(`--experimental-strip-types`)||!o)&&s}}function Hr(){let e=Vr();return _e(e.useSrc?e.srcPath:e.distPath,e.root)}function Ur(e){return e.error?`daemon process ${e.pid} failed to start: ${e.error}`:e.signal?`daemon process ${e.pid} exited before readiness with signal ${e.signal}`:`daemon process ${e.pid} exited before readiness with code ${e.exitCode??0}`}function Wr(e){try{if(!k.existsSync(e))return;let t=k.statSync(e);if(t.size<=0)return;let n=Math.min(t.size,64e3),r=k.openSync(e,`r`);try{let e=Buffer.alloc(n);k.readSync(r,e,0,n,t.size-n);let i=e.toString(`utf8`).trim();return i.length>0?i:void 0}finally{k.closeSync(r)}}catch{return}}function Gr(e){if(!e)return;let t;try{t=new URL(e)}catch(t){throw new i(`INVALID_ARGS`,`Invalid daemon base URL`,{daemonBaseUrl:e},t instanceof Error?t:void 0)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new i(`INVALID_ARGS`,`Daemon base URL must use http or https`,{daemonBaseUrl:e});return t.toString().replace(/\/+$/,``)}function Kr(e,t){if(!e)return;let n=new URL(e).hostname;if(!qr(n)&&!(typeof t==`string`&&t.trim().length>0))throw new i(`INVALID_ARGS`,`Remote daemon base URL for non-loopback hosts requires daemon authentication`,{daemonBaseUrl:e,hint:`Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL.`})}function qr(e){let t=e.trim().toLowerCase().replace(/^\[(.*)\]$/,`$1`);return t===`localhost`?!0:j.isIPv4(t)?Y.check(t,`ipv4`):j.isIPv6(t)?Y.check(t,`ipv6`):!1}async function Jr(e,t={}){let n=e.meta?.requestId??Fe(),r=!!(e.meta?.debug||e.flags?.verbose),i=e.flags,{daemonAuthToken:a,...o}=i??{},s=i?{...e,flags:o}:e,c=_r(s,t.authToken??a),l=Vn(s),u=await je(`daemon_startup`,async()=>await Cr(c),{requestId:n,session:e.session}),d=u.info,f=await Yt(s,d);ni(s.command);let p=Yr(s,f,d.token,n,r);return T({level:`info`,phase:`daemon_request_prepare`,data:{requestId:n,command:s.command,session:s.session}}),await $r(s,u,c,async()=>ti(ei(await je(`daemon_request`,async()=>await cr(d,p,c.transportPreference,c.paths,l,t.onProgress?{onProgress:t.onProgress}:void 0),{requestId:n,command:e.command}),c),s,c))}function Yr(e,t,n,r,i){return{...e,positionals:t.positionals,flags:t.flags,token:n,meta:Xr(e,t,r,i)}}function Xr(e,t,n,r){let i=e.meta??{};return{...i,requestId:n,debug:r,...Zr(i,e.flags),...Qr(t)}}function Zr(e,t){return{includeCost:e.includeCost,cwd:e.cwd,sessionExplicit:e.sessionExplicit,tenantId:e.tenantId??t?.tenant,runId:e.runId??t?.runId,leaseId:e.leaseId??t?.leaseId,sessionIsolation:e.sessionIsolation??t?.sessionIsolation,lockPolicy:e.lockPolicy,lockPlatform:e.lockPlatform}}function Qr(e){return{...e.uploadedArtifactId?{uploadedArtifactId:e.uploadedArtifactId}:{},...e.clientArtifactPaths?{clientArtifactPaths:e.clientArtifactPaths}:{},...e.installSource?{installSource:e.installSource}:{}}}async function $r(e,t,n,r){let a,o=!1,s;try{a=await r()}catch(e){o=!0,s=e}let c=await Mr(e,t,n,a);if(o)throw s;if(!c)throw new i(`COMMAND_FAILED`,`Daemon request produced no response after cleanup`);return c}function ei(e,t){return e.ok||!t.ownedStateDir||!Pr(e)?e:Fr(e,t.paths.baseDir)}function ti(e,t,n){return!e.ok||!Lr(t,e)?e:Rr(e,n.ownedStateDir?n.paths.baseDir:void 0)}function ni(e){!ri(e)||process.stderr.isTTY!==!0||process.env.CI||process.stderr.write(e===C.reinstall?`Reinstalling...
2
2
  `:`Installing...
3
- `)}function ni(e){return e===g.install||e===g.reinstall||e===_.installSource}function Y(e,t){return E.join(e,`metro-sessions`,`${Te(t)}.json`)}function X(e){let t=Y(e.stateDir,e.session);D.mkdirSync(E.dirname(t),{recursive:!0}),D.writeFileSync(t,`${JSON.stringify(e.hints,null,2)}\n`,`utf8`)}function ri(e){let t=Y(e.stateDir,e.session),n;try{n=D.readFileSync(t,`utf8`)}catch{return}let r;try{r=JSON.parse(n)}catch{return}if(!r||typeof r!=`object`||Array.isArray(r))return;let i=r,a={};return typeof i.metroHost==`string`&&i.metroHost&&(a.metroHost=i.metroHost),typeof i.metroPort==`number`&&Number.isInteger(i.metroPort)&&(a.metroPort=i.metroPort),typeof i.bundleUrl==`string`&&i.bundleUrl&&(a.bundleUrl=i.bundleUrl),Object.keys(a).length>0?a:void 0}function ii(e){D.rmSync(Y(e.stateDir,e.session),{force:!0})}var ai=e({createAgentDeviceClient:()=>oi});function oi(e={},t={}){let n=t.transport??qr,o=t=>i(t.responseLevel??e.responseLevel),s=async(t,r=[],i={},o,s)=>{let c=Q(e,i),l={session:j(c.session),command:t,positionals:r,...s?{input:s}:{},flags:Fe(c,o),runtime:c.runtime,meta:dt(c)},u=await n(l,{authToken:c.daemonAuthToken});return u.ok||a(u.error),u.data??{}},c=async(e={})=>{let t=await s(_.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(et)},l=async(e,t={})=>{let n=mt(e,t);return await s(n.command,n.positionals,n.options,n.metadataFlags,n.input)},d=(t={})=>j(Q(e,t).session);return{command:{wait:async e=>await l(`wait`,e),alert:async(e={})=>await l(`alert`,e),..._i(l),reactNative:async e=>await l(`react-native`,e),doctor:async(e={})=>await l(`doctor`,e),prepare:async e=>await l(`prepare`,e),viewport:async e=>await l(`viewport`,e)},devices:{list:async(e={})=>{let t=await l(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map($e)},capabilities:async(e={})=>{let t=await l(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:$e(t.device),availableCommands:n}},boot:async(e={})=>await l(`boot`,e),shutdown:async(e={})=>await l(`shutdown`,e)},sessions:{list:async(e={})=>await c(e),stateDir:async(t={})=>y(Q(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(t={})=>{let n=d(t);try{let e=await l(`close`,t);return{session:n,shutdown:ot(e.shutdown),provider:Z(e.provider),savedScript:h(e,`savedScript`),identifiers:{session:n}}}finally{Si(e,t)}},saveScript:async(e={})=>{let t=await s(_.sessionSaveScript,e.path===void 0?[]:[e.path],e,{force:e.force}),n=t.actionCount;if(typeof n!=`number`||!Number.isInteger(n)||n<0)throw new r(`COMMAND_FAILED`,`Daemon returned an invalid saved-script action count.`);let i=u(t,`session`);return{session:i,savedScript:u(t,`savedScript`),actionCount:n,identifiers:{session:i}}},artifacts:async(e={})=>await l(`artifacts`,e)},apps:{install:async e=>Xe(await l(`install`,e),d(e)),reinstall:async e=>Xe(await l(`reinstall`,e),d(e)),installFromSource:async e=>Ze(await l(`install-from-source`,e),d(e)),list:async(e={})=>{let t=await l(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async t=>{let n=d(t),r=await l(`open`,t);xi({config:e,options:t,runtime:Q(e,t).runtime,sessionReused:r.sessionReused===!0});let i=it(r),a=h(r,`appBundleId`),o=a,s=Array.isArray(r.warnings)?r.warnings.filter(e=>typeof e==`string`):[];return{session:n,...s.length>0?{warnings:s}:{},sessionStateDir:h(r,`sessionStateDir`),runnerLogPath:h(r,`runnerLogPath`),requestLogPath:h(r,`requestLogPath`),eventLogPath:h(r,`eventLogPath`),appName:h(r,`appName`),appBundleId:a,appId:o,startup:at(r.startup),runtime:rt(r.runtime),device:i,...lt(r),identifiers:{session:n,deviceId:i?.id,deviceName:i?.name,udid:i?.ios?.udid,serial:i?.android?.serial,appId:o,appBundleId:a}}},close:async(e={})=>{let t=d(e),n=await l(`close`,e);return{session:t,closedApp:e.app,shutdown:ot(n.shutdown),savedScript:h(n,`savedScript`),identifiers:{session:t}}},push:async e=>await l(`push`,e),triggerEvent:async e=>await l(`trigger-app-event`,e)},materializations:{release:async e=>Qe(await s(_.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ci(await s(_.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ci(await s(_.leaseHeartbeat,[],e)),release:async e=>{let t=await s(_.leaseRelease,[],e);return{released:t.released===!0,provider:Z(t.provider)}}},metro:{prepare:async t=>{let n=await We({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath});return vi(e,n),n},reload:async(t={})=>await Ue({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime??yi(e),timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=d(e),n=await l(`snapshot`,e);return o(e)?n:hi(n,t)},screenshot:async(e={})=>{let t=d(e),n=await l(`screenshot`,e);if(o(e))return n;let r=we(n);return{path:u(n,`path`),width:r?.width,height:r?.height,logicalWidth:r?.logicalWidth,logicalHeight:r?.logicalHeight,pixelDensity:r?.pixelDensity,overlayRefs:r?.overlayRefs,identifiers:{session:t}}},diff:async e=>await l(`diff`,e)},interactions:{click:async e=>await l(`click`,e),press:async e=>await l(`press`,e),longPress:async e=>await l(`longpress`,e),swipe:async e=>await l(`swipe`,e),pan:async e=>await l(`gesture`,si(e)),drag:async e=>await l(`gesture`,ci(e)),fling:async e=>await l(`gesture`,li(e)),swipeGesture:async e=>await l(`gesture`,ui(e)),focus:async e=>await l(`focus`,e),type:async e=>await l(`type`,e),fill:async e=>await l(`fill`,e),scroll:async e=>await l(`scroll`,e),pinch:async e=>await l(`gesture`,di(e)),rotateGesture:async e=>await l(`gesture`,fi(e)),transformGesture:async e=>await l(`gesture`,pi(e)),get:async e=>await l(`get`,e),is:async e=>await l(`is`,e),find:async e=>await l(`find`,e)},replay:{run:async e=>await l(`replay`,e),test:async e=>await l(`test`,e)},batch:{run:async e=>await l(`batch`,e)},observability:{perf:async(e={})=>await l(`perf`,e),logs:async(e={})=>await l(`logs`,e),events:async(e={})=>await l(`events`,e),network:async(e={})=>await l(`network`,e),audio:async(e={})=>await l(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await l(`record`,e),trace:async e=>await l(`trace`,e)},settings:{update:async e=>await l(`settings`,e)}}}function si(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`pan`,origin:{x:t,y:n},delta:{x:r,y:i}}}function ci(e){return{...e,kind:`drag`}}function li(e){let{x:t,y:n,...r}=e;return{...r,kind:`fling`,origin:{x:t,y:n}}}function ui(e){return{...e,kind:`swipe`}}function di(e){let{x:t,y:n,...r}=e;return mi(t,n,`pinch`),{...r,kind:`pinch`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function fi(e){let{x:t,y:n,...r}=e;return mi(t,n,`rotate`),{...r,kind:`rotate`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function pi(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`transform`,origin:{x:t,y:n},delta:{x:r,y:i}}}function mi(e,t,n){if(e===void 0!=(t===void 0))throw new r(`INVALID_ARGS`,`gesture ${n} center requires both x and y`)}function hi(e,t){let n=h(e,`appBundleId`);return{nodes:ut(e.nodes),truncated:e.truncated===!0,appName:h(e,`appName`),appBundleId:n,...gi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function gi(e){let t=Z(e.visibility),n=Z(e.unchanged),r=l(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...o(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{},...typeof e.refsGeneration==`number`?{refsGeneration:e.refsGeneration}:{}}}function _i(e){let t={};for(let[n,r]of Object.entries(Me.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);let n=t.orientation;if(!n)throw Error(`orientation client method missing from the system command family`);return t.rotate=async(e={})=>({...await n(e),action:`rotate`}),t}function Z(e){return m(e)?e:void 0}function Q(e,t){return{...e,...t}}function $(e,t={}){let n=Q(e,t);return{stateDir:y(n.stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,session:j(n.session)}}function vi(e,t){try{let n=new URL(t.statusUrl),r=Number.parseInt(n.port,10);if(!n.hostname||!Number.isInteger(r))return;let i=t.bridge?void 0:t.iosRuntime.bundleUrl??t.androidRuntime.bundleUrl;X({...$(e),hints:{metroHost:n.hostname,metroPort:r,bundleUrl:i}})}catch{}}function yi(e){try{return ri($(e))}catch{return}}function bi(e){if(!e)return;let{metroHost:t,metroPort:n,bundleUrl:r}=e;if(!(t===void 0&&n===void 0&&r===void 0))return{metroHost:t,metroPort:n,bundleUrl:r}}function xi(e){try{let t=$(e.config,e.options),n=bi(e.runtime);if(n){X({...t,hints:n});return}e.sessionReused||ii(t)}catch{}}function Si(e,t){try{ii($(e,t))}catch{}}function Ci(e){let t=e.lease;if(!m(t))throw Error(`Invalid lease response from daemon`);return{leaseId:u(t,`leaseId`),tenantId:u(t,`tenantId`),runId:u(t,`runId`),backend:u(t,`backend`),leaseProvider:h(t,`leaseProvider`),clientId:h(t,`clientId`),deviceKey:h(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}export{gr as a,Sr as i,oi as n,qr as r,ai as t};
3
+ `)}function ri(e){return e===C.install||e===C.reinstall||e===w.installSource}function X(e,t){return O.join(e,`metro-sessions`,`${be(t)}.json`)}function ii(e){let t=X(e.stateDir,e.session);k.mkdirSync(O.dirname(t),{recursive:!0}),k.writeFileSync(t,`${JSON.stringify(e.hints,null,2)}\n`,`utf8`)}function ai(e){let t=X(e.stateDir,e.session),n;try{n=k.readFileSync(t,`utf8`)}catch{return}let r;try{r=JSON.parse(n)}catch{return}if(!r||typeof r!=`object`||Array.isArray(r))return;let i=r,a={};return typeof i.metroHost==`string`&&i.metroHost&&(a.metroHost=i.metroHost),typeof i.metroPort==`number`&&Number.isInteger(i.metroPort)&&(a.metroPort=i.metroPort),typeof i.bundleUrl==`string`&&i.bundleUrl&&(a.bundleUrl=i.bundleUrl),Object.keys(a).length>0?a:void 0}function oi(e){k.rmSync(X(e.stateDir,e.session),{force:!0})}var si=e({createAgentDeviceClient:()=>ci});function ci(e={},t={}){let n=t.transport??Jr,o=t=>a(t.responseLevel??e.responseLevel),s=async(t,i=[],a={},o,s)=>{let c=Q(e,a),l={session:ut(c.session),command:t,positionals:i,...s?{input:s}:{},flags:ke(c,o),runtime:c.runtime,meta:lt(c)},u=await n(l,{authToken:c.daemonAuthToken});return u.ok||r(u.error),u.data??{}},c=async(e={})=>{let t=await s(w.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(Qe)},l=async(e,t={})=>{let n=pt(e,t);return await s(n.command,n.positionals,n.options,n.metadataFlags,n.input)},u=(t={})=>ut(Q(e,t).session);return{command:{wait:async e=>await l(`wait`,e),alert:async(e={})=>await l(`alert`,e),...yi(l),reactNative:async e=>await l(`react-native`,e),doctor:async(e={})=>await l(`doctor`,e),prepare:async e=>await l(`prepare`,e),viewport:async e=>await l(`viewport`,e)},devices:{list:async(e={})=>{let t=await l(`devices`,e);return(Array.isArray(t.devices)?t.devices:[]).map(Ze)},capabilities:async(e={})=>{let t=await l(`capabilities`,e),n=Array.isArray(t.availableCommands)?t.availableCommands.filter(e=>typeof e==`string`):[];return{device:Ze(t.device),availableCommands:n}},boot:async(e={})=>await l(`boot`,e),shutdown:async(e={})=>await l(`shutdown`,e)},sessions:{list:async(e={})=>await c(e),stateDir:async(t={})=>y(Q(e,t).stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,close:async(t={})=>{let n=u(t);try{let e=await l(`close`,t);return{session:n,shutdown:it(e.shutdown),provider:Z(e.provider),savedScript:h(e,`savedScript`),identifiers:{session:n}}}finally{wi(e,t)}},saveScript:async(e={})=>{let t=await s(w.sessionSaveScript,e.path===void 0?[]:[e.path],e,{force:e.force}),n=t.actionCount;if(typeof n!=`number`||!Number.isInteger(n)||n<0)throw new i(`COMMAND_FAILED`,`Daemon returned an invalid saved-script action count.`);let r=g(t,`session`);return{session:r,savedScript:g(t,`savedScript`),actionCount:n,identifiers:{session:r}}},artifacts:async(e={})=>await l(`artifacts`,e)},apps:{install:async e=>Je(await l(`install`,e),u(e)),reinstall:async e=>Je(await l(`reinstall`,e),u(e)),installFromSource:async e=>Ye(await l(`install-from-source`,e),u(e)),list:async(e={})=>{let t=await l(`apps`,e);return Array.isArray(t.apps)?t.apps.filter(e=>typeof e==`string`):[]},open:async t=>{let n=u(t),r=await l(`open`,t);Ci({config:e,options:t,runtime:Q(e,t).runtime,sessionReused:r.sessionReused===!0});let i=nt(r),a=h(r,`appBundleId`),o=a,s=Array.isArray(r.warnings)?r.warnings.filter(e=>typeof e==`string`):[];return{session:n,...s.length>0?{warnings:s}:{},sessionStateDir:h(r,`sessionStateDir`),runnerLogPath:h(r,`runnerLogPath`),requestLogPath:h(r,`requestLogPath`),eventLogPath:h(r,`eventLogPath`),appName:h(r,`appName`),appBundleId:a,appId:o,startup:rt(r.startup),runtime:tt(r.runtime),device:i,...st(r),identifiers:{session:n,deviceId:i?.id,deviceName:i?.name,udid:i?.ios?.udid,serial:i?.android?.serial,appId:o,appBundleId:a}}},close:async(e={})=>{let t=u(e),n=await l(`close`,e);return{session:t,closedApp:e.app,shutdown:it(n.shutdown),savedScript:h(n,`savedScript`),identifiers:{session:t}}},push:async e=>await l(`push`,e),triggerEvent:async e=>await l(`trigger-app-event`,e)},materializations:{release:async e=>Xe(await s(w.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>Ti(await s(w.leaseAllocate,[],{...e,leaseId:void 0})),heartbeat:async e=>Ti(await s(w.leaseHeartbeat,[],e)),release:async e=>{let t=await s(w.leaseRelease,[],e);return{released:t.released===!0,provider:Z(t.provider)}}},metro:{prepare:async t=>{let n=await He({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath});return bi(e,n),n},reload:async(t={})=>await Ve({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime??xi(e),timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{let t=u(e),n=await l(`snapshot`,e);return o(e)?n:_i(n,t)},screenshot:async(e={})=>{let t=u(e),n=await l(`screenshot`,e);if(o(e))return n;let r=ye(n);return{path:g(n,`path`),width:r?.width,height:r?.height,logicalWidth:r?.logicalWidth,logicalHeight:r?.logicalHeight,pixelDensity:r?.pixelDensity,overlayRefs:r?.overlayRefs,identifiers:{session:t}}},diff:async e=>await l(`diff`,e)},interactions:{click:async e=>await l(`click`,e),press:async e=>await l(`press`,e),longPress:async e=>await l(`longpress`,e),swipe:async e=>await l(`swipe`,e),pan:async e=>await l(`gesture`,li(e)),drag:async e=>await l(`gesture`,ui(e)),fling:async e=>await l(`gesture`,di(e)),swipeGesture:async e=>await l(`gesture`,fi(e)),focus:async e=>await l(`focus`,e),type:async e=>await l(`type`,e),fill:async e=>await l(`fill`,e),scroll:async e=>await l(`scroll`,e),pinch:async e=>await l(`gesture`,pi(e)),rotateGesture:async e=>await l(`gesture`,mi(e)),transformGesture:async e=>await l(`gesture`,hi(e)),get:async e=>await l(`get`,e),is:async e=>await l(`is`,e),find:async e=>await l(`find`,e)},replay:{run:async e=>await l(`replay`,e),test:async e=>await l(`test`,e)},batch:{run:async e=>await l(`batch`,e)},observability:{perf:async(e={})=>await l(`perf`,e),logs:async(e={})=>await l(`logs`,e),events:async(e={})=>await l(`events`,e),network:async(e={})=>await l(`network`,e),audio:async(e={})=>await l(`audio`,e)},debug:{symbols:async t=>{let{symbolicateCrashArtifact:n}=await import(`./debug-symbols.js`);return n({cwd:t.cwd??e.cwd,...t})}},recording:{record:async e=>await l(`record`,e),trace:async e=>await l(`trace`,e)},settings:{update:async e=>await l(`settings`,e)}}}function li(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`pan`,origin:{x:t,y:n},delta:{x:r,y:i}}}function ui(e){return{...e,kind:`drag`}}function di(e){let{x:t,y:n,...r}=e;return{...r,kind:`fling`,origin:{x:t,y:n}}}function fi(e){return{...e,kind:`swipe`}}function pi(e){let{x:t,y:n,...r}=e;return gi(t,n,`pinch`),{...r,kind:`pinch`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function mi(e){let{x:t,y:n,...r}=e;return gi(t,n,`rotate`),{...r,kind:`rotate`,...t===void 0&&n===void 0?{}:{origin:{x:t,y:n}}}}function hi(e){let{x:t,y:n,dx:r,dy:i,...a}=e;return{...a,kind:`transform`,origin:{x:t,y:n},delta:{x:r,y:i}}}function gi(e,t,n){if(e===void 0!=(t===void 0))throw new i(`INVALID_ARGS`,`gesture ${n} center requires both x and y`)}function _i(e,t){let n=h(e,`appBundleId`);return{nodes:ct(e.nodes),truncated:e.truncated===!0,appName:h(e,`appName`),appBundleId:n,...vi(e),identifiers:{session:t,appId:n,appBundleId:n}}}function vi(e){let t=Z(e.visibility),n=Z(e.unchanged),r=s(e.snapshotDiagnostics);return{...t?{visibility:t}:{},...o(e),...n?{unchanged:n}:{},...r?{snapshotDiagnostics:r}:{},...typeof e.fallbackScreenshotPath==`string`?{fallbackScreenshotPath:e.fallbackScreenshotPath}:{},...typeof e.refsGeneration==`number`?{refsGeneration:e.refsGeneration}:{}}}function yi(e){let t={};for(let[n,r]of Object.entries(Ee.clientCommandMethods??{}))t[n]=async(t={})=>await e(r,t);let n=t.orientation;if(!n)throw Error(`orientation client method missing from the system command family`);return t.rotate=async(e={})=>({...await n(e),action:`rotate`}),t}function Z(e){return _(e)?e:void 0}function Q(e,t){return{...e,...t}}function $(e,t={}){let n=Q(e,t);return{stateDir:y(n.stateDir??process.env.AGENT_DEVICE_STATE_DIR).baseDir,session:ut(n.session)}}function bi(e,t){try{let n=new URL(t.statusUrl),r=Number.parseInt(n.port,10);if(!n.hostname||!Number.isInteger(r))return;let i=t.bridge?void 0:t.iosRuntime.bundleUrl??t.androidRuntime.bundleUrl;ii({...$(e),hints:{metroHost:n.hostname,metroPort:r,bundleUrl:i}})}catch{}}function xi(e){try{return ai($(e))}catch{return}}function Si(e){if(!e)return;let{metroHost:t,metroPort:n,bundleUrl:r}=e;if(!(t===void 0&&n===void 0&&r===void 0))return{metroHost:t,metroPort:n,bundleUrl:r}}function Ci(e){try{let t=$(e.config,e.options),n=Si(e.runtime);if(n){ii({...t,hints:n});return}e.sessionReused||oi(t)}catch{}}function wi(e,t){try{oi($(e,t))}catch{}}function Ti(e){let t=e.lease;if(!_(t))throw Error(`Invalid lease response from daemon`);return{leaseId:g(t,`leaseId`),tenantId:g(t,`tenantId`),runId:g(t,`runId`),backend:g(t,`backend`),leaseProvider:h(t,`leaseProvider`),clientId:h(t,`clientId`),deviceKey:h(t,`deviceKey`),createdAt:typeof t.createdAt==`number`?t.createdAt:void 0,heartbeatAt:typeof t.heartbeatAt==`number`?t.heartbeatAt:void 0,expiresAt:typeof t.expiresAt==`number`?t.expiresAt:void 0}}export{_r as a,Cr as i,ci as n,Jr as r,si as t};
@@ -1,12 +1,12 @@
1
1
  import { a as createAndroidPortReverseManager, i as AndroidPortReverseEndpoint, n as AndroidAdbExecutorOptions, r as AndroidAdbProvider, t as AndroidAdbExecutor } from "./sdk-android-adb.js";
2
2
  import { t as AppsFilter } from "./app-inventory.js";
3
3
  import { a as readAndroidClipboardWithAdb, i as getAndroidKeyboardStatusWithAdb, n as AndroidKeyboardState, o as writeAndroidClipboardWithAdb, r as dismissAndroidKeyboardWithAdb, t as AndroidKeyboardDismissResult } from "./device-input-state.js";
4
- import fs from "node:fs";
5
- //#region src/platforms/android/app-parsers.d.ts
6
- type AndroidForegroundApp = {
4
+ //#region packages/contracts/src/app-state-runtime.d.ts
5
+ /** Neutral foreground identity returned by a selected platform/provider runtime. */
6
+ type AppStateRuntimeResult = Readonly<{
7
7
  package?: string;
8
8
  activity?: string;
9
- };
9
+ }>;
10
10
  //#endregion
11
11
  //#region src/platforms/android/app-helpers.d.ts
12
12
  type AndroidAppListFilter = AppsFilter;
@@ -19,7 +19,7 @@ declare function listAndroidAppsWithAdb(adb: AndroidAdbExecutor, options?: Andro
19
19
  package: string;
20
20
  name: string;
21
21
  }>>;
22
- declare function getAndroidAppStateWithAdb(adb: AndroidAdbExecutor): Promise<AndroidForegroundApp>;
22
+ declare function getAndroidAppStateWithAdb(adb: AndroidAdbExecutor): Promise<AppStateRuntimeResult>;
23
23
  //#endregion
24
24
  //#region src/platforms/android/app-control.d.ts
25
25
  type AndroidOpenAppWithAdbOptions = {
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{r as t}from"./sdk-android-adb.js";import{o as n,u as r}from"./app-lifecycle.js";import{n as i,r as a}from"./app-helpers.js";import{t as o}from"./logcat.js";import{c as s,i as c,n as l,o as u}from"./device-input-state.js";const d=`android.intent.category.LAUNCHER`,f=`android.intent.category.DEFAULT`;async function p(e,t){await e([`shell`,`am`,`force-stop`,t])}async function m(e,t,n=[d]){for(let i of n){let n=await e([`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,i,t],{allowFailure:!0});if(n.exitCode!==0)continue;let a=r(n.stdout);if(a)return a}return null}async function h(t,r,i={}){let a=i.category??d;if(i.activity){await t([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,f,`-c`,a,`-n`,g(r,i.activity)]);return}let o=await t([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,f,`-c`,a,`-p`,r],{allowFailure:!0});if(o.exitCode===0&&!n(o.stdout,o.stderr))return;let s=await m(t,r,[a]);if(!s)throw new e(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${r}`,{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});await t([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,f,`-c`,a,`-n`,s])}function g(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}export{o as captureAndroidLogcatWithAdb,t as createAndroidPortReverseManager,l as dismissAndroidKeyboardWithAdb,p as forceStopAndroidAppWithAdb,i as getAndroidAppStateWithAdb,c as getAndroidKeyboardStatusWithAdb,a as listAndroidAppsWithAdb,h as openAndroidAppWithAdb,u as readAndroidClipboardWithAdb,s as writeAndroidClipboardWithAdb};
1
+ import{_ as e}from"./sdk-contracts.js";import{r as t}from"./sdk-android-adb.js";import{a as n,c as r}from"./app-lifecycle.js";import{n as i,r as a}from"./app-helpers.js";import{t as o}from"./logcat.js";import{c as s,i as c,n as l,o as u}from"./device-input-state.js";const d=`android.intent.category.LAUNCHER`,f=`android.intent.category.DEFAULT`;async function p(e,t){await e([`shell`,`am`,`force-stop`,t])}async function m(e,t,n=[d]){for(let i of n){let n=await e([`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,i,t],{allowFailure:!0});if(n.exitCode!==0)continue;let a=r(n.stdout);if(a)return a}return null}async function h(t,r,i={}){let a=i.category??d;if(i.activity){await t([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,f,`-c`,a,`-n`,g(r,i.activity)]);return}let o=await t([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,f,`-c`,a,`-p`,r],{allowFailure:!0});if(o.exitCode===0&&!n(o.stdout,o.stderr))return;let s=await m(t,r,[a]);if(!s)throw new e(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${r}`,{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});await t([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,f,`-c`,a,`-n`,s])}function g(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}export{o as captureAndroidLogcatWithAdb,t as createAndroidPortReverseManager,l as dismissAndroidKeyboardWithAdb,p as forceStopAndroidAppWithAdb,i as getAndroidAppStateWithAdb,c as getAndroidKeyboardStatusWithAdb,a as listAndroidAppsWithAdb,h as openAndroidAppWithAdb,u as readAndroidClipboardWithAdb,s as writeAndroidClipboardWithAdb};
@@ -1 +1 @@
1
- import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{b as n,m as r,wt as i,y as a}from"./version.js";import{F as o,n as s,u as c}from"./sdk-android-adb.js";import{t as ee}from"./timeouts.js";import{c as l,d as u,l as d,n as f}from"./app-lifecycle.js";import{a as p}from"./install-artifact.js";import{a as m,s as h}from"./device-input-state.js";import{c as g,d as te,f as _,h as v,i as y,l as b,m as x,n as S,o as C,p as w,r as T,t as E,u as D}from"./input-actions.js";import{f as O}from"./ime-lifecycle.js";import{n as k,r as A,t as j}from"./setting-state.js";import{t as M}from"./method-scope.js";import{promises as N}from"node:fs";const P=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function F(e,n,i,o,s){switch(n.toLowerCase()){case`wifi`:await p(e,[`shell`,`svc`,`wifi`,j(i)?`enable`:`disable`]);return;case`airplane`:{let t=j(i),n=t?`1`:`0`,r=t?`true`:`false`;await p(e,[`shell`,`settings`,`put`,`global`,`airplane_mode_on`,n]),await p(e,[`shell`,`am`,`broadcast`,`-a`,`android.intent.action.AIRPLANE_MODE`,`--ez`,`state`,r]);return}case`location`:if(i.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:i}=r(s);return await p(e,[`emu`,`geo`,`fix`,String(i),String(n)]),{latitude:n,longitude:i}}await p(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,j(i)?`3`:`0`]);return;case`animations`:{let t=j(i)?`1`:`0`;for(let n of P)await p(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...P]}}case`appearance`:await p(e,[`shell`,`cmd`,`uimode`,`night`,await B(e,i)===`dark`?`yes`:`no`]);return;case`clear-app-state`:{if(i.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!o)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await u(e,o);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await p(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let r=await p(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(r.exitCode!==0||!/\bSuccess\b/i.test(r.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await L(e,I(i));return;case`permission`:{if(!o)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);let n=a(i),r=H(s?.permissionTarget,s?.permissionMode);if(r.kind===`notifications`){await W(e,o,n,r);return}let c=n===`grant`?`grant`:`revoke`;if(r.type===`photos`){let t=await U(e,o,c);n===`reset`&&await G(e,o,t);return}await p(e,[`shell`,`pm`,c,o,r.value]),n===`reset`&&await G(e,o,r.value);return}default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function I(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function L(e,n){let r=R(e,n),i=[];for(let t of r){let n=await p(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=A(i);throw i.length>0&&i.every(e=>z(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function R(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function z(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function B(e,n){let r=k(n);if(r!==`toggle`)return r;let i=await p(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw s(`Failed to read current Android appearance`,i);let a=V(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function V(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}function H(e,r){let i=n(e);if(r?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${r}.`);if(i===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(i===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(i===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(i===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(i===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function U(e,n,r){let i=await K(e),a=i!==null&&i>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],o=[];for(let t of a){let i=await p(e,[`shell`,`pm`,r,n,t],{allowFailure:!0});if(i.exitCode===0)return t;o.push({permission:t,stderr:i.stderr,exitCode:i.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:i,attempts:o})}async function W(e,t,n,r){let i=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await p(e,[`shell`,`pm`,`grant`,t,r.permission],{allowFailure:!0}):(await p(e,[`shell`,`pm`,`revoke`,t,r.permission],{allowFailure:!0}),n===`reset`&&await G(e,t,r.permission)),await p(e,[`shell`,`appops`,`set`,t,r.appOps,i])}async function G(e,t,n){await p(e,[`shell`,`pm`,`clear-permission-flags`,t,n,`user-set`],{allowFailure:!0}),await p(e,[`shell`,`pm`,`clear-permission-flags`,t,n,`user-fixed`],{allowFailure:!0})}async function K(e){let t=await p(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}const q=Buffer.from([137,80,78,71,13,10,26,10]);async function J(e,t,n={}){if(n.stabilize===!1){await Z(e,t);return}await Y(e);try{await ee(1e3),await Z(e,t)}finally{await X(e).catch(()=>{})}}async function Y(e){let t=t=>p(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function X(e){await p(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Z(e,n){let r=await p(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(q);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Q(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await N.writeFile(n,r.stdoutBuffer.subarray(i,a))}function Q(e,t){let n=t+q.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}var ne=e({createAndroidInteractor:()=>$});function $(e,t,n){let r={open:(t,n)=>l(e,t,{activity:n?.activity,appBundleId:n?.appBundleId,launchArgs:n?.launchArgs,url:n?.url}),openDevice:()=>d(e),close:t=>f(e,t),tap:(t,n)=>b(e,t,n),doubleTap:async(t,n)=>{await b(e,t,n),await b(e,t,n)},longPress:(t,n,r)=>g(e,t,n,r),focus:(t,n)=>y(e,t,n),type:(t,n)=>w(e,t,n),fill:(t,n,r,i)=>T(e,t,n,r,i),scroll:(t,n)=>te(e,t,n),performGesture:t=>x(e,t),gestureViewport:()=>v(e),screenshot:(t,n)=>J(e,t,n),snapshot:async t=>{let r=t??{},a=await o(`snapshot_capture`,async()=>await O(e,{appBundleId:r.appBundleId,signal:r.signal??n?.signal,interactiveOnly:r.interactiveOnly,depth:r.depth,scope:r.scope,raw:r.raw,includeHiddenContentHints:r.includeHiddenContentHints,helperSessionScope:r.appBundleId?`daemon-session`:`command`}),{backend:`android`});return{nodes:a.nodes??[],truncated:a.truncated??!1,backend:`android`,...i(a)}},back:t=>S(e),home:()=>C(e),setOrientation:t=>_(e,t),appSwitcher:()=>E(e),tvRemote:(t,n)=>D(e,t,n),readClipboard:()=>m(e),writeClipboard:t=>h(e,t),setSetting:(t,n,r,i)=>F(e,t,n,r,i)};return t?M(r,n=>c(t,{serial:e.id},n)):r}export{$ as n,ne as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{c as n,g as r,n as i,s as a}from"./location-coordinates.js";import{F as o,n as s,u as c}from"./sdk-android-adb.js";import{t as l}from"./timeouts.js";import{f as u,g as d,n as f,o as p,s as ee}from"./app-lifecycle.js";import{a as m,s as h}from"./device-input-state.js";import{c as g,d as te,f as _,h as v,i as y,l as b,m as x,n as S,o as C,p as w,r as T,t as E,u as D}from"./input-actions.js";import{n as O}from"./snapshot.js";import{n as k,t as A}from"./setting-state.js";import{t as j}from"./appearance.js";import{t as M}from"./method-scope.js";import{promises as N}from"node:fs";const P=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function F(e,n,r,o,s){switch(n.toLowerCase()){case`wifi`:await d(e,[`shell`,`svc`,`wifi`,A(r)?`enable`:`disable`]);return;case`airplane`:{let t=A(r),n=t?`1`:`0`,i=t?`true`:`false`;await d(e,[`shell`,`settings`,`put`,`global`,`airplane_mode_on`,n]),await d(e,[`shell`,`am`,`broadcast`,`-a`,`android.intent.action.AIRPLANE_MODE`,`--ez`,`state`,i]);return}case`location`:if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:r}=i(s);return await d(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}await d(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,A(r)?`3`:`0`]);return;case`animations`:{let t=A(r)?`1`:`0`;for(let n of P)await d(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...P]}}case`appearance`:await d(e,[`shell`,`cmd`,`uimode`,`night`,await B(e,r)===`dark`?`yes`:`no`]);return;case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!o)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await u(e,o);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await d(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let i=await d(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(i.exitCode!==0||!/\bSuccess\b/i.test(i.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await L(e,I(r));return;case`permission`:{if(!o)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);let n=a(r),i=H(s?.permissionTarget,s?.permissionMode);if(i.kind===`notifications`){await W(e,o,n,i);return}let c=n===`grant`?`grant`:`revoke`;if(i.type===`photos`){let t=await U(e,o,c);n===`reset`&&await G(e,o,t);return}await d(e,[`shell`,`pm`,c,o,i.value]),n===`reset`&&await G(e,o,i.value);return}default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function I(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function L(e,n){let r=R(e,n),i=[];for(let t of r){let n=await d(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=k(i);throw i.length>0&&i.every(e=>z(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function R(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function z(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function B(e,n){let r=j(n);if(r!==`toggle`)return r;let i=await d(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw s(`Failed to read current Android appearance`,i);let a=V(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function V(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}function H(e,r){let i=n(e);if(r?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${r}.`);if(i===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(i===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(i===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(i===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(i===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function U(e,n,r){let i=await K(e),a=i!==null&&i>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],o=[];for(let t of a){let i=await d(e,[`shell`,`pm`,r,n,t],{allowFailure:!0});if(i.exitCode===0)return t;o.push({permission:t,stderr:i.stderr,exitCode:i.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:i,attempts:o})}async function W(e,t,n,r){let i=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await d(e,[`shell`,`pm`,`grant`,t,r.permission],{allowFailure:!0}):(await d(e,[`shell`,`pm`,`revoke`,t,r.permission],{allowFailure:!0}),n===`reset`&&await G(e,t,r.permission)),await d(e,[`shell`,`appops`,`set`,t,r.appOps,i])}async function G(e,t,n){await d(e,[`shell`,`pm`,`clear-permission-flags`,t,n,`user-set`],{allowFailure:!0}),await d(e,[`shell`,`pm`,`clear-permission-flags`,t,n,`user-fixed`],{allowFailure:!0})}async function K(e){let t=await d(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}const q=Buffer.from([137,80,78,71,13,10,26,10]);async function J(e,t,n={}){if(n.stabilize===!1){await Z(e,t);return}await Y(e);try{await l(1e3),await Z(e,t)}finally{await X(e).catch(()=>{})}}async function Y(e){let t=t=>d(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function X(e){await d(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Z(e,n){let r=await d(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(q);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Q(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await N.writeFile(n,r.stdoutBuffer.subarray(i,a))}function Q(e,t){let n=t+q.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}var ne=e({createAndroidInteractor:()=>$});function $(e,t,n){let i={open:(t,n)=>p(e,t,{activity:n?.activity,appBundleId:n?.appBundleId,launchArgs:n?.launchArgs,url:n?.url}),openDevice:()=>ee(e),close:t=>f(e,t),tap:(t,n)=>b(e,t,n),doubleTap:async(t,n)=>{await b(e,t,n),await b(e,t,n)},longPress:(t,n,r)=>g(e,t,n,r),focus:(t,n)=>y(e,t,n),type:(t,n)=>w(e,t,n),fill:(t,n,r,i)=>T(e,t,n,r,i),scroll:(t,n)=>te(e,t,n),performGesture:t=>x(e,t),gestureViewport:()=>v(e),screenshot:(t,n)=>J(e,t,n),snapshot:async t=>{let i=t??{},a=await o(`snapshot_capture`,async()=>await O(e,{appBundleId:i.appBundleId,signal:i.signal??n?.signal,interactiveOnly:i.interactiveOnly,depth:i.depth,scope:i.scope,raw:i.raw,includeHiddenContentHints:i.includeHiddenContentHints,helperSessionScope:i.appBundleId?`daemon-session`:`command`}),{backend:`android`});return{nodes:a.nodes??[],truncated:a.truncated??!1,backend:`android`,...r(a)}},back:t=>S(e),home:()=>C(e),setOrientation:t=>_(e,t),appSwitcher:()=>E(e),tvRemote:(t,n)=>D(e,t,n),readClipboard:()=>m(e),writeClipboard:t=>h(e,t),setSetting:(t,n,r,i)=>F(e,t,n,r,i)};return t?M(i,n=>c(t,{serial:e.id},n)):i}export{$ as n,ne as t};
@@ -1 +1 @@
1
- import{o as e}from"./png-worker-contract.js";import{p as t}from"./device.js";import{n}from"./sdk-android-adb.js";import{a as r,g as i,h as a,m as o}from"./app-lifecycle.js";var s=e({getAndroidAppStateWithAdb:()=>d,listAndroidAppsWithAdb:()=>u});const c=`android.intent.category.LAUNCHER`,l=`android.intent.category.LEANBACK_LAUNCHER`;async function u(e,n={}){let i=await f(e,n.target??`auto`);return(t(n.filter)===`user-installed`?(await g(e)).filter(e=>i.has(e)):Array.from(i)).map(e=>({package:e,name:r(e)})).sort((e,t)=>e.package.localeCompare(t.package))}async function d(e){return await _(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await _(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function f(e,t){let n=(await Promise.all(p(t).map(async t=>{let n=await e(m(t),{allowFailure:!0});return n.exitCode===0?h(n.stdout):[]}))).flat();return new Set(n)}function p(e){switch(e){case`mobile`:return[c];case`tv`:return[l];default:return[c,l]}}function m(e){return[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,e]}function h(e){return e.trim().length===0?[]:a(e)}async function g(e){let t=await e([`shell`,`pm`,`list`,`packages`,`-3`],{allowFailure:!0});if(t.exitCode!==0)throw n(`Failed to list Android user-installed apps`,t);return i(t.stdout)}async function _(e,t){for(let n of t){let t=o((await e(n,{allowFailure:!0})).stdout??``);if(t)return t}return null}export{d as n,u as r,s as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{p as t}from"./device.js";import{n}from"./sdk-android-adb.js";import{d as r,v as i,y as a}from"./app-lifecycle.js";var o=e({getAndroidAppStateWithAdb:()=>u,listAndroidAppsWithAdb:()=>l});const s=`android.intent.category.LAUNCHER`,c=`android.intent.category.LEANBACK_LAUNCHER`;async function l(e,n={}){let i=await d(e,n.target??`auto`);return(t(n.filter)===`user-installed`?(await h(e)).filter(e=>i.has(e)):Array.from(i)).map(e=>({package:e,name:r(e)})).sort((e,t)=>e.package.localeCompare(t.package))}async function u(e){return await g(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await g(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function d(e,t){let n=(await Promise.all(f(t).map(async t=>{let n=await e(p(t),{allowFailure:!0});return n.exitCode===0?m(n.stdout):[]}))).flat();return new Set(n)}function f(e){switch(e){case`mobile`:return[s];case`tv`:return[c];default:return[s,c]}}function p(e){return[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,e]}function m(e){return e.trim().length===0?[]:i(e)}async function h(e){let t=await e([`shell`,`pm`,`list`,`packages`,`-3`],{allowFailure:!0});if(t.exitCode!==0)throw n(`Failed to list Android user-installed apps`,t);return a(t.stdout)}async function g(e,t){let{parseAndroidForegroundApp:n}=await import(`./platform-runtime.js`).then(e=>e.r);for(let r of t){let t=await n((await e(r,{allowFailure:!0})).stdout??``);if(t)return t}return null}export{u as n,l as r,o as t};
@@ -1,7 +1,6 @@
1
- import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{s as n}from"./sdk-batch-runner.js";import{C as r,_ as i,g as a,i as o,n as s,r as c,s as l}from"./sdk-android-adb.js";import{n as u}from"./shell-quote.js";import{t as d}from"./timeouts.js";import{a as f,c as ee,n as p,s as m}from"./install-artifact.js";import h from"node:path";import{promises as g}from"node:fs";import te from"node:os";const ne=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],re=/\bApplication Not Responding:\s*([A-Za-z0-9_.]+)/i,ie=/([^{}]*\bis(?:n't| not)\s+responding[^{}]*)/i,ae=/\b([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+)\b/;function _(e){let t=new Set;for(let n of e.split(`
2
- `)){let e=n.trim();if(!e)continue;let r=e.split(/\s+/)[0]??``;if(!r.includes(`/`))continue;let i=r.split(`/`)[0]??``;i.includes(`.`)&&i&&t.add(i)}return Array.from(t)}function v(e){return e.split(`
3
- `).map(e=>{let t=e.trim();return t.startsWith(`package:`)?t.slice(8):t}).filter(Boolean)}function y(e){return b(e,e=>ce(e))}function oe(e){return b(e,(e,t)=>se(e,t))}function b(e,t){let n=e.split(`
4
- `);for(let e of ne)for(let r of n){let n=r.indexOf(e);if(n===-1)continue;let i=r.trim(),a=t(r.slice(n+e.length),i);if(a)return a}return null}function se(e,t){let n=e.split(`}`)[0]?.trim()??e.trim(),r=re.exec(n);if(r){let e=r[1];return{package:e,focusedWindow:`Application Not Responding: ${e}`,raw:t}}let i=ie.exec(n);if(!i)return null;let a=i[1];if(a===void 0)return null;let o=a.trim().replace(/\s+/g,` `),s=ae.exec(o)?.[1];return{...s?{package:s}:{},focusedWindow:o,raw:t}}function ce(e){for(let t of e.trim().split(/\s+/)){let e=t.indexOf(`/`);if(e<=0)continue;let n=x(t.slice(0,e),!1),r=x(t.slice(e+1),!0);if(n&&r&&n.length===e)return{package:n,activity:r}}return null}function x(e,t){let n=0;for(;n<e.length&&le(e[n],t);)n+=1;return e.slice(0,n)}function le(e,t){if(!e)return!1;let n=e.charCodeAt(0);return n>=48&&n<=57||n>=65&&n<=90||n>=97&&n<=122||e===`_`||e===`.`||t&&e===`$`}const ue=/\.(?:apk|aab)$/i,de=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function S(e){let t=e.trim();return t.length===0?`other`:ue.test(t)?t.includes(`/`)||t.includes(`\\`)||t.startsWith(`.`)||t.startsWith(`~`)||!C(t)?`binary`:`package`:C(t)?`package`:`other`}function C(e){return de.test(e)}function fe(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}var pe=e({closeAndroidApp:()=>q,getAndroidAppState:()=>P,getAndroidBlockingDialogFocus:()=>F,inferAndroidAppName:()=>N,installAndroidApp:()=>He,installAndroidInstallablePath:()=>Q,installAndroidInstallablePathAndResolvePackageName:()=>$,isAmStartError:()=>W,listAndroidApps:()=>j,openAndroidApp:()=>z,openAndroidDevice:()=>K,parseAndroidLaunchComponent:()=>G,reinstallAndroidApp:()=>Ue,resolveAndroidApp:()=>A});const me={settings:{type:`intent`,value:`android.settings.SETTINGS`}},w=`android.intent.category.LAUNCHER`,T=`android.intent.category.LEANBACK_LAUNCHER`,E=`android.intent.category.DEFAULT`,D=`Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.`,he=new Set([`localhost`,`127.0.0.1`,`::1`,`[::1]`]),O=ee();function k(e){return{platform:`android`,deviceId:e.id,variant:e.target??``}}async function A(e,n){let r=n.trim();if(S(r)===`package`)return{type:`package`,value:r};let i=me[r.toLowerCase()];if(i)return i;let a=k(e),o=O.get(a,r);if(o)return o;let s=(await f(e,[`shell`,`pm`,`list`,`packages`])).stdout.split(`
5
- `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase())),c=s[0];if(c!==void 0&&s.length===1)return O.set(a,r,{type:`package`,value:c});throw s.length>1?new t(`INVALID_ARGS`,`Multiple packages matched "${n}"`,{matches:s,hint:`Run agent-device apps --platform android to see the exact installed package names before retrying open.`}):new t(`APP_NOT_INSTALLED`,`No package found matching "${n}"`,{hint:D})}async function j(e,t){let n=await ge(e);return(t===`user-installed`?(await ve(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:N(e)}))}async function ge(e){let t=new Set;for(let n of M(e,{includeFallbackWhenUnknown:!0})){let r=await f(e,[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,n],{allowFailure:!0});if(!(r.exitCode!==0||r.stdout.trim().length===0))for(let e of _(r.stdout))t.add(e)}return t}function _e(e){return M(e)[0]??w}function M(e,t={}){return e.target===`tv`?[T]:e.target===`mobile`?[w]:t.includeFallbackWhenUnknown?[w,T]:[w]}async function ve(e){return v((await f(e,[`shell`,`pm`,`list`,`packages`,`-3`])).stdout)}function N(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(`.`).flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),r=n[n.length-1]??e;for(let e=n.length-1;e>=0;--e){let i=n[e];if(i&&!t.has(i)){r=i;break}}return r.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}async function P(e){return await I(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await I(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function F(e){return await ye(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])}async function I(e,t){for(let n of t){let t=y((await f(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}async function ye(e,t){for(let n of t){let t=oe((await f(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}function be(e){let t;try{t=new URL(e)}catch{return null}let n=t.hostname.toLowerCase();if(!he.has(n)||!t.port)return null;let r=Number(t.port);return Number.isInteger(r)?`tcp:${r}`:null}async function L(e,n){let r=be(n);if(!r)return;let i=c(l(e));try{await i.ensure({local:r,remote:r})}catch(e){let n={localPort:r.replace(`tcp:`,``),operation:`adb reverse ${r} ${r}`};throw e instanceof t&&Object.assign(n,{hint:e.details?.hint,diagnosticId:e.details?.diagnosticId,logPath:e.details?.logPath}),new t(`COMMAND_FAILED`,`Failed to ensure Android port reverse ${r} before opening localhost URL`,n,e)}}function R(e){return(e.launchArgs??[]).map(u)}async function z(e,t,r){e.booted||await m(e.id);let i=De(r),a=i.activity,o=t.trim();if(n(o)){await xe(e,o,i);return}if(i.url!==void 0){await Se(e,t,i);return}let s=await A(e,t),c=_e(e);if(s.type===`intent`){await Ce(e,s.value,i);return}if(a){await we(e,s.value,a,c,i);return}await Te(e,s.value,c,i)}async function xe(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening a deep link URL`);await L(e,n),await f(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,u(n),...Oe(r.appBundleId),...R(r)])}async function Se(e,r,i){if(i.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening an app-bound deep link URL`);let a=i.url?.trim()??``;if(!n(a))throw new t(`INVALID_ARGS`,`Android app-bound open requires a valid URL target`);await L(e,a);let o=await Ee(e,r,`app-bound open`);await f(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,u(a),`-p`,o,...R(i)])}async function Ce(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override requires a package name, not an intent`);await f(e,[`shell`,`am`,`start`,`-W`,`-a`,n,...R(r)])}async function we(e,t,n,r,i){let a=n.includes(`/`)?n:`${t}/${n.startsWith(`.`)?n:`.${n}`}`;try{await f(e,B(a,r,i))}catch(n){throw await ke(e,t,n),n}}async function Te(e,t,n,r){let i=await f(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,E,`-c`,n,`-p`,t,...R(r)],{allowFailure:!0});if(i.exitCode===0&&!W(i.stdout,i.stderr))return;let a=await Ae(e,t);if(!a)throw await H(e,t)?s(`Failed to launch ${t}`,i):V(t);await f(e,B(a,n,r))}function B(e,t,n){return[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,E,`-c`,t,`-n`,e,...R(n)]}async function Ee(e,n,r){let i=await A(e,n);if(i.type===`intent`)throw new t(`INVALID_ARGS`,`Android ${r} requires a package name, not an intent`);return i.value}function De(e){return typeof e==`string`?{activity:e}:e??{}}function Oe(e){let t=e?.trim();return t?[`-p`,t]:[]}function V(e){return new t(`APP_NOT_INSTALLED`,`No package found matching "${e}"`,{package:e,hint:D})}async function H(e,t){let n=await f(e,[`shell`,`pm`,`path`,t],{allowFailure:!0}),r=`${n.stdout}\n${n.stderr}`;return n.exitCode===0&&/\bpackage:/i.test(r)?!0:(U(r),!1)}async function ke(e,n,r){if(U(r instanceof t?`${String(r.details?.stdout??``)}\n${String(r.details?.stderr??``)}`:``)||!await H(e,n))throw V(n)}function U(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function Ae(e,t){let n=Array.from(new Set(M(e,{includeFallbackWhenUnknown:!0})));for(let r of n){let n=await f(e,[`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=G(n.stdout);if(i)return i}return null}function W(e,t){let n=`${e}\n${t}`;return/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(n)}function G(e){let t=e.split(`
6
- `).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;--e){let n=t[e];if(n===void 0||!n.includes(`/`))continue;let r=n.split(/\s+/)[0];if(r!==void 0)return r}return null}async function K(e){e.booted||await m(e.id)}async function q(e,n){if(n.trim().toLowerCase()===`settings`){await f(e,[`shell`,`am`,`force-stop`,`com.android.settings`]),await J(e,`com.android.settings`);return}let r=await A(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`Close requires a package name, not an intent`);await f(e,[`shell`,`am`,`force-stop`,r.value]),await J(e,r.value)}async function J(e,t){await je(e,t),await Ne(e,t)}async function je(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if((await Me(e))?.package!==t)return;await d(50)}}async function Me(e){for(let t of[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`],[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]]){let n=y((await f(e,t,{allowFailure:!0})).stdout??``);if(n)return n}return null}async function Ne(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if(!await Y(e,t)&&(await d(150),!await Y(e,t)))return;await d(50)}}async function Y(e,t){return((await f(e,[`shell`,`pidof`,t],{allowFailure:!0})).stdout??``).trim().length>0}async function Pe(e,n){let r=await A(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`);let i=await f(e,[`uninstall`,r.value],{allowFailure:!0});if(i.exitCode!==0){let e=`${i.stdout}\n${i.stderr}`.toLowerCase();if(!e.includes(`unknown package`)&&!e.includes(`not installed`))throw s(`adb uninstall failed for ${r.value}`,i)}return{package:r.value}}let X=null;function Fe(){return`${process.env.PATH??``}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Ie(){let e=Fe();if(X?.key===e)return X.invocation;if(await r(`bundletool`)){let t={cmd:`bundletool`,prefixArgs:[]};return X={key:e,invocation:t},t}let n=await a(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!n)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,n]};return X={key:e,invocation:i},i}async function Z(e){let t=await Ie();await i(t.cmd,[...t.prefixArgs,...e])}function Le(e){return h.extname(e).toLowerCase()===`.aab`}async function Re(e,t){let n=l(e),r=`universal`;if(n.installBundle){await n.installBundle(t,{mode:r});return}let i=await g.mkdtemp(h.join(te.tmpdir(),`agent-device-aab-`)),a=h.join(i,`bundle.apks`);try{await Z([`build-apks`,`--bundle`,t,`--output`,a,`--mode`,r]),await Z([`install-apks`,`--apks`,a,`--device-id`,e.id])}finally{await g.rm(i,{recursive:!0,force:!0})}}async function ze(e,t){if(Le(t)){await Re(e,t);return}await o(t,{device:e,replace:!0})}async function Be(e){let t=await f(e,[`shell`,`pm`,`list`,`packages`]);return new Set(t.stdout.split(`
7
- `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}async function Ve(e,t){let n=await Be(e),r=Array.from(n).filter(e=>!t.has(e));if(r.length===1)return r[0]}async function Q(e,t){await O.invalidateWhile(k(e),async()=>{e.booted||await m(e.id),await ze(e,t)})}async function $(e,t,n){let r=n?void 0:await Be(e);return await Q(e,t),n??(r?await Ve(e,r):void 0)}async function He(e,t){e.booted||await m(e.id);let n=await p({kind:`path`,path:t});try{let t=await $(e,n.installablePath,n.packageName),r=t?N(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:r,launchTarget:t}}finally{await n.cleanup()}}async function Ue(e,t,n){return await O.invalidateWhile(k(e),async()=>{e.booted||await m(e.id);let{package:r}=await Pe(e,t),i=await p({kind:`path`,path:n},{resolveIdentity:!1});try{await Q(e,i.installablePath)}finally{await i.cleanup()}return{package:r}})}export{N as a,z as c,A as d,S as f,v as g,_ as h,F as i,K as l,y as m,q as n,W as o,fe as p,P as r,j as s,pe as t,G as u};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n}from"./sdk-contracts.js";import{K as r}from"./sdk-batch-runner.js";import{_ as i,n as a,o,r as s,s as c}from"./sdk-android-adb.js";import{n as l}from"./shell-quote.js";import{t as u}from"./timeouts.js";import"./sdk.js";import{i as ee,n as d,o as te,t as ne}from"./boot-diagnostics.js";const re=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],f=/\bApplication Not Responding:\s*([A-Za-z0-9_.]+)/i,ie=/([^{}]*\bis(?:n't| not)\s+responding[^{}]*)/i,ae=/\b([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+)\b/;function p(e){let t=new Set;for(let n of e.split(`
2
+ `)){let e=n.trim();if(!e)continue;let r=e.split(/\s+/)[0]??``;if(!r.includes(`/`))continue;let i=r.split(`/`)[0]??``;i.includes(`.`)&&i&&t.add(i)}return Array.from(t)}function m(e){return e.split(`
3
+ `).map(e=>{let t=e.trim();return t.startsWith(`package:`)?t.slice(8):t}).filter(Boolean)}function oe(e){return se(e,(e,t)=>ce(e,t))}function se(e,t){let n=e.split(`
4
+ `);for(let e of re)for(let r of n){let n=r.indexOf(e);if(n===-1)continue;let i=r.trim(),a=t(r.slice(n+e.length),i);if(a)return a}return null}function ce(e,t){let n=e.split(`}`)[0]?.trim()??e.trim(),r=f.exec(n);if(r){let e=r[1];return{package:e,focusedWindow:`Application Not Responding: ${e}`,raw:t}}let i=ie.exec(n);if(!i)return null;let a=i[1];if(a===void 0)return null;let o=a.trim().replace(/\s+/g,` `),s=ae.exec(o)?.[1];return{...s?{package:s}:{},focusedWindow:o,raw:t}}function h(e={}){let t=e.ttlMs??3e4,n=e.nowMs??Date.now,r=new Map,i=e=>{let t=le(e);for(let e of r.keys())e.startsWith(t)&&r.delete(e)};return{get(e,t){let i=g(e,t),a=r.get(i);if(a){if(a.expiresAtMs<=n()){r.delete(i);return}return a.value}},set(e,i,a){return r.set(g(e,i),{value:a,expiresAtMs:n()+t}),a},clear(e){i(e)},async invalidateWhile(e,t){i(e);try{return await t()}finally{i(e)}}}}function g(e,t){return[e.platform,e.deviceId,e.variant??``,t.trim().toLowerCase()].join(`\0`)}function le(e){return[e.platform,e.deviceId,``].join(`\0`)}var _=e({isClipboardShellUnsupported:()=>y,runAndroidAdb:()=>v});async function v(e,t,n){return await o(e)(t,n)}function y(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`no shell command implementation`)||n.includes(`unknown command`)}var ue=e({classifyAndroidAppTarget:()=>b,formatAndroidInstalledPackageRequiredMessage:()=>pe});const de=/\.(?:apk|aab)$/i,fe=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function b(e){let t=e.trim();return t.length===0?`other`:de.test(t)?t.includes(`/`)||t.includes(`\\`)||t.startsWith(`.`)||t.startsWith(`~`)||!x(t)?`binary`:`package`:x(t)?`package`:`other`}function x(e){return fe.test(e)}function pe(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}var me=e({androidAppsDiscoveryHint:()=>S,inferAndroidAppName:()=>E,resolveAndroidApp:()=>T,withAndroidAppResolutionCacheInvalidated:()=>ge});const he={settings:{type:`intent`,value:`android.settings.SETTINGS`}},S=`Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.`,C=h();function w(e){return{platform:`android`,deviceId:e.id,variant:e.target??``}}async function ge(e,t){return await C.invalidateWhile(w(e),t)}async function T(e,n){let r=n.trim();if(b(r)===`package`)return{type:`package`,value:r};let i=he[r.toLowerCase()];if(i)return i;let a=w(e),o=C.get(a,r);if(o)return o;let s=(await v(e,[`shell`,`pm`,`list`,`packages`])).stdout.split(`
5
+ `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase())),c=s[0];if(c!==void 0&&s.length===1)return C.set(a,r,{type:`package`,value:c});throw s.length>1?new t(`INVALID_ARGS`,`Multiple packages matched "${n}"`,{matches:s,hint:`Run agent-device apps --platform android to see the exact installed package names before retrying open.`}):new t(`APP_NOT_INSTALLED`,`No package found matching "${n}"`,{hint:S})}function E(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(`.`).flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),r=n[n.length-1]??e;for(let e=n.length-1;e>=0;--e){let i=n[e];if(i&&!t.has(i)){r=i;break}}return r.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}var _e=e({waitForAndroidBoot:()=>O});const D=1e4;async function ve(e,t=D,n){return await i(`adb`,[`-s`,e,`shell`,`getprop`,`sys.boot_completed`],{allowFailure:!0,signal:n,timeoutMs:t})}async function O(e,n=6e4,r){let i=ee.fromTimeoutMs(n),a=Math.min(1e3,Math.max(50,Math.floor(n/20))),o=Math.max(1,Math.ceil(n/a)),s,c=!1;try{await te(async({deadline:a})=>{if(a?.isExpired())throw c=!0,new t(`COMMAND_FAILED`,`Android boot deadline exceeded`,{serial:e,timeoutMs:n,elapsedMs:i.elapsedMs(),message:`timeout`});let o=Math.max(1e3,a?.remainingMs()??n),l=await ve(e,Math.min(o,D),r);if(s=l,l.stdout.trim()!==`1`)throw new t(`COMMAND_FAILED`,`Android device is still booting`,{serial:e,stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode})},{maxAttempts:o,baseDelayMs:a,maxDelayMs:a,jitter:0,shouldRetry:e=>{let t=d({error:e,stdout:s?.stdout,stderr:s?.stderr,context:{platform:`android`,phase:`boot`}});return t!==`ADB_TRANSPORT_UNAVAILABLE`&&t!==`ANDROID_BOOT_TIMEOUT`}},{deadline:i,phase:`boot`,signal:r,classifyReason:e=>d({error:e,stdout:s?.stdout,stderr:s?.stderr,context:{platform:`android`,phase:`boot`}})})}catch(t){k({error:t,serial:e,timeoutMs:n,deadline:i,lastBootResult:s,timedOut:c})}}function k(e){let t=n(e.error),r=A(e,t);throw M(t,r,e.timedOut,j(e,r))}function A(e,t){let n=d({error:e.error,stdout:e.lastBootResult?.stdout,stderr:e.lastBootResult?.stderr,context:{platform:`android`,phase:`boot`}});return n===`BOOT_COMMAND_FAILED`&&t.message===`Android device is still booting`?`ANDROID_BOOT_TIMEOUT`:n}function j(e,t){return{serial:e.serial,timeoutMs:e.timeoutMs,elapsedMs:e.deadline.elapsedMs(),reason:t,hint:ne(t),stdout:e.lastBootResult?.stdout,stderr:e.lastBootResult?.stderr,exitCode:e.lastBootResult?.exitCode,...n(e.error).details??{}}}function M(e,n,r,i){return r||n===`ANDROID_BOOT_TIMEOUT`?new t(`COMMAND_FAILED`,`Android device did not finish booting in time`,i):e.code===`TOOL_MISSING`?new t(`TOOL_MISSING`,e.message,i):n===`ADB_TRANSPORT_UNAVAILABLE`?new t(`COMMAND_FAILED`,e.message,i):new t(e.code,e.message,i,e.cause)}var N=e({closeAndroidApp:()=>Z,getAndroidAppState:()=>R,getAndroidBlockingDialogFocus:()=>z,isAmStartError:()=>J,listAndroidApps:()=>Se,openAndroidApp:()=>H,openAndroidDevice:()=>X,parseAndroidLaunchComponent:()=>Y});const P=`android.intent.category.LAUNCHER`,F=`android.intent.category.LEANBACK_LAUNCHER`,I=`android.intent.category.DEFAULT`,ye=new Set([`localhost`,`127.0.0.1`,`::1`,`[::1]`]),be=[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`],[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]],xe=/(?:(mCurrentFocus=Window\{)|(mFocusedApp=AppWindowToken\{)|(mResumedActivity:)|(ResumedActivity:))(.*)$/gm;async function Se(e,t){let n=await Ce(e);return(t===`user-installed`?(await Te(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:E(e)}))}async function Ce(e){let t=new Set;for(let n of L(e,{includeFallbackWhenUnknown:!0})){let r=await v(e,[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,n],{allowFailure:!0});if(!(r.exitCode!==0||r.stdout.trim().length===0))for(let e of p(r.stdout))t.add(e)}return t}function we(e){return L(e)[0]??P}function L(e,t={}){return e.target===`tv`?[F]:e.target===`mobile`?[P]:t.includeFallbackWhenUnknown?[P,F]:[P]}async function Te(e){return m((await v(e,[`shell`,`pm`,`list`,`packages`,`-3`])).stdout)}async function R(e){for(let t of be){let n=ze((await v(e,[...t],{allowFailure:!0})).stdout??``);if(n)return n}return{}}async function z(e){return await Ee(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])}async function Ee(e,t){for(let n of t){let t=oe((await v(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}function De(e){let t;try{t=new URL(e)}catch{return null}let n=t.hostname.toLowerCase();if(!ye.has(n)||!t.port)return null;let r=Number(t.port);return Number.isInteger(r)?`tcp:${r}`:null}async function B(e,n){let r=De(n);if(!r)return;let i=s(c(e));try{await i.ensure({local:r,remote:r})}catch(e){let n={localPort:r.replace(`tcp:`,``),operation:`adb reverse ${r} ${r}`};throw e instanceof t&&Object.assign(n,{hint:e.details?.hint,diagnosticId:e.details?.diagnosticId,logPath:e.details?.logPath}),new t(`COMMAND_FAILED`,`Failed to ensure Android port reverse ${r} before opening localhost URL`,n,e)}}function V(e){return(e.launchArgs??[]).map(l)}async function H(e,t,n){e.booted||await O(e.id);let i=Pe(n),a=i.activity,o=t.trim();if(r(o)){await Oe(e,o,i);return}if(i.url!==void 0){await ke(e,t,i);return}let s=await T(e,t),c=we(e);if(s.type===`intent`){await Ae(e,s.value,i);return}if(a){await je(e,s.value,a,c,i);return}await Me(e,s.value,c,i)}async function Oe(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening a deep link URL`);await B(e,n),await v(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,l(n),...Fe(r.appBundleId),...V(r)])}async function ke(e,n,i){if(i.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening an app-bound deep link URL`);let a=i.url?.trim()??``;if(!r(a))throw new t(`INVALID_ARGS`,`Android app-bound open requires a valid URL target`);await B(e,a);let o=await Ne(e,n,`app-bound open`);await v(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,l(a),`-p`,o,...V(i)])}async function Ae(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override requires a package name, not an intent`);await v(e,[`shell`,`am`,`start`,`-W`,`-a`,n,...V(r)])}async function je(e,t,n,r,i){let a=n.includes(`/`)?n:`${t}/${n.startsWith(`.`)?n:`.${n}`}`;try{await v(e,U(a,r,i))}catch(n){throw await Ie(e,t,n),n}}async function Me(e,t,n,r){let i=await v(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,I,`-c`,n,`-p`,t,...V(r)],{allowFailure:!0});if(i.exitCode===0&&!J(i.stdout,i.stderr))return;let o=await q(e,t);if(!o)throw await G(e,t)?a(`Failed to launch ${t}`,i):W(t);await v(e,U(o,n,r))}function U(e,t,n){return[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,I,`-c`,t,`-n`,e,...V(n)]}async function Ne(e,n,r){let i=await T(e,n);if(i.type===`intent`)throw new t(`INVALID_ARGS`,`Android ${r} requires a package name, not an intent`);return i.value}function Pe(e){return typeof e==`string`?{activity:e}:e??{}}function Fe(e){let t=e?.trim();return t?[`-p`,t]:[]}function W(e){return new t(`APP_NOT_INSTALLED`,`No package found matching "${e}"`,{package:e,hint:S})}async function G(e,t){let n=await v(e,[`shell`,`pm`,`path`,t],{allowFailure:!0}),r=`${n.stdout}\n${n.stderr}`;return n.exitCode===0&&/\bpackage:/i.test(r)?!0:(K(r),!1)}async function Ie(e,n,r){if(K(r instanceof t?`${String(r.details?.stdout??``)}\n${String(r.details?.stderr??``)}`:``)||!await G(e,n))throw W(n)}function K(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function q(e,t){let n=Array.from(new Set(L(e,{includeFallbackWhenUnknown:!0})));for(let r of n){let n=await v(e,[`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=Y(n.stdout);if(i)return i}return null}function J(e,t){let n=`${e}\n${t}`;return/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(n)}function Y(e){let t=e.split(`
6
+ `).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;--e){let n=t[e];if(n===void 0||!n.includes(`/`))continue;let r=n.split(/\s+/)[0];if(r!==void 0)return r}return null}async function X(e){e.booted||await O(e.id)}async function Z(e,n){if(n.trim().toLowerCase()===`settings`){await v(e,[`shell`,`am`,`force-stop`,`com.android.settings`]),await Q(e,`com.android.settings`);return}let r=await T(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`Close requires a package name, not an intent`);await v(e,[`shell`,`am`,`force-stop`,r.value]),await Q(e,r.value)}async function Q(e,t){await Le(e,t),await Be(e,t)}async function Le(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if((await Re(e))?.package!==t)return;await u(50)}}async function Re(e){let t=await R(e);return t.package?t:null}function ze(e){for(let t of e.matchAll(xe)){let e=t[5]?.match(/\b([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+)\/([A-Za-z0-9_.$]+)/);if(e?.[1]&&e[2])return{package:e[1],activity:e[2]}}return null}async function Be(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if(!await $(e,t)&&(await u(150),!await $(e,t)))return;await u(50)}}async function $(e,t){return((await v(e,[`shell`,`pidof`,t],{allowFailure:!0})).stdout??``).trim().length>0}export{h as _,J as a,Y as c,E as d,T as f,v as g,y as h,z as i,_e as l,_ as m,Z as n,H as o,ue as p,R as r,X as s,N as t,me as u,p as v,m as y};