agent-device 0.21.22 → 0.21.24

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 (273) hide show
  1. package/README.md +6 -6
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.apk → agent-device-android-ime-helper-0.21.24.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.manifest.json → agent-device-android-ime-helper-0.21.24.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.22.manifest.json → agent-device-android-snapshot-helper-0.21.24.manifest.json} +6 -6
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
  9. package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
  10. package/apple/snapshot-bridge/README.md +9 -7
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +34 -10
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +3 -3
  20. package/dist/src/adapter.js +1 -1
  21. package/dist/src/adb.js +1 -1
  22. package/dist/src/agent-browser-lifecycle.js +1 -1
  23. package/dist/src/agent-browser-process-record.js +1 -1
  24. package/dist/src/agent-browser-provider.js +1 -1
  25. package/dist/src/agent-device-client.js +2 -2
  26. package/dist/src/alert-runtime.js +1 -1
  27. package/dist/src/alert.js +1 -1
  28. package/dist/src/android-adb.d.ts +3 -2
  29. package/dist/src/android-input-ownership.js +1 -1
  30. package/dist/src/app-backend.js +1 -1
  31. package/dist/src/app-inventory.d.ts +4 -0
  32. package/dist/src/app-launch.js +1 -1
  33. package/dist/src/app-lifecycle.js +1 -1
  34. package/dist/src/app-log-reconnect.js +1 -1
  35. package/dist/src/app-log-runtime2.js +3 -3
  36. package/dist/src/app-resolution.js +2 -2
  37. package/dist/src/app-state-runtime.d.ts +15 -0
  38. package/dist/src/apple-runner-platform.js +1 -1
  39. package/dist/src/application-lifecycle-interaction.js +1 -1
  40. package/dist/src/aws-device-farm-connection.js +1 -0
  41. package/dist/src/back-mode.js +1 -1
  42. package/dist/src/backend-snapshot-options.js +1 -1
  43. package/dist/src/browserstack-connection.js +1 -0
  44. package/dist/src/browserstack-device-features.js +1 -0
  45. package/dist/src/browserstack.js +1 -0
  46. package/dist/src/cache.js +1 -1
  47. package/dist/src/cli-config.js +1 -1
  48. package/dist/src/cli-help.js +35 -19
  49. package/dist/src/cli-runner.js +1 -1
  50. package/dist/src/cli.js +3 -4
  51. package/dist/src/client-companion-tunnel.js +1 -0
  52. package/dist/src/client-metro-companion.js +1 -1
  53. package/dist/src/client-metro.js +1 -1
  54. package/dist/src/client-options.js +3 -3
  55. package/dist/src/client-types.d.ts +7 -5
  56. package/dist/src/cloud-artifacts.d.ts +9 -2
  57. package/dist/src/code-signature-cache.js +1 -1
  58. package/dist/src/command-metadata.js +1 -1
  59. package/dist/src/command-schema.js +1 -1
  60. package/dist/src/command-tools.js +2 -2
  61. package/dist/src/connection-runtime.js +1 -1
  62. package/dist/src/connection-verification.js +1 -0
  63. package/dist/src/connection.js +5 -5
  64. package/dist/src/contracts.d.ts +1 -1
  65. package/dist/src/daemon-client-lease-beat.js +1 -1
  66. package/dist/src/daemon-client-lifecycle.js +1 -1
  67. package/dist/src/daemon-client-transport.js +1 -1
  68. package/dist/src/daemon-http.js +1 -1
  69. package/dist/src/daemon-policy-file.js +1 -1
  70. package/dist/src/daemon-registration-owner.js +1 -1
  71. package/dist/src/device-claim-inspection.js +1 -1
  72. package/dist/src/device-input-state.d.ts +2 -15
  73. package/dist/src/device-readiness-runtime.js +1 -1
  74. package/dist/src/device-selection-resolver.js +1 -1
  75. package/dist/src/device-session.js +3 -1
  76. package/dist/src/device.js +1 -1
  77. package/dist/src/device2.js +1 -1
  78. package/dist/src/device3.js +1 -1
  79. package/dist/src/dispatch-resolve.js +3 -3
  80. package/dist/src/doctor-facade.js +1 -1
  81. package/dist/src/durable-capture-resource.js +1 -1
  82. package/dist/src/durable-resource.js +1 -1
  83. package/dist/src/exec.js +1 -1
  84. package/dist/src/file.js +1 -1
  85. package/dist/src/find.js +1 -1
  86. package/dist/src/finders.js +1 -1
  87. package/dist/src/format.js +2 -1
  88. package/dist/src/gesture-admission.js +1 -1
  89. package/dist/src/gesture-plan-types.d.ts +2 -5
  90. package/dist/src/gesture-runtime.js +1 -1
  91. package/dist/src/helper.js +2 -2
  92. package/dist/src/human-control.js +1 -1
  93. package/dist/src/ime-rebind.js +1 -0
  94. package/dist/src/ime-settings-record.js +1 -0
  95. package/dist/src/ime-state.js +1 -0
  96. package/dist/src/index.d.ts +3 -3
  97. package/dist/src/input-actions.js +1 -1
  98. package/dist/src/input-actions2.js +1 -1
  99. package/dist/src/install-source2.js +1 -1
  100. package/dist/src/instance-client.js +1 -1
  101. package/dist/src/interaction-positionals.js +1 -1
  102. package/dist/src/interaction-ref-policy.js +1 -1
  103. package/dist/src/interaction.js +1 -1
  104. package/dist/src/interaction2.js +1 -1
  105. package/dist/src/interactor.js +5 -5
  106. package/dist/src/interactors.js +1 -1
  107. package/dist/src/internal/bin.js +1 -1
  108. package/dist/src/internal/daemon.js +1 -1
  109. package/dist/src/inventory2.js +1 -1
  110. package/dist/src/ios-client.js +4 -4
  111. package/dist/src/ios-snapshot-acquisition.js +1 -1
  112. package/dist/src/ios-snapshot-engine.js +1 -1
  113. package/dist/src/ios-snapshot-runtime.js +1 -1
  114. package/dist/src/launch-confirmation.js +1 -1
  115. package/dist/src/lease-scope.js +1 -1
  116. package/dist/src/lease.js +1 -1
  117. package/dist/src/limrun.d.ts +4 -555
  118. package/dist/src/load.js +1 -1
  119. package/dist/src/local-interactor-operation-set.js +1 -1
  120. package/dist/src/log-stream.js +33 -0
  121. package/dist/src/managed-device-scope.js +1 -1
  122. package/dist/src/manifest.js +1 -0
  123. package/dist/src/mechanics.js +16 -16
  124. package/dist/src/mobile-snapshot-semantics.js +1 -1
  125. package/dist/src/node-http.js +1 -0
  126. package/dist/src/observation.js +1 -2
  127. package/dist/src/overlay.js +3 -3
  128. package/dist/src/owner-identity.js +3 -3
  129. package/dist/src/perf-facade.js +1 -1
  130. package/dist/src/perf-runtime-plan.js +1 -1
  131. package/dist/src/perf-target.js +1 -1
  132. package/dist/src/physical-device-control.js +1 -1
  133. package/dist/src/platform-request-scope.js +1 -1
  134. package/dist/src/platform-runtime-app-log-process.js +1 -1
  135. package/dist/src/platform-runtime-open-target.js +1 -1
  136. package/dist/src/platform-runtime-operation-host.js +4 -4
  137. package/dist/src/platform-runtime-runtime-hints.js +1 -1
  138. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  139. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
  140. package/dist/src/platform-runtime-unavailable.js +1 -1
  141. package/dist/src/platform-runtime.js +1 -1
  142. package/dist/src/platform-runtime2.js +1 -1
  143. package/dist/src/plugin.js +1 -0
  144. package/dist/src/plugins/webdriver.d.ts +111 -0
  145. package/dist/src/plugins/webdriver.js +1 -0
  146. package/dist/src/plugins.d.ts +2 -1
  147. package/dist/src/plugins2.js +1 -1
  148. package/dist/src/process-exit.js +1 -1
  149. package/dist/src/process.js +1 -1
  150. package/dist/src/provider-credential-fingerprint.js +1 -1
  151. package/dist/src/provider-device-admission.js +1 -1
  152. package/dist/src/provider-device-runtime.d.ts +556 -0
  153. package/dist/src/provider-policy.js +1 -0
  154. package/dist/src/provider-profile-fields.js +1 -1
  155. package/dist/src/provider-webdriver.js +1 -2
  156. package/dist/src/providers.js +1 -1
  157. package/dist/src/proxy.js +2 -2
  158. package/dist/src/react-devtools.js +2 -0
  159. package/dist/src/react-native.js +1 -1
  160. package/dist/src/record-runtime.js +1 -1
  161. package/dist/src/record-trace.js +1 -1
  162. package/dist/src/recording.js +1 -1
  163. package/dist/src/registry.js +24 -24
  164. package/dist/src/remote-bridge.js +1 -0
  165. package/dist/src/remote-config-core.js +1 -0
  166. package/dist/src/remote-config.js +1 -1
  167. package/dist/src/remote-config2.js +1 -1
  168. package/dist/src/remote-connection-state.js +1 -0
  169. package/dist/src/replay.js +2 -2
  170. package/dist/src/request-admission.js +1 -1
  171. package/dist/src/request-runtime-binding.js +1 -1
  172. package/dist/src/result-serialization.js +1 -1
  173. package/dist/src/retry.js +1 -1
  174. package/dist/src/retry2.js +1 -0
  175. package/dist/src/runner-artifact-manifest.js +1 -1
  176. package/dist/src/runner-cache-metadata.js +2 -3
  177. package/dist/src/runner-cache-retention.js +1 -0
  178. package/dist/src/runner-cache-trim.js +1 -0
  179. package/dist/src/runner-client.js +1 -1
  180. package/dist/src/runner-dev-tools-security.js +1 -1
  181. package/dist/src/runner-device-readiness.js +1 -1
  182. package/dist/src/runner-device-set.js +1 -0
  183. package/dist/src/runner-disposal.js +1 -1
  184. package/dist/src/runner-error-classification.js +1 -1
  185. package/dist/src/runner-exchange.js +1 -1
  186. package/dist/src/runner-lease.js +1 -0
  187. package/dist/src/runner-operations-facade.js +1 -1
  188. package/dist/src/runner-session-types.js +1 -1
  189. package/dist/src/runner-start-budget.js +1 -1
  190. package/dist/src/runner-toolchain-probe.js +2 -0
  191. package/dist/src/runner.js +1 -1
  192. package/dist/src/runtime-deployment.js +1 -0
  193. package/dist/src/runtime.js +1 -1
  194. package/dist/src/runtime10.js +1 -2
  195. package/dist/src/runtime11.js +2 -0
  196. package/dist/src/runtime2.js +2 -5
  197. package/dist/src/runtime3.js +5 -1
  198. package/dist/src/runtime4.js +1 -5
  199. package/dist/src/runtime5.js +5 -1
  200. package/dist/src/runtime6.js +1 -1
  201. package/dist/src/runtime7.js +1 -1
  202. package/dist/src/runtime8.js +1 -1
  203. package/dist/src/runtime9.js +1 -1
  204. package/dist/src/screen-recording-transport.js +1 -1
  205. package/dist/src/screenshot-density.js +1 -1
  206. package/dist/src/screenshot-overlay-draw.js +1 -1
  207. package/dist/src/screenshot3.js +2 -2
  208. package/dist/src/script.js +1 -1
  209. package/dist/src/scroll-gesture.js +1 -1
  210. package/dist/src/sdk-batch.js +2 -2
  211. package/dist/src/sdk-contracts.d.ts +25 -33
  212. package/dist/src/sdk-contracts.js +2 -2
  213. package/dist/src/sdk-device.js +1 -1
  214. package/dist/src/sdk-finders.d.ts +1 -1
  215. package/dist/src/sdk-finders.js +1 -1
  216. package/dist/src/sdk-remote-config.d.ts +4 -0
  217. package/dist/src/sdk-remote-config.js +1 -1
  218. package/dist/src/sdk-selectors.d.ts +1 -1
  219. package/dist/src/sdk-selectors.js +1 -1
  220. package/dist/src/selection.js +0 -0
  221. package/dist/src/selector-pipeline-policy.js +1 -1
  222. package/dist/src/selector-runtime.js +1 -1
  223. package/dist/src/selectors.js +1 -1
  224. package/dist/src/server.js +2 -2
  225. package/dist/src/session-snapshot.js +1 -1
  226. package/dist/src/session2.js +5 -5
  227. package/dist/src/simctl.js +1 -1
  228. package/dist/src/simulator-boot.js +1 -1
  229. package/dist/src/simulator-state.js +1 -1
  230. package/dist/src/simulator.js +1 -1
  231. package/dist/src/snapshot-capture-annotations.js +1 -1
  232. package/dist/src/snapshot-desktop-projection.js +1 -1
  233. package/dist/src/snapshot-private-evidence.js +1 -0
  234. package/dist/src/snapshot-runtime-binding.js +1 -1
  235. package/dist/src/snapshot-runtime.js +1 -1
  236. package/dist/src/snapshot-state.js +1 -1
  237. package/dist/src/snapshot4.js +1 -1
  238. package/dist/src/src2.js +1 -1
  239. package/dist/src/src3.js +1 -1
  240. package/dist/src/src4.js +1 -1
  241. package/dist/src/src5.js +1 -1
  242. package/dist/src/src6.js +1 -1
  243. package/dist/src/src7.js +1 -1
  244. package/dist/src/src8.js +20 -20
  245. package/dist/src/store.js +1 -1
  246. package/dist/src/target-evidence.js +1 -1
  247. package/dist/src/text-entry-focus.js +1 -1
  248. package/dist/src/tool-provider2.js +1 -1
  249. package/dist/src/touch-runtime2.js +1 -1
  250. package/dist/src/tree.js +1 -1
  251. package/dist/src/type-text-runtime.js +1 -1
  252. package/dist/src/video.js +1 -1
  253. package/package.json +24 -16
  254. package/server.json +2 -2
  255. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.22.apk.sha256 +0 -1
  256. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk +0 -0
  257. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk.sha256 +0 -1
  258. package/dist/src/capabilities.js +0 -1
  259. package/dist/src/compatibility-policy.js +0 -1
  260. package/dist/src/daemon-artifacts.js +0 -1
  261. package/dist/src/device-claim-rule.js +0 -1
  262. package/dist/src/human-control-contract.js +0 -1
  263. package/dist/src/prepare-kind.js +0 -1
  264. package/dist/src/provider-device-runtimes.js +0 -1
  265. package/dist/src/screen-recording-admission-ledger.js +0 -1
  266. package/dist/src/screenshot-runtime.js +0 -1
  267. package/dist/src/session-routing.js +0 -1
  268. package/dist/src/session-runtime-admission.js +0 -1
  269. package/dist/src/session-stream.js +0 -27
  270. package/dist/src/timeouts.js +0 -1
  271. package/dist/src/touch-reference-frame.js +0 -1
  272. package/dist/src/vars.js +0 -2
  273. package/dist/src/viewport.js +0 -1
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{F as t,K as n,P as r}from"./sdk-contracts.js";import{m as i}from"./sdk-device.js";import{t as a}from"./parser.js";import{A as o,B as s,D as c,F as l,G as u,H as d,L as f,N as p,O as m,R as ee,S as te,T as h,W as ne,_ as re,a as ie,b as g,d as ae,f as _,g as oe,m as se,n as ce,p as le,s as ue,u as v,v as y,w as de,y as fe,z as pe}from"./host.js";import{d as me,r as he}from"./apple-runner-platform.js";import{_ as ge,a as _e,b as ve,c as ye,d as be,f as xe,g as Se,h as Ce,l as we,m as Te,n as Ee,p as De,r as Oe,t as ke,v as Ae,x as je,y as Me}from"./runner-cache-metadata.js";import{S as Ne,_ as Pe,g as Fe,h as Ie,m as Le,n as b,u as Re,v as x}from"./runner-session-types.js";import{P as ze,r as Be}from"./runner-error-classification.js";import Ve from"node:crypto";import S from"node:fs";import He from"node:os";import C from"node:path";const w=new Set;function Ue(e){return C.join(e,Ee)}function We(e,t){S.mkdirSync(e,{recursive:!0}),S.writeFileSync(Ue(e),`${JSON.stringify(t,null,2)}\n`)}async function Ge(e,t){if(e.cache===`external`){k(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}w.add(e.derived),await u({acquire:()=>Ke(e.derived),task:async()=>{k(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),O(e.derived),D(e.derived)}})}async function Ke(e){return await ce({lockDirPath:qe(e),owner:{pid:process.pid,startTime:m(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,description:`iOS runner cache lock`})}function qe(e){return C.join(C.dirname(e),`${C.basename(e)}.lock`)}function Je(e,t){!$e()&&!t&&!w.has(e)||(k(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),O(e),D(e),w.delete(e))}async function T(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return We(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(k(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function E(e,t){if(e)throw new r(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:e.reason,refusingPath:e.path??t,...e.reason===`root_unusable`?{}:{resolvesTo:e.target},derived:t,hint:`Inspect ${e.path??t} under ${t}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function D(e){try{if(!S.existsSync(e))return;if(C.basename(e)!==`derived`){S.rmSync(e,{recursive:!0,force:!0});return}for(let t of S.readdirSync(e,{withFileTypes:!0}))Xe(t.name)&&S.rmSync(C.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Ye=new Set([Ee,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Xe(e){return Ye.has(e)}function Ze(e){try{let t=JSON.parse(S.readFileSync(Ue(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function Qe(e,t){let n=Ze(e);return n?ve(Oe(n))===ve(Oe(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:_e(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function $e(){return re(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function O(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!et(e))throw new r(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:e,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${C.join(_(),`.tmp`)}.`})}function et(e){let t=C.resolve(_(),`.tmp`),n=C.relative(t,C.resolve(e));return n!==``&&!n.startsWith(`..`)&&!C.isAbsolute(n)}async function tt(e){let t=Qe(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function nt(e,t){k(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function k(e,t,n){v({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const rt=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),it=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function at(e,t,n){if(!i(e))return;if(t.length===0)throw new r(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:n});let a=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of a)if(!S.existsSync(e))throw new r(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:n});for(let e of a)await lt(e)||await ot(e,n)}async function ot(e,n){try{let t=C.join(e,`Contents`,`Frameworks`),n=S.existsSync(t)?S.readdirSync(t).sort().map(e=>C.join(t,e)):[];for(let e of n)await p(`codesign`,[...it,e]);await p(`codesign`,[...it,e])}catch(r){let i=t(r,`COMMAND_FAILED`);throw st(e,n,i.message,i.details)}if(!await lt(e))throw st(e,n,`Product still fails code signature verification after re-signing`)}function st(e,t,n,i){return new r(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:n,details:i})}function ct(e){if(!(e instanceof r))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&rt.has(t)}async function lt(e){return(await p(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const ut=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function dt(e){let t=await mt(e);if(!t||t.length===0)return null;let n=C.dirname(e),r=new Set,i=ft(t,n);for(let e of i.testRootPaths){if(!S.existsSync(e))return null;r.add(e)}for(let e of pt(i)){if(!e)return null;r.add(e)}return Array.from(r)}function ft(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(C.join(t,e));let o=xt(e);o&&r.add(C.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function pt(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>S.existsSync(C.join(e,t)));return n?C.join(n,t):null})}async function mt(e){let t=await h(e);if(t)return ht(t);if(process.platform===`darwin`)return null;try{return yt(S.readFileSync(e,`utf8`))}catch{return null}}function ht(e){let t=new Set;for(let n of[e,...gt(e),..._t(e)])for(let e of vt(n))t.add(e);return Array.from(t)}function gt(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!g(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(g))}return n}function _t(e){return Object.values(e).filter(e=>g(e)&&`TestBundlePath`in e)}function vt(e){let t=new Set;for(let[n,r]of Object.entries(e))if(ut.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function yt(e){return bt(a(e))}function bt(e){let t=new Set;return d(e,(e,n)=>{if(ut.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function xt(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const St=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function Ct(e){await wt(Lt(e))}async function wt(e){let t=e.filter(Ft);if(t.length===0)return;let n=e.filter(e=>A(e)&&!It(e));for(let e of t){let t=Pt(e,n);t&&await Tt(t,e)}}async function Tt(e,t){let n=Et(e,t),r=await Dt(e,t);(n||r)&&(await At(t),Nt(t))}function Et(e,t){let n=!1;for(let r of S.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!Mt(r.name)||jt(C.join(e,r.name),C.join(t,r.name))&&(n=!0);return n}async function Dt(e,t){let n=C.join(e,`Info.plist`),r=C.join(t,`Info.plist`),i=await h(n),a=await h(r);if(!i||!a)return!1;let o=Ot(i,a);if(o.length===0)return!1;for(let e of o)await kt(r,e.key,e.value,e.shouldInsert);return!0}function Ot(e,t){return St.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function kt(e,t,n,r){o(await p(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function At(e){o(await p(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function jt(e,t){if(S.existsSync(t)){let n=S.readFileSync(e),r=S.readFileSync(t);return!n.equals(r)&&(S.copyFileSync(e,t),!0)}return S.copyFileSync(e,t),!0}function Mt(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function Nt(e){let t=new Date;S.utimesSync(e,t,t)}function Pt(e,t){let n=C.dirname(e);return t.find(e=>C.dirname(e)===n&&C.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>C.dirname(t)===n&&t!==e)??null}function Ft(e){return A(e)&&It(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function It(e){return C.basename(e).endsWith(`-Runner.app`)}function A(e){return C.basename(e).endsWith(`.app`)}function Lt(e){if(!S.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of S.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=C.join(e,r.name);if(A(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const j=`AgentDeviceRunner.env`,Rt=`session`,zt=`${N(`${j}.${Rt}`)}-`;function Bt(e){return M(`${Rt}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function Vt(e){return`${zt}${N(M(e))}-[0-9]`}function Ht(e){let t=e?C.basename(e):``;if(t.startsWith(`${j}.`))return N(t)}function M(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function N(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Ut={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function Wt(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?C.resolve(i):C.dirname(e);S.mkdirSync(a,{recursive:!0});let o=M(n),s=C.join(a,`${j}.${o}.json`),c=C.join(a,`${j}.${o}.xctestrun`),l=await Gt(e);return Yt(l,e=>qt(e,t)),Jt(l),await Kt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function Gt(e){let t=await p(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0||!t.stdout.trim())throw new r(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(t){throw new r(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(t)})}}async function Kt(e,t,n){S.writeFileSync(t,JSON.stringify(e,null,2)),o(await p(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function qt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function Jt(e){Yt(e,e=>Object.assign(e,Ut),{requireTestBundlePath:!0})}function Yt(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||Xt(e.TestTargets,t,n);for(let n of Object.values(e)){let e=Zt(n,{requireTestBundlePath:!0});e&&t(e)}}function Xt(e,t,n){if(Array.isArray(e))for(let r of e){let e=Zt(r,n);e&&t(e)}}function Zt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const Qt=new Map,P=new Set;function $t(e,t,n){let r={deviceId:e,requestId:n,child:t};P.add(r),t.on(`close`,()=>{P.delete(r)})}function en(e){return nn(e).map(e=>e.child)}function tn(e){return nn(e).filter(e=>!rn(e.requestId)).map(e=>e.child)}function nn(e){return[...P].filter(t=>e===void 0||t.deviceId===e)}function rn(e){if(!e)return!1;let t=le(e);return t!==void 0&&!t.aborted}function an(e){for(let t of P)t.child===e&&P.delete(t)}async function on(e,t){let n=sn(t);if(n)return n;let r=_(),i=we(e,r,t.budget),a=Ce(e,i);return await ne(Qt,a,async()=>await u({acquire:()=>Ke(a),task:()=>ln({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function sn(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let n=C.resolve(t);if(!S.existsSync(n))throw new r(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:n});let i=e.iosXctestDerivedDataPath?.trim(),a=i?C.resolve(i):cn(n);return k(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:n}),{xctestrunPath:n,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function cn(e){let t=Ve.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return C.join(He.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function ln(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;Je(a,e.forceRebuild);let o=await tt({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await un({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&nt(o,a),o.reason!==`cache_metadata_missing`&&(O(a),D(a)),await dn({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function un(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await fn(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:Te(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function dn(e){let{device:t,options:n,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=je(i);if(!S.existsSync(l))throw new r(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=ye(n.budget,`runner_xctestrun_build`),d=Date.now();ae({type:`command`,status:`progress`,message:`Building Apple runner...`}),await vn(t,l,o,n,u);let f=Math.max(0,Date.now()-d),p=mn(o,t);if(!p)throw new r(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await dt(p);if(!m)throw new r(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await at(t,m,p),await wt(m),E(await T(o,a,p,m),o),k(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,cacheKey:Te(a),artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function fn(e,t,n,r){try{return await at(e,r.productPaths,r.xctestrunPath),E(await T(t,n,r.xctestrunPath,r.productPaths),t),k(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!ct(e))throw e;return k(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function pn(e){try{let t=_(),n=we(e,t);return(await tt({derived:Ce(e,n),expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function mn(e,t){let n=hn(e);return n.length===0?null:(n.sort((e,n)=>gn(e,n,t)),n[0]?.path??null)}function hn(e){if(!S.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=S.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=C.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=S.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function gn(e,t,n){if(n){let r=_n(t.path,n)-_n(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function _n(e,t){let n=0,r=e.toLowerCase();C.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${C.sep}macos${C.sep}`)&&(n-=5e3);let i=me(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}async function vn(e,t,i,a,o){let s=De(process.env),c=Me(process.env,e.kind===`device`,e),u=e.kind===`device`?[`-allowProvisioningUpdates`]:[],d=ge(),f=be(process.env),p=Ae();try{await l(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,Se(e),`1`,...Pe(e,he(e)),`-derivedDataPath`,i,...xe(i),...d,...f,...p,...s,...u,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:t=>{$t(e.id,t,a.requestId)},onStdoutChunk:e=>{Ne(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{Ne(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(t){if(n(t))throw t;let i=t instanceof r?t:new r(`COMMAND_FAILED`,String(t)),o=Le(e),{reason:s,hint:c,matched:l}=Be(new r(i.code,i.message,{...i.details,...o})),u=oe(i),d=`xcodebuild build-for-testing failed`;throw new r(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?Fe(d,e,o):d,{reason:s,error:i.message,details:i.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}const F=process.pid;let yn;function I(){return yn??={value:m(process.pid)},yn.value}function L(){return Zn(F,I())}function bn(e){let t=H(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:L(),ownerPid:F,ownerStartTime:I(),ownerStateDir:Dn(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?m(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...Kn(Ie(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function xn(e,t){return await u({acquire:()=>ce({lockDirPath:`${B(e)}.lock`,owner:{pid:F,startTime:I(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function R(e){try{return Wn(JSON.parse(S.readFileSync(B(e),`utf8`)),e)}catch{return null}}function z(e){if(!e)return{type:`empty`};if(e.ownerToken===L())return{type:`owned`,lease:e};let t=ue({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function Sn(e,t,n){let i=e.id,a=z(R(i));if(a.type===`empty`){await t.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(Cn(a.lease)){await G(a.lease,`same-state-dir`,t);return}if(wn(a.lease,e)){await G(a.lease,`device-claim-takeover`,t);return}if(Tn(a.lease,n)){await G(a.lease,`logical-lease-takeover`,t);return}throw new r(`COMMAND_FAILED`,n?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:n,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:On(a.lease,n)})}await G(a.lease,a.type,t)}function Cn(e){let t=Dn();return!t||!e.ownerStateDir?!1:C.resolve(t)===C.resolve(e.ownerStateDir)}function wn(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&se(t)}function Tn(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:En(t.deviceKey,e.deviceId)}function En(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function Dn(){return te()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function On(e,t){let n=kn(e),r=An(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function kn(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function An(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${jn(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function jn(e,t){return`${e}=${ee(t)}`}function Mn(e){let t=z(R(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Nn(e){let t=Mn(e);return t.type===`adoptable`?t.lease:null}function Pn(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Fn(e,t){let n=z(R(e));n.type===`owned`&&await G(n.lease,`owned`,t)}async function In(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Hn(e);await Promise.all(n.map(async e=>{await G(e,`owned`,t)}))}function Ln(e){return R(e)?.ownerToken??null}function Rn(e){e&&Bn({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function zn(e){let t=B(e.deviceId);S.mkdirSync(C.dirname(t),{recursive:!0}),de({destination:t,contents:JSON.stringify(e,null,2)})}function Bn(e){let t=R(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{S.unlinkSync(B(e.deviceId))}catch{}}function B(e){return C.join(Vn(),`${Qn(e)}.json`)}function Vn(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?C.resolve(e):C.join(He.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Hn(e){let t,n=Vn();try{t=S.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=Un(C.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function Un(e){try{let t=JSON.parse(S.readFileSync(e,`utf8`)),n=V(t.deviceId);return n?Wn(t,n):null}catch{return null}}function Wn(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=Gn(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:U(n.ownerStartTime),ownerStateDir:U(n.ownerStateDir)??void 0,runnerPid:W(n.runnerPid),runnerStartTime:U(n.runnerStartTime),runnerLogPath:H(n.runnerLogPath),cacheKey:H(n.cacheKey),...Kn(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Gn(e){let t={ownerToken:V(e.ownerToken),ownerPid:W(e.ownerPid),sessionId:V(e.sessionId),port:W(e.port),xctestrunPath:V(e.xctestrunPath),jsonPath:V(e.jsonPath),createdAtMs:qn(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function V(e){return typeof e==`string`&&e.length>0?e:null}function H(e){return V(e)??void 0}function Kn(e){let t=V(e);return t?{simulatorSetPath:t}:{}}function U(e){return typeof e==`string`?e:null}function W(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function qn(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function G(e,t,n){v({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(Yn(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(Yn(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),Rn(e)}function Jn(e,t){return y(t)&&K(e,t)}function Yn(e){let t=e.runnerPid??void 0;if(!(!t||!y(t))){if(K(e,t))return t;v({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function K(e,t){return e.runnerStartTime?m(t)===e.runnerStartTime:Xn(c(t))}function Xn(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function Zn(e,t){let n=Ve.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function Qn(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var $n=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>er,abortRunnerSessionsAndPrepProcesses:()=>ir,cleanupOwnedIosRunnerLease:()=>rr,disposeRunnerSession:()=>nr,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>q,stopRunnerPrepProcesses:()=>ar,stopRunnerPrepProcessesWithoutActiveOwner:()=>or});const er=1e3,tr=2e3,q={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:hr,cleanupTempFile:x};async function nr(e,t={}){b(e,`draining`);let n=!1;if(t.graceful!==!1)n=await cr(e);else if(i(e.device)){await J([e]),await Y(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await lr(e,t.waitTimeoutMs??1e4),mr(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Y(e,t)}async function rr(e){await Fn(e,q)}async function ir(e){let t=en(),n=e.filter(e=>i(e.device)),r=e.filter(e=>!i(e.device));for(let t of e)b(t,`draining`);await Z(r,`SIGINT`),await Q(t,`SIGINT`),await Z(r,`SIGTERM`),await Q(t,`SIGTERM`),await Z(r,`SIGKILL`),await Q(t,`SIGKILL`),await J(n),await Promise.allSettled(e.map(async e=>{await Y(e)}))}async function ar(e){await sr(en(e))}async function or(e){await sr(tn(e))}async function sr(e){await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{an(e)}}))}async function cr(e){try{return await Re(e.device,e.port,ze({command:`shutdown`}),void 0,15e3),!1}catch{return i(e.device)?(await J([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function lr(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!mr(e.child.pid)}finally{n&&clearTimeout(n)}}async function J(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await ur(e,5e3);await Z(t,`SIGTERM`),await Z(await ur(t,2e3),`SIGKILL`)}async function ur(e,t){let n=await Promise.all(e.map(async e=>await lr(e,t)));return e.filter((e,t)=>!n[t])}async function Y(e,t={}){await dr(e,t),x(e.xctestrunPath),x(e.jsonPath),b(e,`stopped`)}async function dr(e,t){let n=async()=>{if(!fr(e))try{await pr(e.device)}finally{Rn(e.lease)}};if(t.leaseLockHeld){await n();return}try{await xn(e.deviceId,n)}catch(t){v({level:`warn`,phase:`ios_runner_disposal_lease_lock_unavailable`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:t instanceof Error?t.message:String(t)}})}}function fr(e){let t=Ln(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function pr(e){e.kind===`simulator`&&await Promise.allSettled(ke.map(async t=>{try{await f(ie(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:tr})}catch(n){v({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:tr,error:n instanceof Error?n.message:String(n)}})}}))}function mr(e){return e?X(e)||fe(e):!1}function X(e){return e?y(e):!1}async function Z(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&an(e)}))}async function $(e,t){if(!e||e<=0)return;s(e,t),pe([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await p(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function hr(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${Ht(e.xctestrunPath)??Vt(t)}`;for(let e of[`TERM`,`KILL`])try{await p(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){v({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{T as A,pn as C,dt as D,Ct as E,Ge as O,mn as S,Wt as T,L as _,X as a,zn as b,ar as c,bn as d,In as f,Nn as g,Mn as h,nr as i,E as k,or as l,Sn as m,ir as n,q as o,Jn as p,rr as r,$n as s,er as t,Pn as u,K as v,Bt as w,on as x,xn as y};
1
+ import{r as e}from"./rolldown-runtime.js";import{F as t,I as n,K as r,P as i}from"./sdk-contracts.js";import{g as a}from"./sdk-device.js";import{t as o}from"./parser.js";import{A as s,B as c,F as l,G as u,H as d,L as f,N as p,T as m,W as ee,a as te,b as h,d as ne,f as g,g as re,u as _,v as ie,y as ae,z as oe}from"./host.js";import{d as se,r as ce}from"./apple-runner-platform.js";import{i as le}from"./runner-toolchain-probe.js";import{_ as ue,c as de,d as fe,f as pe,g as me,h as he,l as ge,m as _e,o as ve,p as ye,t as be,u as xe,y as Se}from"./runner-cache-metadata.js";import{_ as v,n as y,p as b,u as Ce}from"./runner-session-types.js";import{P as we,r as Te}from"./runner-error-classification.js";import{a as Ee,i as De,n as Oe}from"./runner-device-set.js";import{E as x,S,_ as ke,a as Ae,b as C,d as je,g as Me,m as Ne,r as Pe,v as Fe,w,x as Ie,y as Le}from"./runner-lease.js";import Re from"node:crypto";import T from"node:fs";import ze from"node:os";import E from"node:path";const Be=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),D=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function O(e,t,n){if(!a(e))return;if(t.length===0)throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:n});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!T.existsSync(e))throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:n});for(let e of r)await A(e)||await Ve(e,n)}async function Ve(e,n){try{let t=E.join(e,`Contents`,`Frameworks`),n=T.existsSync(t)?T.readdirSync(t).sort().map(e=>E.join(t,e)):[];for(let e of n)await p(`codesign`,[...D,e]);await p(`codesign`,[...D,e])}catch(r){let i=t(r,`COMMAND_FAILED`);throw k(e,n,i.message,i.details)}if(!await A(e))throw k(e,n,`Product still fails code signature verification after re-signing`)}function k(e,t,n,r){return new i(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:n,details:r})}function He(e){if(!(e instanceof i))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&Be.has(t)}async function A(e){return(await p(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const j=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function M(e){let t=await Ge(e);if(!t||t.length===0)return null;let n=E.dirname(e),r=new Set,i=Ue(t,n);for(let e of i.testRootPaths){if(!T.existsSync(e))return null;r.add(e)}for(let e of We(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Ue(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(E.join(t,e));let o=Qe(e);o&&r.add(E.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function We(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>T.existsSync(E.join(e,t)));return n?E.join(n,t):null})}async function Ge(e){let t=await m(e);if(t)return Ke(t);if(process.platform===`darwin`)return null;try{return Xe(T.readFileSync(e,`utf8`))}catch{return null}}function Ke(e){let t=new Set;for(let n of[e,...qe(e),...Je(e)])for(let e of Ye(n))t.add(e);return Array.from(t)}function qe(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!h(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(h))}return n}function Je(e){return Object.values(e).filter(e=>h(e)&&`TestBundlePath`in e)}function Ye(e){let t=new Set;for(let[n,r]of Object.entries(e))if(j.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function Xe(e){return Ze(o(e))}function Ze(e){let t=new Set;return d(e,(e,n)=>{if(j.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function Qe(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const $e=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function et(e){await N(ft(e))}async function N(e){let t=e.filter(dt);if(t.length===0)return;let n=e.filter(e=>F(e)&&!P(e));for(let e of t){let t=ut(e,n);t&&await tt(t,e)}}async function tt(e,t){let n=nt(e,t),r=await rt(e,t);(n||r)&&(await ot(t),lt(t))}function nt(e,t){let n=!1;for(let r of T.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!ct(r.name)||st(E.join(e,r.name),E.join(t,r.name))&&(n=!0);return n}async function rt(e,t){let n=E.join(e,`Info.plist`),r=E.join(t,`Info.plist`),i=await m(n),a=await m(r);if(!i||!a)return!1;let o=it(i,a);if(o.length===0)return!1;for(let e of o)await at(r,e.key,e.value,e.shouldInsert);return!0}function it(e,t){return $e.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function at(e,t,n,r){s(await p(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function ot(e){s(await p(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function st(e,t){if(T.existsSync(t)){let n=T.readFileSync(e),r=T.readFileSync(t);return!n.equals(r)&&(T.copyFileSync(e,t),!0)}return T.copyFileSync(e,t),!0}function ct(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function lt(e){let t=new Date;T.utimesSync(e,t,t)}function ut(e,t){let n=E.dirname(e);return t.find(e=>E.dirname(e)===n&&E.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>E.dirname(t)===n&&t!==e)??null}function dt(e){return F(e)&&P(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function P(e){return E.basename(e).endsWith(`-Runner.app`)}function F(e){return E.basename(e).endsWith(`.app`)}function ft(e){if(!T.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of T.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=E.join(e,r.name);if(F(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const I=`AgentDeviceRunner.env`,L=`session`,pt=`${z(`${I}.${L}`)}-`;function mt(e){return R(`${L}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function ht(e){return`${pt}${z(R(e))}-[0-9]`}function gt(e){let t=e?E.basename(e):``;if(t.startsWith(`${I}.`))return z(t)}function R(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function z(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const _t={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function vt(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?E.resolve(i):E.dirname(e);T.mkdirSync(a,{recursive:!0});let o=R(n),s=E.join(a,`${I}.${o}.json`),c=E.join(a,`${I}.${o}.xctestrun`),l=await yt(e);return B(l,e=>xt(e,t)),St(l),await bt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function yt(e){let t=await p(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0||!t.stdout.trim())throw new i(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(t){throw new i(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(t)})}}async function bt(e,t,n){T.writeFileSync(t,JSON.stringify(e,null,2)),s(await p(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function xt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function St(e){B(e,e=>Object.assign(e,_t),{requireTestBundlePath:!0})}function B(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||Ct(e.TestTargets,t,n);for(let n of Object.values(e)){let e=V(n,{requireTestBundlePath:!0});e&&t(e)}}function Ct(e,t,n){if(Array.isArray(e))for(let r of e){let e=V(r,n);e&&t(e)}}function V(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const wt=new Map,H=new Map;function Tt(e){return zt(Bt(e,!0))}function Et(e){return zt(Bt(e,!1))}function Dt(e){e.retryPending=!1;let t=H.get(e.deviceId);t&&(t.inFlight.delete(e),Rt(e.deviceId,t))}function U(e){let t=Lt(e);t.pendingTeardowns+=1;for(let e of t.inFlight)e.close(`device_teardown`);let n=!1;return()=>{n||(n=!0,--t.pendingTeardowns,Rt(e,t))}}function Ot(e){let t=[...new Set([...H.keys(),...e??[]])].map(e=>U(e));return()=>{for(let e of t.splice(0))e()}}function kt(e){return(H.get(e)?.pendingTeardowns??0)>0}function At(e){let t=e;return!t.mintedByStart||t.admitted||t.retired!==`device_teardown`||kt(t.deviceId)?!1:(t.readmit(),!0)}function jt(e,t){return t&&!t.admitted?!1:!kt(e)}function Mt(e){return n({runnerStartRetired:!0,runnerStartRetirementReason:e})}function Nt(e,t){if(!jt(e,t))throw Mt(t?.retired??`device_teardown`)}function Pt(e,t){return t.aborted?`already-spent`:(e.interestedWaiters.add(t),`interested`)}function Ft(e,t){let n=e;return n.interestedWaiters.delete(t),!n.admitted||n.interestedWaiters.size>0?!1:n.close(`last_waiter_canceled`)}function It(e,t){e.interestedWaiters.delete(t)}function Lt(e){let t=H.get(e);if(t)return t;let n={pendingTeardowns:0,inFlight:new Set};return H.set(e,n),n}function Rt(e,t){t.pendingTeardowns<=0&&t.inFlight.size===0&&H.delete(e)}function zt(e){return Lt(e.deviceId).inFlight.add(e),e}function Bt(e,t){let n=new Set,r;return{deviceId:e,interestedWaiters:n,mintedByStart:t,retryPending:!1,get admitted(){return r===void 0},get retired(){return r},close(t){return!r&&(r=t,_({level:`debug`,phase:`ios_runner_start_admission_retired`,data:{deviceId:e,reason:t}}),!0)},readmit(){r=void 0,_({level:`debug`,phase:`ios_runner_start_admission_readmitted`,data:{deviceId:e}})}}}const W=new Set;function Vt(e,t,n){let r={deviceId:e,startAdmission:n,child:t};W.add(r),t.on(`close`,()=>{W.delete(r)})}function Ht(e){return Kt(e).map(e=>e.child)}function Ut(e){return Kt(e).filter(e=>e.startAdmission===void 0||!Wt(e.startAdmission)).map(e=>e.child)}function Wt(e){let t=e;return t.interestedWaiters.size>0||t.retryPending}function Gt(e){e.retryPending=!0}function Kt(e){return[...W].filter(t=>e===void 0||t.deviceId===e)}function qt(e){for(let t of W)t.child===e&&W.delete(t)}async function Jt(e,t){let n=Xt(t);if(n)return n;let r=g(),i=ve(e,r,t.budget),a=pe(e,i),o=await ee(wt,a,async()=>await u({acquire:()=>Me(a),task:()=>Qt({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}));return o.artifact===`rebuilt`&&Yt(a),o}async function Yt(e){try{let{evictStaleRunnerCaches:t}=await import(`./runner-cache-retention.js`);await t(e)}catch(t){_({level:`warn`,phase:`runner_xctestrun_cache_eviction_unavailable`,data:{derived:e,error:t instanceof Error?t.message:String(t)}})}}function Xt(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let n=E.resolve(t);if(!T.existsSync(n))throw new i(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:n});let r=e.iosXctestDerivedDataPath?.trim(),a=r?E.resolve(r):Zt(n);return C(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:n}),{xctestrunPath:n,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function Zt(e){let t=Re.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return E.join(ze.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function Qt(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;Le(a,e.forceRebuild);let o=await S({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await $t({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&Ie(o,a),o.reason!==`cache_metadata_missing`&&(ke(a),Fe(a)),await en({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function $t(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await nn(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:fe(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function en(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=Se(r);if(!T.existsSync(l))throw new i(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=le(n.budget,`runner_xctestrun_build`),d=Date.now();ne({type:`command`,status:`progress`,message:`Building Apple runner...`}),await ln(t,l,o,n,u);let f=Math.max(0,Date.now()-d),p=an(o,t);if(!p)throw new i(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await M(p);if(!m)throw new i(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await O(t,m,p),await N(m),w(await x(o,a,p,m),o),await tn(ye(t,a),o,[p,...m]),C(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,cacheKey:fe(a),artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function tn(e,t,n){try{let{trimRunnerBuildScratch:r}=await import(`./runner-cache-trim.js`);(await r(t,n,e)).length>0&&C(`clean`,`build_scratch_trimmed`,{derived:t})}catch(e){_({level:`warn`,phase:`runner_xctestrun_cache_trim_failed`,data:{derived:t,error:e instanceof Error?e.message:String(e)}})}}async function nn(e,t,n,r){try{return await O(e,r.productPaths,r.xctestrunPath),w(await x(t,n,r.xctestrunPath,r.productPaths),t),C(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!He(e))throw e;return C(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function rn(e){try{let t=g(),n=ve(e,t),r=pe(e,n);return(await S({derived:r,expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function an(e,t){let n=on(e);return n.length===0?null:(n.sort((e,n)=>sn(e,n,t)),n[0]?.path??null)}function on(e){if(!T.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=T.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=E.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=T.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function sn(e,t,n){if(n){let r=cn(t.path,n)-cn(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function cn(e,t){let n=0,r=e.toLowerCase();E.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${E.sep}macos${E.sep}`)&&(n-=5e3);let i=se(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}async function ln(e,t,n,a,o){Nt(e.id,a.startAdmission);let s=xe(process.env),c=ue(process.env,e.kind===`device`,e),u=e.kind===`device`?[`-allowProvisioningUpdates`]:[],d=he(),f=de(process.env),p=me();try{await l(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,_e(e),`1`,...Ee(e,ce(e)),`-derivedDataPath`,n,...ge(n),...d,...f,...p,...s,...u,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:t=>{Vt(e.id,t,a.startAdmission)},onStdoutChunk:e=>{v(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{v(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(t){if(r(t))throw t;let n=t instanceof i?t:new i(`COMMAND_FAILED`,String(t)),o=Oe(e),{reason:s,hint:c,matched:l}=Te(new i(n.code,n.message,{...n.details,...o})),u=re(n),d=`xcodebuild build-for-testing failed`;throw new i(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?De(d,e,o):d,{reason:s,error:n.message,details:n.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}var un=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>dn,abortRunnerSessionsAndPrepProcesses:()=>hn,cleanupOwnedIosRunnerLease:()=>mn,disposeRunnerSession:()=>pn,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>G,stopRunnerPrepProcesses:()=>K,stopRunnerPrepProcessesWithoutLiveOwner:()=>gn});const dn=1e3,fn=2e3,G={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:wn,cleanupTempFile:b};async function pn(e,t={}){y(e,`draining`);let n=!1;if(t.graceful!==!1)n=await vn(e);else if(a(e.device)){await q([e]),await J(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await yn(e,t.waitTimeoutMs??1e4),Y(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await J(e,t)}async function mn(e){await Pe(e,G)}async function hn(e){let t=Ht(),n=e.filter(e=>a(e.device)),r=e.filter(e=>!a(e.device));for(let t of e)y(t,`draining`);await Z(r,`SIGINT`),await Q(t,`SIGINT`),await Z(r,`SIGTERM`),await Q(t,`SIGTERM`),await Z(r,`SIGKILL`),await Q(t,`SIGKILL`),await q(n),await Promise.allSettled(e.map(async e=>{await J(e)}))}async function K(e){await _n(Ht(e))}async function gn(e){await _n(Ut(e))}async function _n(e){await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{qt(e)}}))}async function vn(e){try{return await Ce(e.device,e.port,we({command:`shutdown`}),void 0,15e3),!1}catch{return a(e.device)?(await q([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function yn(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!Y(e.child.pid)}finally{n&&clearTimeout(n)}}async function q(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await bn(e,5e3);await Z(t,`SIGTERM`),await Z(await bn(t,2e3),`SIGKILL`)}async function bn(e,t){let n=await Promise.all(e.map(async e=>await yn(e,t)));return e.filter((e,t)=>!n[t])}async function J(e,t={}){await xn(e,t),b(e.xctestrunPath),b(e.jsonPath),y(e,`stopped`)}async function xn(e,t){let n=async()=>{if(!Sn(e))try{await Cn(e.device)}finally{je(e.lease)}};if(t.leaseLockHeld){await n();return}try{await Ne(e.deviceId,n)}catch(t){_({level:`warn`,phase:`ios_runner_disposal_lease_lock_unavailable`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:t instanceof Error?t.message:String(t)}})}}function Sn(e){let t=Ae(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Cn(e){e.kind===`simulator`&&await Promise.allSettled(be.map(async t=>{try{await f(te(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:fn})}catch(n){_({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:fn,error:n instanceof Error?n.message:String(n)}})}}))}function Y(e){return e?X(e)||ae(e):!1}function X(e){return e?ie(e):!1}async function Z(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&qt(e)}))}async function $(e,t){if(!e||e<=0)return;c(e,t),oe([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await p(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function wn(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${gt(e.xctestrunPath)??ht(t)}`;for(let e of[`TERM`,`KILL`])try{await p(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){_({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{Ot as C,vt as D,mt as E,et as O,It as S,Mt as T,rn as _,X as a,Et as b,K as c,Nt as d,Ft as f,Dt as g,an as h,pn as i,M as k,gn as l,U as m,hn as n,G as o,Jt as p,mn as r,un as s,dn as t,Pt as u,Gt as v,jt as w,At as x,Tt as y};
@@ -1,3 +1,3 @@
1
- import{G as e,I as t,P as n,rt as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{g as a,p as o,x as s}from"./host.js";import ee from"node:crypto";const c=`RUNNER_BUSY`,l=`RUNNER_WEDGED`,u=`APP_NOT_RUNNING`;function te(e){let t=o(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}function d(e){return e instanceof DOMException&&e.name===`TimeoutError`}function ne(e){return s(e.requestId)||o(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&d(e.signal.reason)}function re(e){let t=o(e.requestId),n=e.signal;if(!n||n===t)return t;let r=new AbortController,i=()=>{d(n.reason)||r.abort(n.reason)};return n.aborted?i():n.addEventListener(`abort`,i,{once:!0}),t?AbortSignal.any([t,r.signal]):r.signal}const f=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,p=new Set([`APP_SCREEN_WINDOW_UNRESOLVED`,`APP_SCREEN_UNRESOLVED`,`APP_SCREEN_CAPTURE_UNRENDERABLE`]),ie=new Map([[c,{retriable:!0,reason:`runner_busy`}],[`MAIN_THREAD_TIMEOUT`,{reason:`runner_main_thread_timeout`}],[u,{retriable:!0}],[i,{}],[f,{}],...[...p].map(e=>[e,{}])]),ae=new Map([[`INVALID_ARGS`,`no`],[`ELEMENT_NOT_FOUND`,`no`],[`ELEMENT_OFFSCREEN`,`no`],[`AMBIGUOUS_MATCH`,`no`],[c,`no`],[l,`no`],[u,`no`],[f,`no`],[i,`no`],...[...p].map(e=>[e,`no`])]);function m(e){let t=e===void 0?void 0:ie.get(e);return Object.freeze({code:t?`COMMAND_FAILED`:r(e),details:Object.freeze({runnerErrorCode:e,...t,dispatched:(e===void 0?void 0:ae.get(e))??`unknown`})})}function oe(e){let t;try{t=JSON.parse(e)}catch{throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!h(t))throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return t}function h(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return e.ok===!0}function _(e){return!e.data||typeof e.data!=`object`||Array.isArray(e.data)?{}:e.data}function v(e,t){let r=y(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=m(r);return new n(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:t})}function y(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function b(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:x()}}function x(){return`runner-${ee.randomUUID()}`}function S(e){if(s(e))throw t()}const C={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},w={...C,readinessPreflightExempt:!0},T={...C,readOnly:!0},E={...T,readinessProbe:!0},D={...C,readinessPreflightSkipEligibleAfterHealthyMutation:!0},se={tap:D,mouseClick:C,longPress:D,drag:D,remotePress:C,type:C,swipe:D,scroll:D,desktopScroll:D,findText:T,querySelector:T,readText:T,snapshot:T,screenshot:T,backInApp:C,backSystem:C,home:C,rotate:C,gesture:D,gestureViewport:T,appSwitcher:C,actionButton:C,keyboardDismiss:C,keyboardReturn:C,alert:e=>(e.action??`get`).toLowerCase()===`get`?T:C,sequence:D,recordStart:C,recordStop:C,status:E,uptime:E,appState:T,pasteboardWrite:C,activate:w,terminate:w,targetReset:w,shutdown:C};function O(e){return k(e).readOnly}function ce(e){return k(e).readinessProbe}function le(e){return k(e).readinessPreflightExempt}function ue(e){return k(e).readinessPreflightSkipEligibleAfterHealthyMutation}function k(e){let t=se[e.command];return typeof t==`function`?t(e):t}const A="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function j(e){return{runnerConnectFailureReason:e}}const M=`runner_reply_lost`,N=e=>e.reason===M,P=e=>e.runnerErrorCode===c,F=e=>typeof e.devToolsSecurityStatus==`string`,I=e=>typeof e.simulatorSetPath==`string`,L=e=>e.usbmuxDeviceAttached===!1,R=e=>t=>t.runnerConnectFailureReason===e,z=t=>t.runnerReadinessPreflightFailed===!0&&!e(t),B=`build_failed_unclassified`,V={reason:`signing_provisioning_profile_missing`,hint:`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`},H=[{reason:M,match:{code:`COMMAND_FAILED`,details:N},verdicts:{retryable:!1,drainResend:!1,connectRetry:!1,restartBeforeSend:!1,restartAfterReadinessPreflight:!1}},{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:L},verdicts:{connectRetry:!1}},{reason:`runner_busy_refusal`,match:{code:`COMMAND_FAILED`,details:P},verdicts:{retryable:!0,connectRetry:!0,drainResend:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,details:R(`xcodebuild_exited_early`)},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:z},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,details:R(`runner_connect_refused`)},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,details:R(`runner_endpoint_probe_exhausted`)},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:l},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}},{reason:`simulator_set_destination_not_found`,match:{toolTextIncludesAll:[`matching the provided destination specifier`],details:I},verdicts:{},buildFailure:{reason:`simulator_set_destination_not_found`,hint:"Check that the simulator still exists in the --ios-simulator-device-set this error names (`xcrun simctl --set <set> list devices`). If it does, the Xcode this error names no longer honors -DVTSimulatorSetLocation, so use a simulator in the default set."}},{reason:`bundle_identifier_registration_failed`,match:{toolTextIncludesAll:[`failed registering bundle identifier`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`bundle_identifier_unavailable`,match:{toolTextLineIncludesAll:[`app identifier`,`not available`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`signing_requires_development_team`,match:{toolTextIncludesAll:[`requires a development team`]},verdicts:{},buildFailure:{reason:`signing_no_development_team`,hint:`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`}},{reason:`conflicting_provisioning_settings_unproven`,match:{toolTextIncludesAll:[`conflicting provisioning settings`]},verdicts:{},buildFailure:{reason:B,hint:A}},{reason:`signing_no_profiles_for_bundle_id`,match:{toolTextIncludesAll:[`no profiles for`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_xcode_error`,match:{toolTextLineIncludesAll:[`provisioning profile`,`ideprovisioningerrordomain`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_does_not_cover`,match:{toolTextLineIncludesAll:[`provisioning profile`,`doesn't include`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_expired`,match:{toolTextLineIncludesAll:[`provisioning profile`,`has expired`]},verdicts:{},buildFailure:V},{reason:`signing_unspecified`,match:{toolTextIncludesAll:[`code signing`]},verdicts:{},buildFailure:{reason:`signing_unspecified`,hint:`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}},{reason:`devtools_security_refused`,match:{code:`COMMAND_FAILED`,details:F},verdicts:{},buildFailure:{reason:`devtools_security_developer_mode_disabled`,hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach."}}];function U(e,t){return t.code!==void 0&&e.code!==t.code||!de(e,t.details)||!pe(e,t.toolTextIncludesAll)||!me(e,t.toolTextLineIncludesAll)?!1:fe(e,t.foreignMessageIncludesAll)}function de(e,t){return t===void 0||t(e.details??{})}function fe(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function W(e){let t=e.details??{};return[e.message,t.stdout,t.stderr].filter(e=>typeof e==`string`).join(`
1
+ import{G as e,I as t,P as n,rt as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{g as a,p as o,x as s}from"./host.js";import ee from"node:crypto";const c=`RUNNER_BUSY`,l=`RUNNER_WEDGED`,u=`APP_NOT_RUNNING`;function te(e){let t=o(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}function d(e){return e instanceof DOMException&&e.name===`TimeoutError`}function ne(e){return s(e.requestId)||o(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&d(e.signal.reason)}function re(e){let t=o(e.requestId),n=e.signal;if(!n||n===t)return t;let r=new AbortController,i=()=>{d(n.reason)||r.abort(n.reason)};return n.aborted?i():n.addEventListener(`abort`,i,{once:!0}),t?AbortSignal.any([t,r.signal]):r.signal}const f=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,p=new Set([`APP_SCREEN_WINDOW_UNRESOLVED`,`APP_SCREEN_UNRESOLVED`,`APP_SCREEN_CAPTURE_UNRENDERABLE`]),ie=new Map([[c,{retriable:!0,reason:`runner_busy`}],[`MAIN_THREAD_TIMEOUT`,{reason:`runner_main_thread_timeout`}],[u,{retriable:!0}],[i,{}],[f,{}],...[...p].map(e=>[e,{}])]),ae=new Map([[`INVALID_ARGS`,`no`],[`ELEMENT_NOT_FOUND`,`no`],[`ELEMENT_OFFSCREEN`,`no`],[`AMBIGUOUS_MATCH`,`no`],[c,`no`],[l,`no`],[u,`no`],[`OBSERVATION_UNAVAILABLE`,`no`],[f,`no`],[i,`no`],...[...p].map(e=>[e,`no`])]);function m(e){let t=e===void 0?void 0:ie.get(e);return Object.freeze({code:t?`COMMAND_FAILED`:r(e),details:Object.freeze({runnerErrorCode:e,...t,dispatched:(e===void 0?void 0:ae.get(e))??`unknown`})})}function oe(e){let t;try{t=JSON.parse(e)}catch{throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!h(t))throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return t}function h(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return e.ok===!0}function _(e){return!e.data||typeof e.data!=`object`||Array.isArray(e.data)?{}:e.data}function v(e,t){let r=y(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=m(r);return new n(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:t})}function y(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function b(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:x()}}function x(){return`runner-${ee.randomUUID()}`}function S(e){if(s(e))throw t()}const C={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},w={...C,readinessPreflightExempt:!0},T={...C,readOnly:!0},E={...T,readinessProbe:!0},D={...C,readinessPreflightSkipEligibleAfterHealthyMutation:!0},se={tap:D,mouseClick:C,longPress:D,drag:D,remotePress:C,type:C,swipe:D,scroll:D,desktopScroll:D,findText:T,querySelector:T,readText:T,snapshot:T,screenshot:T,backInApp:C,backSystem:C,home:C,rotate:C,gesture:D,gestureViewport:T,appSwitcher:C,actionButton:C,keyboardDismiss:C,keyboardReturn:C,alert:e=>(e.action??`get`).toLowerCase()===`get`?T:C,sequence:D,recordStart:C,recordStop:C,status:E,uptime:E,appState:T,pasteboardWrite:C,activate:w,terminate:w,targetReset:w,shutdown:C};function O(e){return k(e).readOnly}function ce(e){return k(e).readinessProbe}function le(e){return k(e).readinessPreflightExempt}function ue(e){return k(e).readinessPreflightSkipEligibleAfterHealthyMutation}function k(e){let t=se[e.command];return typeof t==`function`?t(e):t}const A="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function j(e){return{runnerConnectFailureReason:e}}const M=`runner_reply_lost`,N=e=>e.reason===M,P=e=>e.runnerErrorCode===c,F=e=>typeof e.devToolsSecurityStatus==`string`,I=e=>typeof e.simulatorSetPath==`string`,L=e=>e.usbmuxDeviceAttached===!1,R=e=>t=>t.runnerConnectFailureReason===e,z=t=>t.runnerReadinessPreflightFailed===!0&&!e(t),B=`build_failed_unclassified`,V={reason:`signing_provisioning_profile_missing`,hint:`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`},H=[{reason:M,match:{code:`COMMAND_FAILED`,details:N},verdicts:{retryable:!1,drainResend:!1,connectRetry:!1,restartBeforeSend:!1,restartAfterReadinessPreflight:!1}},{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:L},verdicts:{connectRetry:!1}},{reason:`runner_busy_refusal`,match:{code:`COMMAND_FAILED`,details:P},verdicts:{retryable:!0,connectRetry:!0,drainResend:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,details:R(`xcodebuild_exited_early`)},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:z},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,details:R(`runner_connect_refused`)},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,details:R(`runner_endpoint_probe_exhausted`)},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:l},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}},{reason:`simulator_set_destination_not_found`,match:{toolTextIncludesAll:[`matching the provided destination specifier`],details:I},verdicts:{},buildFailure:{reason:`simulator_set_destination_not_found`,hint:"Check that the simulator still exists in the --ios-simulator-device-set this error names (`xcrun simctl --set <set> list devices`). If it does, the Xcode this error names no longer honors -DVTSimulatorSetLocation, so use a simulator in the default set."}},{reason:`bundle_identifier_registration_failed`,match:{toolTextIncludesAll:[`failed registering bundle identifier`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`bundle_identifier_unavailable`,match:{toolTextLineIncludesAll:[`app identifier`,`not available`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`signing_requires_development_team`,match:{toolTextIncludesAll:[`requires a development team`]},verdicts:{},buildFailure:{reason:`signing_no_development_team`,hint:`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`}},{reason:`conflicting_provisioning_settings_unproven`,match:{toolTextIncludesAll:[`conflicting provisioning settings`]},verdicts:{},buildFailure:{reason:B,hint:A}},{reason:`signing_no_profiles_for_bundle_id`,match:{toolTextIncludesAll:[`no profiles for`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_xcode_error`,match:{toolTextLineIncludesAll:[`provisioning profile`,`ideprovisioningerrordomain`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_does_not_cover`,match:{toolTextLineIncludesAll:[`provisioning profile`,`doesn't include`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_expired`,match:{toolTextLineIncludesAll:[`provisioning profile`,`has expired`]},verdicts:{},buildFailure:V},{reason:`signing_unspecified`,match:{toolTextIncludesAll:[`code signing`]},verdicts:{},buildFailure:{reason:`signing_unspecified`,hint:`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}},{reason:`devtools_security_refused`,match:{code:`COMMAND_FAILED`,details:F},verdicts:{},buildFailure:{reason:`devtools_security_developer_mode_disabled`,hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach."}}];function U(e,t){return t.code!==void 0&&e.code!==t.code||!de(e,t.details)||!pe(e,t.toolTextIncludesAll)||!me(e,t.toolTextLineIncludesAll)?!1:fe(e,t.foreignMessageIncludesAll)}function de(e,t){return t===void 0||t(e.details??{})}function fe(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function W(e){let t=e.details??{};return[e.message,t.stdout,t.stderr].filter(e=>typeof e==`string`).join(`
2
2
  `).toLowerCase()}function pe(e,t){if(!t)return!0;let n=W(e);return t.every(e=>n.includes(e))}function me(e,t){return!t||W(e).split(`
3
3
  `).some(e=>t.every(t=>e.includes(t)))}function G(e,t){if(e instanceof n){for(let n of H)if(n.verdicts[t]!==void 0&&U(e,n.match))return n.verdicts[t]}}function he(e){return!(e instanceof n)||e.code!==`COMMAND_FAILED`?!1:G(e,`retryable`)??!1}function ge(e){return K(e)?!0:e instanceof n&&e.details?.runnerErrorCode===`MAIN_THREAD_TIMEOUT`}function K(e){return G(e,`drainResend`)??!1}function _e(e){return e instanceof n&&e.details?.runner!==void 0}function ve(e){return!(e instanceof n)||e.code!==`DEVICE_NOT_FOUND`?!1:L(e.details??{})}function ye(e){return G(e,`connectRetry`)??!0}function q(e){return G(e,`restartAfterReadinessPreflight`)??!1}function be(e){return G(e,`artifactSuspect`)??!1}function xe(e){return G(e,`sessionFatalReason`)}function Se(e,t){return J(e)?X(e)===`no`||O(t):!1}function J(e){return G(e,`restartBeforeSend`)??!1}function Ce(e){return J(e)&&Y(e)||q(e)||K(e)}function Y(e){return e instanceof n&&e.details?.dispatched===`no`||Z(e,0)}function X(e){return Y(e)?`no`:`unknown`}function Z(e,t){return t>4||typeof e!=`object`||!e?!1:e.code===`ECONNREFUSED`?!0:e instanceof AggregateError&&e.errors.length>0?e.errors.every(e=>Z(e,t+1)):Z(e.cause,t+1)}function Q(e){if(e instanceof n)for(let t of H){let n=t.buildFailure;if(n&&U(e,t.match))return{reason:n.reason,hint:n.hint,matched:!0}}return{reason:B,hint:A,matched:!1}}function $(e,t){if(!t||!(e instanceof n))return e;let r=we(e)===void 0&&t.developerDiskImage===`unavailable`&&!Ee(e)&&!Te(e);return new n(e.code,e.message,{...e.details??{},...r?{reason:`device_developer_disk_image_unavailable`,hint:t.developerDiskImageHint}:{},developerDiskImage:t.developerDiskImage},e.cause)}function we(e){let t=e.details?.reason;if(typeof t==`string`&&t!==`build_failed_unclassified`)return t}function Te(e){let t=e.details?.startupHostDeadlineHit;return typeof t==`boolean`?t:a(e)}function Ee(e){let t=e.details?.startupRuleMatched;return typeof t==`boolean`?t:Q(e).matched}export{g as A,f as C,m as D,ne as E,te as M,re as N,oe as O,b as P,ce as S,v as T,Se as _,he as a,O as b,ge as c,ve as d,X as f,q as g,be as h,$ as i,_ as j,d as k,Ce as l,j as m,M as n,K as o,xe as p,Q as r,Y as s,A as t,_e as u,ye as v,S as w,le as x,ue as y};
@@ -1 +1 @@
1
- import{P as e}from"./sdk-contracts.js";import{U as t,t as n,u as r}from"./host.js";import{b as i,f as a,l as o,n as s,u as c}from"./runner-session-types.js";import{A as l,O as u,P as d,S as f,T as p,b as m,c as h,j as g,p as _,u as v,x as y,y as b}from"./runner-error-classification.js";import x from"node:fs/promises";const S=2e3;async function C(e,t={}){if(e){try{await i(e,{timeoutMs:Math.min(S,t.timeoutMs??S),signal:t.signal})}catch{return}try{return{logPath:e,byteOffset:(await x.stat(e)).size}}catch{return{logPath:e,byteOffset:0}}}}async function w(t){let n=await T(t.logSince)??D(t.error);return n?new e(n.code??t.error.code,t.error.message,{...t.error.details??{},hint:typeof t.error.details?.hint==`string`?`${t.error.details.hint} ${n.hint}`:n.hint,runnerFailureReason:n.reason},t.error):t.error}async function T(e){if(!e)return;let t=await j(e,65536);if(t)return E(t)}function E(e){let t=e.toLowerCase();if(O(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_axruntime_coretext_crash`,hint:`The target iOS app appears to have crashed while XCTest/AXRuntime read accessibility attributes. This is usually a simulator/XCTest/runtime or app accessibility payload issue, not a text-entry failure. Reproduce on the latest stable simulator runtime, reinstall the app, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`};if(k(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_crash`,hint:`The target iOS app appears to have crashed while the runner was executing the command. Reopen or reinstall the app, retry on a fresh/latest stable simulator runtime, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`}}function D(e){if(A(e.message))return{reason:`runner_main_thread_execution_timeout`,hint:`XCTest timed out waiting for main-thread work on the current iOS screen. The app may still be visually responsive, especially on focused React Native overlays or animating screens. Use screenshot as visual truth, use coordinate presses only to prove or leave the state, and retry snapshot -i after the UI settles or after navigating away.`}}function O(e){return e.includes(`axruntime`)&&e.includes(`coretext`)&&(e.includes(`attributesforelement`)||e.includes(`axuielementcopymultipleattributevalues`)||e.includes(`reconstitutedsmuggledctfontfromdictionary`)||e.includes(`reconstitutedsmuggledattributedstringfromdictionary`))}function k(e){return e.includes(`process crashed`)||e.includes(`the application under test`)||e.includes(`terminated unexpectedly`)||e.includes(`exception type:`)&&e.includes(`thread 0 crashed`)}function A(e){return e.toLowerCase().includes(`main thread execution timed out`)}async function j(e,t){let n;try{let r=await x.stat(e.logPath),i=Math.max(e.byteOffset,r.size-t),a=r.size-i;if(a<=0)return;n=await x.open(e.logPath,`r`);let o=Buffer.alloc(a);return await n.read(o,0,a,i),o.toString(`utf8`)}catch{return}finally{await n?.close().catch(()=>{})}}async function M(e,t,r,i,a,o,s){let c=await C(i,{timeoutMs:a,signal:s}),l=d(r),u=m(l),f=n.fromTimeoutMs(a),p=U(t,l);p.action===`run`?await R({device:e,session:t,runnerCommand:l,logAttempt:c,deadline:f,signal:s,decision:p}):z(l,t,p);let h;try{h=await L({device:e,session:t,runnerCommand:l,logPath:i,deadline:f,timeoutMs:a,signal:s,readOnlyCommand:u})}catch(e){throw I(e,t,p)}try{let e=await B(h,t,c);return await N(t,l,e,o),e}catch(e){let n=P(t,l,e),r=_(e);throw r?(t.lastHealthyMutation=void 0,await o(r),e):n?e:I(e,t,p)}}async function N(e,t,n,r){e.commandCharges.settleAnswered(t.commandId);let i=F(n);i!==void 0&&(e.runnerMainThreadBusy=i);let a=H(n);a?(e.lastHealthyMutation=void 0,await r(a)):b(t)&&(e.lastHealthyMutation={atMs:Date.now(),appBundleId:t.appBundleId})}function P(e,t,n){let r=v(n);return r?e.commandCharges.settleAnswered(t.commandId):e.commandCharges.markAbandoned(t.commandId),h(n)?e.runnerMainThreadBusy=!0:r&&(e.runnerMainThreadBusy=!1),r}function F(e){return typeof e.runnerMainThreadBusy==`boolean`?e.runnerMainThreadBusy:void 0}function I(e,t,n){return n.action!==`skip`||n.reason!==`recent_healthy_mutation`?e:(t.lastHealthyMutation=void 0,G(e,{runnerReadinessPreflightSkipped:!0,runnerReadinessPreflightSkipReason:n.reason,runnerReadinessPreflightSkippedAgeMs:n.lastHealthyMutationAgeMs}))}async function L(n){let{device:r,session:i,runnerCommand:o,logPath:s,deadline:l,timeoutMs:u,signal:d,readOnlyCommand:p}=n,m=l.remainingMs();if(m<=0)throw new e(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:u});let h=p?{command:o.command,commandId:o.commandId,readOnly:!0,sessionReady:i.state===`ready`,timeoutMs:m}:{command:o.command,commandId:o.commandId},g=!f(o);g&&i.commandCharges.charge(o.commandId);try{return await t(`ios_runner_command_send`,async()=>p?await c(r,i.port,o,s,m,i,d):await a(r,i.port,o,m,d),h)}catch(e){throw g&&i.commandCharges.markAbandoned(o.commandId),e}}async function R(e){let{device:n,session:r,runnerCommand:i,logAttempt:a,deadline:o,signal:s,decision:l}=e,u=a?.logPath,f=r.state===`ready`?Math.min(1e3,o.remainingMs()):Math.min(K(r),o.remainingMs());try{let e=F(await B(await t(`ios_runner_readiness_preflight`,async()=>await c(n,r.port,d({command:`uptime`}),u,f,r,s),{command:i.command,commandId:i.commandId,reason:l.reason,lastHealthyMutationAgeMs:l.lastHealthyMutationAgeMs,sessionReady:r.state===`ready`,timeoutMs:f}),r,a));e!==void 0&&(r.runnerMainThreadBusy=e)}catch(e){throw W(e)}}function z(e,t,n){r({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:n.reason,lastHealthyMutationAgeMs:n.reason===`recent_healthy_mutation`?n.lastHealthyMutationAgeMs:void 0,sessionReady:t.state===`ready`}})}async function B(e,t,n){let r=u(await e.text());if(!l(r))throw await w({error:p(r,n?.logPath),logSince:n});s(t,`ready`);let i=g(r);return V(i),i}function V(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&r({level:`debug`,phase:`ios_runner_gesture_fallback`,data:{fallback:t,message:typeof e.gestureFallbackMessage==`string`?e.gestureFallbackMessage:void 0,hint:typeof e.gestureFallbackHint==`string`?e.gestureFallbackHint:void 0}})}function H(e){if(e.runnerFatal===!0)return typeof e.runnerFatalReason==`string`&&e.runnerFatalReason.trim().length>0?e.runnerFatalReason:`runner_reported_fatal_response`}function U(e,t){let n=m(t);if(y(t))return{action:`skip`,reason:`preflight_exempt_command`};if(e.state!==`ready`)return n?{action:`skip`,reason:`read_only_startup_command`}:{action:`run`,reason:`startup`};if(f(t))return{action:`skip`,reason:`readiness_probe_command`};if(!b(t))return{action:`run`,reason:`conservative_command`};let r=e.lastHealthyMutation;if(!r)return{action:`run`,reason:`no_recent_healthy_mutation`};if(t.appBundleId!==r.appBundleId)return{action:`run`,reason:`app_activation_uncertain`};let i=Date.now()-r.atMs;return i>5e3?{action:`run`,reason:`healthy_mutation_stale`,lastHealthyMutationAgeMs:i}:{action:`skip`,reason:`recent_healthy_mutation`,lastHealthyMutationAgeMs:i}}function W(e){return G(e,{runnerReadinessPreflightFailed:!0})}function G(t,n){let r=t instanceof e?t:new e(`COMMAND_FAILED`,t instanceof Error?t.message:String(t),void 0,t);return new e(r.code,r.message,{...r.details??{},...n},r.cause??t)}function K(e){let t=e.launchDeadline;return t?Math.max(0,Math.floor(t.remainingMs())):o}export{M as executeRunnerExchange,K as readRunnerStartupTimeoutMs};
1
+ import{P as e}from"./sdk-contracts.js";import{U as t,t as n,u as r}from"./host.js";import{f as i,h as a,l as o,n as s,u as c}from"./runner-session-types.js";import{A as l,O as u,P as d,S as f,T as p,b as m,c as h,j as g,p as _,u as v,x as y,y as b}from"./runner-error-classification.js";import x from"node:fs/promises";const S=2e3;async function C(e,t={}){if(e){try{await a(e,{timeoutMs:Math.min(S,t.timeoutMs??S),signal:t.signal})}catch{return}try{return{logPath:e,byteOffset:(await x.stat(e)).size}}catch{return{logPath:e,byteOffset:0}}}}async function w(t){let n=await T(t.logSince)??D(t.error);return n?new e(n.code??t.error.code,t.error.message,{...t.error.details??{},hint:typeof t.error.details?.hint==`string`?`${t.error.details.hint} ${n.hint}`:n.hint,runnerFailureReason:n.reason},t.error):t.error}async function T(e){if(!e)return;let t=await j(e,65536);if(t)return E(t)}function E(e){let t=e.toLowerCase();if(O(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_axruntime_coretext_crash`,hint:`The target iOS app appears to have crashed while XCTest/AXRuntime read accessibility attributes. This is usually a simulator/XCTest/runtime or app accessibility payload issue, not a text-entry failure. Reproduce on the latest stable simulator runtime, reinstall the app, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`};if(k(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_crash`,hint:`The target iOS app appears to have crashed while the runner was executing the command. Reopen or reinstall the app, retry on a fresh/latest stable simulator runtime, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`}}function D(e){if(A(e.message))return{reason:`runner_main_thread_execution_timeout`,hint:`XCTest timed out waiting for main-thread work on the current iOS screen. The app may still be visually responsive, especially on focused React Native overlays or animating screens. Use screenshot as visual truth, use coordinate presses only to prove or leave the state, and retry snapshot -i after the UI settles or after navigating away.`}}function O(e){return e.includes(`axruntime`)&&e.includes(`coretext`)&&(e.includes(`attributesforelement`)||e.includes(`axuielementcopymultipleattributevalues`)||e.includes(`reconstitutedsmuggledctfontfromdictionary`)||e.includes(`reconstitutedsmuggledattributedstringfromdictionary`))}function k(e){return e.includes(`process crashed`)||e.includes(`the application under test`)||e.includes(`terminated unexpectedly`)||e.includes(`exception type:`)&&e.includes(`thread 0 crashed`)}function A(e){return e.toLowerCase().includes(`main thread execution timed out`)}async function j(e,t){let n;try{let r=await x.stat(e.logPath),i=Math.max(e.byteOffset,r.size-t),a=r.size-i;if(a<=0)return;n=await x.open(e.logPath,`r`);let o=Buffer.alloc(a);return await n.read(o,0,a,i),o.toString(`utf8`)}catch{return}finally{await n?.close().catch(()=>{})}}async function M(e,t,r,i,a,o,s){let c=await C(i,{timeoutMs:a,signal:s}),l=d(r),u=m(l),f=n.fromTimeoutMs(a),p=U(t,l);p.action===`run`?await R({device:e,session:t,runnerCommand:l,logAttempt:c,deadline:f,signal:s,decision:p}):z(l,t,p);let h;try{h=await L({device:e,session:t,runnerCommand:l,logPath:i,deadline:f,timeoutMs:a,signal:s,readOnlyCommand:u})}catch(e){throw I(e,t,p)}try{let e=await B(h,t,c);return await N(t,l,e,o),e}catch(e){let n=P(t,l,e),r=_(e);throw r?(t.lastHealthyMutation=void 0,await o(r),e):n?e:I(e,t,p)}}async function N(e,t,n,r){e.commandCharges.settleAnswered(t.commandId);let i=F(n);i!==void 0&&(e.runnerMainThreadBusy=i);let a=H(n);a?(e.lastHealthyMutation=void 0,await r(a)):b(t)&&(e.lastHealthyMutation={atMs:Date.now(),appBundleId:t.appBundleId})}function P(e,t,n){let r=v(n);return r?e.commandCharges.settleAnswered(t.commandId):e.commandCharges.markAbandoned(t.commandId),h(n)?e.runnerMainThreadBusy=!0:r&&(e.runnerMainThreadBusy=!1),r}function F(e){return typeof e.runnerMainThreadBusy==`boolean`?e.runnerMainThreadBusy:void 0}function I(e,t,n){return n.action!==`skip`||n.reason!==`recent_healthy_mutation`?e:(t.lastHealthyMutation=void 0,G(e,{runnerReadinessPreflightSkipped:!0,runnerReadinessPreflightSkipReason:n.reason,runnerReadinessPreflightSkippedAgeMs:n.lastHealthyMutationAgeMs}))}async function L(n){let{device:r,session:a,runnerCommand:o,logPath:s,deadline:l,timeoutMs:u,signal:d,readOnlyCommand:p}=n,m=l.remainingMs();if(m<=0)throw new e(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:u});let h=p?{command:o.command,commandId:o.commandId,readOnly:!0,sessionReady:a.state===`ready`,timeoutMs:m}:{command:o.command,commandId:o.commandId},g=!f(o);g&&a.commandCharges.charge(o.commandId);try{return await t(`ios_runner_command_send`,async()=>p?await c(r,a.port,o,s,m,a,d):await i(r,a.port,o,m,d),h)}catch(e){throw g&&a.commandCharges.markAbandoned(o.commandId),e}}async function R(e){let{device:n,session:r,runnerCommand:i,logAttempt:a,deadline:o,signal:s,decision:l}=e,u=a?.logPath,f=r.state===`ready`?Math.min(1e3,o.remainingMs()):Math.min(K(r),o.remainingMs());try{let e=F(await B(await t(`ios_runner_readiness_preflight`,async()=>await c(n,r.port,d({command:`uptime`}),u,f,r,s),{command:i.command,commandId:i.commandId,reason:l.reason,lastHealthyMutationAgeMs:l.lastHealthyMutationAgeMs,sessionReady:r.state===`ready`,timeoutMs:f}),r,a));e!==void 0&&(r.runnerMainThreadBusy=e)}catch(e){throw W(e)}}function z(e,t,n){r({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:n.reason,lastHealthyMutationAgeMs:n.reason===`recent_healthy_mutation`?n.lastHealthyMutationAgeMs:void 0,sessionReady:t.state===`ready`}})}async function B(e,t,n){let r=u(await e.text());if(!l(r))throw await w({error:p(r,n?.logPath),logSince:n});s(t,`ready`);let i=g(r);return V(i),i}function V(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&r({level:`debug`,phase:`ios_runner_gesture_fallback`,data:{fallback:t,message:typeof e.gestureFallbackMessage==`string`?e.gestureFallbackMessage:void 0,hint:typeof e.gestureFallbackHint==`string`?e.gestureFallbackHint:void 0}})}function H(e){if(e.runnerFatal===!0)return typeof e.runnerFatalReason==`string`&&e.runnerFatalReason.trim().length>0?e.runnerFatalReason:`runner_reported_fatal_response`}function U(e,t){let n=m(t);if(y(t))return{action:`skip`,reason:`preflight_exempt_command`};if(e.state!==`ready`)return n?{action:`skip`,reason:`read_only_startup_command`}:{action:`run`,reason:`startup`};if(f(t))return{action:`skip`,reason:`readiness_probe_command`};if(!b(t))return{action:`run`,reason:`conservative_command`};let r=e.lastHealthyMutation;if(!r)return{action:`run`,reason:`no_recent_healthy_mutation`};if(t.appBundleId!==r.appBundleId)return{action:`run`,reason:`app_activation_uncertain`};let i=Date.now()-r.atMs;return i>5e3?{action:`run`,reason:`healthy_mutation_stale`,lastHealthyMutationAgeMs:i}:{action:`skip`,reason:`recent_healthy_mutation`,lastHealthyMutationAgeMs:i}}function W(e){return G(e,{runnerReadinessPreflightFailed:!0})}function G(t,n){let r=t instanceof e?t:new e(`COMMAND_FAILED`,t instanceof Error?t.message:String(t),void 0,t);return new e(r.code,r.message,{...r.details??{},...n},r.cause??t)}function K(e){let t=e.launchDeadline;return t?Math.max(0,Math.floor(t.remainingMs())):o}export{M as executeRunnerExchange,K as readRunnerStartupTimeoutMs};
@@ -0,0 +1 @@
1
+ import{P as e}from"./sdk-contracts.js";import{D as t,G as n,O as r,R as i,S as a,_ as ee,f as o,m as te,n as s,s as c,u as l,v as u,w as ne}from"./host.js";import"./runner-toolchain-probe.js";import{i as re,n as d,r as f,v as p}from"./runner-cache-metadata.js";import{r as ie}from"./runner-device-set.js";import m from"node:crypto";import h from"node:fs";import ae from"node:os";import g from"node:path";const _=new Set;function v(e){return g.join(e,d)}function oe(e,t){h.mkdirSync(e,{recursive:!0}),h.writeFileSync(v(e),`${JSON.stringify(t,null,2)}\n`)}async function se(e,t){if(e.cache===`external`){T(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}_.add(e.derived),await n({acquire:()=>y(e.derived),task:async()=>{T(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),w(e.derived),S(e.derived)}})}async function y(e,t=6e5){return await s({lockDirPath:ce(e),owner:{pid:process.pid,startTime:r(process.pid),acquiredAtMs:Date.now()},timeoutMs:t,pollMs:100,description:`iOS runner cache lock`})}function ce(e){return g.join(g.dirname(e),`${g.basename(e)}.lock`)}function le(e,t){!pe()&&!t&&!_.has(e)||(T(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),w(e),S(e),_.delete(e))}async function b(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return oe(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(T(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function x(t,n){if(t)throw new e(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:t.reason,refusingPath:t.path??n,...t.reason===`root_unusable`?{}:{resolvesTo:t.target},derived:n,hint:`Inspect ${t.path??n} under ${n}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function S(e){try{if(!h.existsSync(e))return;if(g.basename(e)!==`derived`){h.rmSync(e,{recursive:!0,force:!0});return}for(let t of h.readdirSync(e,{withFileTypes:!0}))ue(t.name)&&h.rmSync(g.join(e,t.name),{recursive:!0,force:!0})}catch{}}const C=new Set([d,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function ue(e){return C.has(e)}function de(e){try{let t=JSON.parse(h.readFileSync(v(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function fe(e,t){let n=de(e);return n?p(f(n))===p(f(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:re(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function pe(){return ee(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function w(t,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!me(t))throw new e(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:t,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${g.join(o(),`.tmp`)}.`})}function me(e){let t=g.resolve(o(),`.tmp`),n=g.relative(t,g.resolve(e));return n!==``&&!n.startsWith(`..`)&&!g.isAbsolute(n)}async function he(e){let t=fe(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function ge(e,t){T(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function T(e,t,n){l({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const E=process.pid;let D;function O(){return D??={value:r(process.pid)},D.value}function k(){return Re(E,O())}function A(e){let t=q(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:k(),ownerPid:E,ownerStartTime:O(),ownerStateDir:R(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?r(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...J(ie(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function j(e,t){return await n({acquire:()=>s({lockDirPath:`${H(e)}.lock`,owner:{pid:E,startTime:O(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function M(e){try{return G(JSON.parse(h.readFileSync(H(e),`utf8`)),e)}catch{return null}}function N(e){if(!e)return{type:`empty`};if(e.ownerToken===k())return{type:`owned`,lease:e};let t=c({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function P(t,n,r){let i=t.id,a=N(M(i));if(a.type===`empty`){await n.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(F(a.lease)){await Z(a.lease,`same-state-dir`,n);return}if(I(a.lease,t)){await Z(a.lease,`device-claim-takeover`,n);return}if(L(a.lease,r)){await Z(a.lease,`logical-lease-takeover`,n);return}throw new e(`COMMAND_FAILED`,r?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:r,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:ve(a.lease,r)})}await Z(a.lease,a.type,n)}function F(e){let t=R();return!t||!e.ownerStateDir?!1:g.resolve(t)===g.resolve(e.ownerStateDir)}function I(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&te(t)}function L(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:_e(t.deviceKey,e.deviceId)}function _e(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function R(){return a()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function ve(e,t){let n=ye(e),r=be(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function ye(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function be(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${xe(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function xe(e,t){return`${e}=${i(t)}`}function z(e){let t=N(M(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Se(e){let t=z(e);return t.type===`adoptable`?t.lease:null}function B(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Ce(e,t){let n=N(M(e));n.type===`owned`&&await Z(n.lease,`owned`,t)}async function we(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Oe(e);await Promise.all(n.map(async e=>{await Z(e,`owned`,t)}))}function Te(e){return M(e)?.ownerToken??null}function V(e){e&&De({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function Ee(e){let t=H(e.deviceId);h.mkdirSync(g.dirname(t),{recursive:!0}),ne({destination:t,contents:JSON.stringify(e,null,2)})}function De(e){let t=M(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{h.unlinkSync(H(e.deviceId))}catch{}}function H(e){return g.join(U(),`${ze(e)}.json`)}function U(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?g.resolve(e):g.join(ae.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Oe(e){return W({strict:!1}).filter(t=>t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime))}function W(e){let t=e.strict?Ae:ke,n=U(),r=t(()=>h.readdirSync(n,{withFileTypes:!0}))??[],i=[];for(let e of r){if(!e.isFile()||!e.name.endsWith(`.json`))continue;let r=t(()=>h.readFileSync(g.join(n,e.name),`utf8`)),a=r===null?null:Ne(r);a&&i.push(a)}return i}function ke(e){try{return e()}catch{return null}}function Ae(e){try{return e()}catch(e){if(e.code===`ENOENT`)return null;throw e}}function je(){return W({strict:!0}).filter(e=>!Me(e)).map(({xctestrunPath:e,cacheKey:t})=>({xctestrunPath:e,cacheKey:t}))}function Me(e){let t=N(e);if(t.type!==`stale`||t.staleReason===`owner-state-dir-gone`)return!1;if(e.runnerPid===null)return!0;let n=c({owner:{pid:e.runnerPid,startTime:e.runnerStartTime??null}});return n===`owner-process-dead`||n===`owner-process-reused`}function Ne(e){try{let t=JSON.parse(e),n=K(t.deviceId);return n?G(t,n):null}catch{return null}}function G(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=Pe(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:Y(n.ownerStartTime),ownerStateDir:Y(n.ownerStateDir)??void 0,runnerPid:X(n.runnerPid),runnerStartTime:Y(n.runnerStartTime),runnerLogPath:q(n.runnerLogPath),cacheKey:q(n.cacheKey),...J(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Pe(e){let t={ownerToken:K(e.ownerToken),ownerPid:X(e.ownerPid),sessionId:K(e.sessionId),port:X(e.port),xctestrunPath:K(e.xctestrunPath),jsonPath:K(e.jsonPath),createdAtMs:Fe(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function K(e){return typeof e==`string`&&e.length>0?e:null}function q(e){return K(e)??void 0}function J(e){let t=K(e);return t?{simulatorSetPath:t}:{}}function Y(e){return typeof e==`string`?e:null}function X(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function Fe(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function Z(e,t,n){l({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(Q(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(Q(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),V(e)}function Ie(e,t){return u(t)&&$(e,t)}function Q(e){let t=e.runnerPid??void 0;if(!(!t||!u(t))){if($(e,t))return t;l({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function $(e,n){return e.runnerStartTime?r(n)===e.runnerStartTime:Le(t(n))}function Le(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function Re(e,t){let n=m.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function ze(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}export{se as C,b as E,he as S,v as T,w as _,Te as a,T as b,P as c,V as d,k as f,y as g,Ee as h,we as i,z as l,j as m,A as n,Ie as o,$ as p,Ce as r,je as s,B as t,Se as u,S as v,x as w,ge as x,le as y};
@@ -1 +1 @@
1
- import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,d as r,l as i,p as a,s as o,u as s,v as c,y as l}from"./runner-cache-metadata.js";import{a as u,c as d,d as f,f as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./runner-client.js";import{A as S,D as C,E as w,S as T,g as E,k as D,v as O}from"./runner-disposal.js";async function k(e,t,n,r){return await d(e,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:n},r)}async function A(e){let{cleanupRunnerLeasesForOwner:t}=await import(`./runner-client.js`).then(e=>e.t),{runnerLeaseCleanupAdapter:n}=await import(`./runner-disposal.js`).then(e=>e.s);await t(e,n)}export{w as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,T as findRunnerXctestrun,g as hasLiveIosRunnerSession,t as isRunnerXcuitestScriptPlatform,y as notifyIosRunnerAppRelaunched,m as prepareIosRunner,u as prewarmAppleRunnerCache,_ as prewarmIosRunnerSession,k as queryAppleRunnerSelector,x as readRunnerSessionLiveness,E as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,D as requireCertifiedRunnerCacheArtifacts,o as requireRunnerBuildSettingsMatchBuildLog,C as resolveExistingRunnerProductPaths,i as resolveExpectedRunnerCacheMetadata,s as resolveRunnerAppBundleId,r as resolveRunnerArchBuildSettings,a as resolveRunnerBundleBuildSettings,n as resolveRunnerPerformanceBuildSettings,c as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,l as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,O as verifyLeaseRunnerPidIdentity,S as writeRunnerCacheMetadataForArtifacts};
1
+ import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,a as r,c as i,g as a,h as o,o as s,s as c,u as l}from"./runner-cache-metadata.js";import{a as u,c as d,d as f,f as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./runner-client.js";import{E as S,p as C,u as w,w as T}from"./runner-lease.js";import{O as E,h as D,k as O}from"./runner-disposal.js";async function k(e,t,n,r){return await d(e,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:n},r)}async function A(e){let{cleanupRunnerLeasesForOwner:t}=await import(`./runner-client.js`).then(e=>e.t),{runnerLeaseCleanupAdapter:n}=await import(`./runner-disposal.js`).then(e=>e.s);await t(e,n)}export{E as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,D as findRunnerXctestrun,g as hasLiveIosRunnerSession,t as isRunnerXcuitestScriptPlatform,y as notifyIosRunnerAppRelaunched,m as prepareIosRunner,u as prewarmAppleRunnerCache,_ as prewarmIosRunnerSession,k as queryAppleRunnerSelector,x as readRunnerSessionLiveness,w as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,T as requireCertifiedRunnerCacheArtifacts,r as requireRunnerBuildSettingsMatchBuildLog,O as resolveExistingRunnerProductPaths,s as resolveExpectedRunnerCacheMetadata,c as resolveRunnerAppBundleId,i as resolveRunnerArchBuildSettings,l as resolveRunnerBundleBuildSettings,o as resolveRunnerPerformanceBuildSettings,a as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,n as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,C as verifyLeaseRunnerPidIdentity,S as writeRunnerCacheMetadataForArtifacts};
@@ -1 +1 @@
1
- import{I as e,K as t,P as n,V as r,z as i}from"./sdk-contracts.js";import{n as a}from"./entities.js";import{t as o}from"./parser.js";import{A as s,L as c,M as l,V as u,a as d,i as f,j as p,o as m,t as h}from"./host.js";import{o as g}from"./runner-cache-metadata.js";import{d as _,i as v,m as y,r as ee,s as te,t as ne,v as re}from"./runner-error-classification.js";import b from"node:fs";import ie from"node:os";import x from"node:path";import S from"node:net";import C from"node:http";async function ae(){return await new Promise((e,t)=>{let r=S.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>t(new n(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,t)})}function oe(e,t,n,r){t&&E(t,e),n&&E(n,e),r&&process.stderr.write(e)}const w=new Map,T=new Map;function E(e,t){let n=(w.get(e)??Promise.resolve()).then(()=>D(e,t),()=>D(e,t)).then(()=>{T.delete(e)},t=>{T.set(e,t)}).finally(()=>{w.get(e)===n&&w.delete(e)});w.set(e,n)}async function D(e,t){await b.promises.mkdir(x.dirname(e),{recursive:!0}),await b.promises.appendFile(e,t)}async function se(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=w.get(e);if(r){let e=()=>{};try{await Promise.race([r,new Promise((t,r)=>{e=()=>r(n.reason),n.addEventListener(`abort`,e,{once:!0})})])}finally{n.removeEventListener(`abort`,e)}}let i=T.get(e);if(i!==void 0)throw i}function ce(e){try{b.existsSync(e)&&b.unlinkSync(e)}catch{}}function le(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return x.join(ie.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function ue(e,t){let n=0;try{n=b.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function de(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,i=null,a=null,o=!1,s=()=>{if(!o)try{i??=b.openSync(e.file.logPath,`r`);let t=b.fstatSync(i).size;for(t<r&&(r=0);r<t;){let a=Math.min(n.length,t-r),o=b.readSync(i,n,0,a,r);if(o<=0)break;r+=o,e.onOutput(n.toString(`utf8`,0,o)),t=b.fstatSync(i).size}}catch{l()}},c=()=>{o||(a=setTimeout(()=>{s(),c()},t),a.unref?.())};function l(){if(!o&&(o=!0,a&&clearTimeout(a),a=null,i!==null)){try{b.closeSync(i)}catch{}i=null}}return c(),{drain:()=>{s(),l()},stop:l}}function fe(e,t){if(!e)return``;let n=null;try{n=b.openSync(e.logPath,`r`);let r=b.fstatSync(n).size,i=Math.max(e.startOffset,r-t),a=r-i;if(a<=0)return``;let o=Buffer.alloc(a),s=b.readSync(n,o,0,a,i);return o.toString(`utf8`,0,Math.max(s,0))}catch{return``}finally{if(n!==null)try{b.closeSync(n)}catch{}}}const O=new Map;function k(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return j(e,t,null,!1);let o=p(e);if(o.backend===`xctest`||!r)return pe(e,t);if(!a){let r=me(e.id);if(r)return j(e,t,r,!0);if(n!==void 0)return j(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&he(e.id,s),j(e,t,s,!1)}}}function A(e){O.delete(e)}function pe(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function j(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function me(e){let t=O.get(e);return t?t.expiresAt<=Date.now()?(O.delete(e),null):t.ip:null}function he(e,t){O.set(e,{ip:t,expiresAt:Date.now()+3e4})}function M(e){return u(e).simulatorSetPath}function ge(e,t){let n=u(e),r=u(t);return n.udid===r.udid&&n.simulatorSetPath===r.simulatorSetPath}function _e(e,t){let n=M(e);return n===void 0?[`-destination`,t]:[`-destination`,t,`-DVTSimulatorSetLocation=${n}`]}function N(e){let t=M(e);if(t===void 0)return{};let n=g(e);return n===void 0?{simulatorSetPath:t}:{simulatorSetPath:t,xcodeVersion:n}}function P(e,t,n){return`${e}: xcodebuild found no simulator ${t.id} in simulator set ${n.simulatorSetPath}${n.xcodeVersion===void 0?``:` with Xcode ${n.xcodeVersion}`}`}const F=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function ve(e,t,n,r,i){let a=h.fromTimeoutMs(r);return await be(e,t,await ye(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function ye(e,t,r,i){let a=await I(e,r,i);try{await L(a,1,z(`ListDevices`));let e=xe((await R(a,r,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new n(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:F})}finally{a.destroy()}}async function be(e,t,n,r,i,a){let o=await I(e,i,a);try{await L(o,2,z(`Connect`,{DeviceID:n,PortNumber:Te(r)}));let e=Ce((await R(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw we({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function I(t,r,i){if(H(r,`connect to usbmuxd`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=S.createConnection(t),c=!1,l=setTimeout(()=>{p(new n(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:t,timeoutMs:r}))},r),u=()=>p(),d=e=>p(e),f=()=>p(e()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function L(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function R(t,r,i){if(H(r,`read usbmuxd response`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new n(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:r})),r),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new n(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new n(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(e()),m=(e,n)=>{c||(c=!0,clearTimeout(l),t.off(`data`,u),t.off(`error`,d),t.off(`close`,f),i?.removeEventListener(`abort`,p),t.pause(),e?o(e):a(n))};t.on(`data`,u),t.once(`error`,d),t.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),t.resume()})}function z(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${a(e)}</key><integer>${t}</integer>`:`<key>${a(e)}</key><string>${a(t)}</string>`).join(``)}</dict></plist>`}function xe(e,t){let n;for(let r of V(o(e))){let e=Se(r);if(e?.udid===t){if(B(B(r,`Properties`),`ConnectionType`)?.text===`USB`)return e.id;n??=e.id}}return n}function Se(e){if(e.name!==`dict`)return;let t=B(e,`Properties`);if(t?.name!==`dict`)return;let n=B(t,`SerialNumber`)?.text,r=Number(B(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function Ce(e,t){for(let n of V(o(e))){if(n.name!==`dict`)continue;let e=B(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function B(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*V(e){for(let t of e)yield t,yield*V(t.children)}function we(e){let{result:t,udid:r,deviceId:i,port:a}=e;return t===2?new n(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:F}):t===3?new n(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new n(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Te(e){return(e&255)<<8|e>>>8&255}function H(e,t){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function Ee(e){return{postCommand:async(t,r,a,o,s)=>{let c=h.fromTimeoutMs(o),l=await ve(e,t,r,c.remainingMs(),s).catch(e=>{throw e instanceof n?i(e,`no`):e});try{return await De(l,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const U=Ee(`/var/run/usbmuxd`);async function De(t,r,i,a){if(Ae(i),a?.aborted)throw e();let o=Buffer.from(JSON.stringify(r),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new C.Agent;l.createConnection=(e,n)=>(n?.(null,t),t);try{let e=await Oe(l,t,o,c);return new Response((await ke(e)).toString(`utf8`),{status:e.statusCode??500})}catch(t){throw a?.aborted?e():s.aborted?new n(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):t}finally{l.destroy(),t.destroy()}}async function Oe(e,t,n,r){return await new Promise((i,a)=>{let o=C.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function ke(e){let t=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new n(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function Ae(e){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const W=45e3;async function je(t,r,i,a=W,o){if(o?.aborted)throw e();let s=h.fromTimeoutMs(a),c=k(t,r),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await Me(t,r,i,s,o)}catch(e){if(!G(t,e))throw e;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new n(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:r,endpoints:l.endpoints});return await K(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function Me(e,t,r,i,a){let o=i.remainingMs();if(o<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await U.postCommand(e.id,t,r,o,a)}function G(e,t){return _(t)?p(e).backend!==`xctest`:!1}async function K(e,t,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:r},e):e}}const q=45e3,J=2e4;async function Ne(n,r,i,a,o=q,s,c){let u=h.fromTimeoutMs(o),{resolveRoute:d,markUsbmuxUnattached:f}=k(n,r),p=await d(u.remainingMs()),m=null,g=!1,v=Math.max(1,Math.ceil(o/250));try{return await l(async({deadline:e})=>{let t=await Pe({device:n,port:r,command:i,timeoutMs:o,logPath:a,session:s,route:p,resolveRoute:d,markUsbmuxUnattached:f,signal:c,attemptDeadline:e,setRoute:e=>{p=e},setLastError:e=>{m=e,te(e)||(g=!0)}});if(t)return t;throw ze({port:r,endpoints:p.endpoints,lastError:m,signal:c})},{maxAttempts:v,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:re},{deadline:u,phase:`ios_runner_connect`,signal:c,retryWakeSignal:n.kind===`simulator`?s?.startupRetryWake:void 0})}catch(n){if(c?.aborted||t(n))throw e();if(_(n))throw n;m||=n}if(c?.aborted)throw e();if(n.kind===`simulator`){let e=u.remainingMs();if(e<=0)throw Y(Ue({port:r,endpoints:p.endpoints,logPath:a,lastError:m}),g);let t=await Z(n,r,i,e,c).catch(e=>{throw Y(e,g)});return new Response(t.body,{status:t.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?Y(await We({session:s,port:r,logPath:a}),g):Y(Ue({port:r,endpoints:p.endpoints,logPath:a,lastError:m,deviceStates:s?.startupDeviceStates}),g)}function Y(e,t){return e instanceof n?t?i(e,`unknown`):r(e,`no`):e}async function Pe(e){await Fe(e);let t=await Ie(e);return t.response?t.response:await Le(e)||await Re(e,t.usedCachedTunnelIp)}async function Fe(e){if(e.attemptDeadline?.isExpired())throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await We({session:e.session,port:e.port,logPath:e.logPath})}async function Ie(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await X(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&A(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Le(e){return e.device.kind!==`simulator`||e.session?.state!==`ready`?null:await Ve(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Re(e,t){if(e.device.kind!==`device`||!t)return null;A(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await X(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function ze(t){if(t.signal?.aborted)throw e();return new n(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:t.port,endpoints:t.endpoints,lastError:t.lastError?String(t.lastError):void 0,...y(`runner_endpoint_probe_exhausted`)})}async function X(r,a,o){if(a.kind===`network`)return await Be(a.endpoints,o);let s=a.endpoints[0];try{let e=o.attemptDeadline?.remainingMs()??o.timeoutMs;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o.port,timeoutMs:o.timeoutMs}),`no`);return await U.postCommand(r.id,o.port,o.command,Math.min(J,e),o.signal)}catch(n){if(o.signal?.aborted||t(n))throw e();if(_(n)){if(!G(r,n))throw n;return o.onUsbmuxUnattached?.(),null}return o.onError(s,n),null}}async function Be(r,a){let{command:o,port:s,timeoutMs:c,signal:l,attemptDeadline:u,onError:d}=a;for(let a of r)try{let e=u?.remainingMs()??c;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:s,timeoutMs:c}),`no`);return await K(a,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(o)},Math.min(J,e),l)}catch(n){if(l?.aborted||t(n))throw e();d(a,n)}return null}async function Ve(n,r,i,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let e=await Z(n,r,i,l,o);return new Response(e.body,{status:e.status})}catch(n){if(o?.aborted||t(n))throw e();return c(n),null}}async function Z(e,t,n,r,i){let a=JSON.stringify(n),o=d(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]);return{status:200,body:s(await c(o,{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=m({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:f(n),...y(`runner_connect_refused`),dispatched:e.exitCode===7?`no`:`unknown`}}).stdout}}function He(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?f(a):`${f(a)} ${ne}`}function Ue(e){let{port:t,endpoints:r,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new n(`COMMAND_FAILED`,s,{port:t,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:m({error:a,message:s,context:{platform:`ios`,phase:`connect`}}),hint:f(`IOS_RUNNER_CONNECT_TIMEOUT`),...y(`runner_connect_refused`)});return v(c,o)}async function We(e){let{session:t,port:r,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=t.readLogTail?.(65536)??``,c=m({message:o,stdout:s,stderr:s,context:{platform:`ios`,phase:`connect`}}),l=N(t.device),u=ee(new n(`COMMAND_FAILED`,o,{stderr:s,...l})),d=u.reason===`simulator_set_destination_not_found`,f=new n(`COMMAND_FAILED`,d?P(o,t.device,l):o,{port:r,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:d?u.reason:c,hint:d?u.hint:He(o,s,s,c),...l,...y(`xcodebuild_exited_early`)});return v(f,t.startupDeviceStates)}const Ge={starting:[`ready`,`draining`,`stopped`],ready:[`draining`,`stopped`],draining:[`stopped`],stopped:[]};function Ke(e,t){Ge[e.state].includes(t)&&(e.state=t)}function qe(e){return e.state===`starting`||e.state===`ready`}function Q(e){return e?.runnerMainThreadBusy===!0}var Je=class{charges=[];get hasOutstandingCharges(){return this.charges.length>0}get outstandingChargeCount(){return this.charges.length}get hasAbandonedCharges(){return this.charges.some(e=>e.abandoned)}charge(e){this.charges.push({commandId:$(e),abandoned:!1})}markAbandoned(e){let t=this.findChargeIndex(e);t!==-1&&(this.charges[t].abandoned=!0)}settleAnswered(e){let t=this.findChargeIndex(e);if(t===-1)return;let n=this.charges[t];if(this.charges.splice(t,1),n.abandoned)return;let r=this.charges.findIndex((e,n)=>n<t&&e.abandoned);r!==-1&&this.charges.splice(r,1)}settleTerminalEvidence(e){let t=$(e);if(t===``)return!1;let n=this.charges.filter(e=>e.commandId!==t||!e.abandoned);return n.length!==this.charges.length&&(this.charges=n,!0)}findChargeIndex(e){let t=$(e);if(t===``)return-1;for(let e=this.charges.length-1;e>=0;--e)if(this.charges[e].commandId===t)return e;return-1}};function $(e){return e?.trim()??``}function Ye(e){return e.state===`ready`?e.commandCharges.hasOutstandingCharges?{detach:!1,reason:`command_in_flight`}:Q(e)?{detach:!1,reason:`main_thread_occupied`}:{detach:!0}:{detach:!1,reason:`runner_never_served_a_command`}}function Xe(e){return e.processRunning?e.state:`gone`}function Ze(e,t){return`${e}:${t}:${Date.now()}`}function Qe(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}export{fe as C,oe as S,de as T,_e as _,Q as a,se as b,Xe as c,W as d,je as f,P as g,M as h,qe as i,q as l,N as m,Ke as n,Qe as o,ge as p,Ze as r,Ye as s,Je as t,Ne as u,ce as v,le as w,ae as x,ue as y};
1
+ import{I as e,K as t,P as n,V as r,z as i}from"./sdk-contracts.js";import{n as a}from"./entities.js";import{t as o}from"./parser.js";import{A as s,L as c,M as l,a as u,i as d,j as f,o as p,t as m}from"./host.js";import{d as h,i as g,m as _,r as v,s as ee,t as te,v as ne}from"./runner-error-classification.js";import{i as re,n as ie}from"./runner-device-set.js";import y from"node:fs";import ae from"node:os";import b from"node:path";import x from"node:net";import S from"node:http";async function oe(){return await new Promise((e,t)=>{let r=x.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>t(new n(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,t)})}function se(e,t,n,r){t&&T(t,e),n&&T(n,e),r&&process.stderr.write(e)}const C=new Map,w=new Map;function T(e,t){let n=(C.get(e)??Promise.resolve()).then(()=>E(e,t),()=>E(e,t)).then(()=>{w.delete(e)},t=>{w.set(e,t)}).finally(()=>{C.get(e)===n&&C.delete(e)});C.set(e,n)}async function E(e,t){await y.promises.mkdir(b.dirname(e),{recursive:!0}),await y.promises.appendFile(e,t)}async function ce(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=C.get(e);if(r){let e=()=>{};try{await Promise.race([r,new Promise((t,r)=>{e=()=>r(n.reason),n.addEventListener(`abort`,e,{once:!0})})])}finally{n.removeEventListener(`abort`,e)}}let i=w.get(e);if(i!==void 0)throw i}function le(e){try{y.existsSync(e)&&y.unlinkSync(e)}catch{}}function D(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return b.join(ae.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function ue(e,t){let n=0;try{n=y.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function de(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,i=null,a=null,o=!1,s=()=>{if(!o)try{i??=y.openSync(e.file.logPath,`r`);let t=y.fstatSync(i).size;for(t<r&&(r=0);r<t;){let a=Math.min(n.length,t-r),o=y.readSync(i,n,0,a,r);if(o<=0)break;r+=o,e.onOutput(n.toString(`utf8`,0,o)),t=y.fstatSync(i).size}}catch{l()}},c=()=>{o||(a=setTimeout(()=>{s(),c()},t),a.unref?.())};function l(){if(!o&&(o=!0,a&&clearTimeout(a),a=null,i!==null)){try{y.closeSync(i)}catch{}i=null}}return c(),{drain:()=>{s(),l()},stop:l}}function fe(e,t){if(!e)return``;let n=null;try{n=y.openSync(e.logPath,`r`);let r=y.fstatSync(n).size,i=Math.max(e.startOffset,r-t),a=r-i;if(a<=0)return``;let o=Buffer.alloc(a),s=y.readSync(n,o,0,a,i);return o.toString(`utf8`,0,Math.max(s,0))}catch{return``}finally{if(n!==null)try{y.closeSync(n)}catch{}}}const O=new Map;function k(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return j(e,t,null,!1);let o=f(e);if(o.backend===`xctest`||!r)return pe(e,t);if(!a){let r=me(e.id);if(r)return j(e,t,r,!0);if(n!==void 0)return j(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&he(e.id,s),j(e,t,s,!1)}}}function A(e){O.delete(e)}function pe(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function j(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function me(e){let t=O.get(e);return t?t.expiresAt<=Date.now()?(O.delete(e),null):t.ip:null}function he(e,t){O.set(e,{ip:t,expiresAt:Date.now()+3e4})}const M=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function ge(e,t,n,r,i){let a=m.fromTimeoutMs(r);return await ve(e,t,await _e(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function _e(e,t,r,i){let a=await N(e,r,i);try{await P(a,1,I(`ListDevices`));let e=ye((await F(a,r,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new n(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:M})}finally{a.destroy()}}async function ve(e,t,n,r,i,a){let o=await N(e,i,a);try{await P(o,2,I(`Connect`,{DeviceID:n,PortNumber:Ce(r)}));let e=xe((await F(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw Se({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function N(t,r,i){if(z(r,`connect to usbmuxd`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=x.createConnection(t),c=!1,l=setTimeout(()=>{p(new n(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:t,timeoutMs:r}))},r),u=()=>p(),d=e=>p(e),f=()=>p(e()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function P(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function F(t,r,i){if(z(r,`read usbmuxd response`),i?.aborted)throw e();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new n(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:r})),r),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new n(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new n(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(e()),m=(e,n)=>{c||(c=!0,clearTimeout(l),t.off(`data`,u),t.off(`error`,d),t.off(`close`,f),i?.removeEventListener(`abort`,p),t.pause(),e?o(e):a(n))};t.on(`data`,u),t.once(`error`,d),t.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),t.resume()})}function I(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${a(e)}</key><integer>${t}</integer>`:`<key>${a(e)}</key><string>${a(t)}</string>`).join(``)}</dict></plist>`}function ye(e,t){let n;for(let r of R(o(e))){let e=be(r);if(e?.udid===t){if(L(L(r,`Properties`),`ConnectionType`)?.text===`USB`)return e.id;n??=e.id}}return n}function be(e){if(e.name!==`dict`)return;let t=L(e,`Properties`);if(t?.name!==`dict`)return;let n=L(t,`SerialNumber`)?.text,r=Number(L(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function xe(e,t){for(let n of R(o(e))){if(n.name!==`dict`)continue;let e=L(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function L(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*R(e){for(let t of e)yield t,yield*R(t.children)}function Se(e){let{result:t,udid:r,deviceId:i,port:a}=e;return t===2?new n(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:M}):t===3?new n(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new n(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Ce(e){return(e&255)<<8|e>>>8&255}function z(e,t){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function we(e){return{postCommand:async(t,r,a,o,s)=>{let c=m.fromTimeoutMs(o),l=await ge(e,t,r,c.remainingMs(),s).catch(e=>{throw e instanceof n?i(e,`no`):e});try{return await Te(l,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const B=we(`/var/run/usbmuxd`);async function Te(t,r,i,a){if(De(i),a?.aborted)throw e();let o=Buffer.from(JSON.stringify(r),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new S.Agent;l.createConnection=(e,n)=>(n?.(null,t),t);try{let e=await Ee(l,t,o,c);return new Response((await V(e)).toString(`utf8`),{status:e.statusCode??500})}catch(t){throw a?.aborted?e():s.aborted?new n(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):t}finally{l.destroy(),t.destroy()}}async function Ee(e,t,n,r){return await new Promise((i,a)=>{let o=S.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function V(e){let t=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new n(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function De(e){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const H=45e3;async function Oe(t,r,i,a=H,o){if(o?.aborted)throw e();let s=m.fromTimeoutMs(a),c=k(t,r),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await ke(t,r,i,s,o)}catch(e){if(!U(t,e))throw e;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new n(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:r,endpoints:l.endpoints});return await W(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function ke(e,t,r,i,a){let o=i.remainingMs();if(o<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await B.postCommand(e.id,t,r,o,a)}function U(e,t){return h(t)?f(e).backend!==`xctest`:!1}async function W(e,t,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:r},e):e}}const G=45e3,K=2e4;async function Ae(n,r,i,a,o=G,s,c){let u=m.fromTimeoutMs(o),{resolveRoute:d,markUsbmuxUnattached:f}=k(n,r),p=await d(u.remainingMs()),g=null,_=!1,v=Math.max(1,Math.ceil(o/250));try{return await l(async({deadline:e})=>{let t=await je({device:n,port:r,command:i,timeoutMs:o,logPath:a,session:s,route:p,resolveRoute:d,markUsbmuxUnattached:f,signal:c,attemptDeadline:e,setRoute:e=>{p=e},setLastError:e=>{g=e,ee(e)||(_=!0)}});if(t)return t;throw Ie({port:r,endpoints:p.endpoints,lastError:g,signal:c})},{maxAttempts:v,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:ne},{deadline:u,phase:`ios_runner_connect`,signal:c,retryWakeSignal:n.kind===`simulator`?s?.startupRetryWake:void 0})}catch(n){if(c?.aborted||t(n))throw e();if(h(n))throw n;g||=n}if(c?.aborted)throw e();if(n.kind===`simulator`){let e=u.remainingMs();if(e<=0)throw q(X({port:r,endpoints:p.endpoints,logPath:a,lastError:g}),_);let t=await Y(n,r,i,e,c).catch(e=>{throw q(e,_)});return new Response(t.body,{status:t.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?q(await Z({session:s,port:r,logPath:a}),_):q(X({port:r,endpoints:p.endpoints,logPath:a,lastError:g,deviceStates:s?.startupDeviceStates}),_)}function q(e,t){return e instanceof n?t?i(e,`unknown`):r(e,`no`):e}async function je(e){await Me(e);let t=await Ne(e);return t.response?t.response:await Pe(e)||await Fe(e,t.usedCachedTunnelIp)}async function Me(e){if(e.attemptDeadline?.isExpired())throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await Z({session:e.session,port:e.port,logPath:e.logPath})}async function Ne(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await J(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&A(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Pe(e){return e.device.kind!==`simulator`||e.session?.state!==`ready`?null:await Re(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Fe(e,t){if(e.device.kind!==`device`||!t)return null;A(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await J(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function Ie(t){if(t.signal?.aborted)throw e();return new n(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:t.port,endpoints:t.endpoints,lastError:t.lastError?String(t.lastError):void 0,..._(`runner_endpoint_probe_exhausted`)})}async function J(r,a,o){if(a.kind===`network`)return await Le(a.endpoints,o);let s=a.endpoints[0];try{let e=o.attemptDeadline?.remainingMs()??o.timeoutMs;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o.port,timeoutMs:o.timeoutMs}),`no`);return await B.postCommand(r.id,o.port,o.command,Math.min(K,e),o.signal)}catch(n){if(o.signal?.aborted||t(n))throw e();if(h(n)){if(!U(r,n))throw n;return o.onUsbmuxUnattached?.(),null}return o.onError(s,n),null}}async function Le(r,a){let{command:o,port:s,timeoutMs:c,signal:l,attemptDeadline:u,onError:d}=a;for(let a of r)try{let e=u?.remainingMs()??c;if(e<=0)throw i(new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:s,timeoutMs:c}),`no`);return await W(a,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(o)},Math.min(K,e),l)}catch(n){if(l?.aborted||t(n))throw e();d(a,n)}return null}async function Re(n,r,i,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let e=await Y(n,r,i,l,o);return new Response(e.body,{status:e.status})}catch(n){if(o?.aborted||t(n))throw e();return c(n),null}}async function Y(e,t,n,r,i){let a=JSON.stringify(n),o=u(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]);return{status:200,body:s(await c(o,{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=p({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:d(n),..._(`runner_connect_refused`),dispatched:e.exitCode===7?`no`:`unknown`}}).stdout}}function ze(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?d(a):`${d(a)} ${te}`}function X(e){let{port:t,endpoints:r,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new n(`COMMAND_FAILED`,s,{port:t,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:p({error:a,message:s,context:{platform:`ios`,phase:`connect`}}),hint:d(`IOS_RUNNER_CONNECT_TIMEOUT`),..._(`runner_connect_refused`)});return g(c,o)}async function Z(e){let{session:t,port:r,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=t.readLogTail?.(65536)??``,c=p({message:o,stdout:s,stderr:s,context:{platform:`ios`,phase:`connect`}}),l=ie(t.device),u=v(new n(`COMMAND_FAILED`,o,{stderr:s,...l})),d=u.reason===`simulator_set_destination_not_found`,f=new n(`COMMAND_FAILED`,d?re(o,t.device,l):o,{port:r,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:d?u.reason:c,hint:d?u.hint:ze(o,s,s,c),...l,..._(`xcodebuild_exited_early`)});return g(f,t.startupDeviceStates)}const Be={starting:[`ready`,`draining`,`stopped`],ready:[`draining`,`stopped`],draining:[`stopped`],stopped:[]};function Ve(e,t){Be[e.state].includes(t)&&(e.state=t)}function He(e){return e.state===`starting`||e.state===`ready`}function Q(e){return e?.runnerMainThreadBusy===!0}var Ue=class{charges=[];get hasOutstandingCharges(){return this.charges.length>0}get outstandingChargeCount(){return this.charges.length}get hasAbandonedCharges(){return this.charges.some(e=>e.abandoned)}charge(e){this.charges.push({commandId:$(e),abandoned:!1})}markAbandoned(e){let t=this.findChargeIndex(e);t!==-1&&(this.charges[t].abandoned=!0)}settleAnswered(e){let t=this.findChargeIndex(e);if(t===-1)return;let n=this.charges[t];if(this.charges.splice(t,1),n.abandoned)return;let r=this.charges.findIndex((e,n)=>n<t&&e.abandoned);r!==-1&&this.charges.splice(r,1)}settleTerminalEvidence(e){let t=$(e);if(t===``)return!1;let n=this.charges.filter(e=>e.commandId!==t||!e.abandoned);return n.length!==this.charges.length&&(this.charges=n,!0)}findChargeIndex(e){let t=$(e);if(t===``)return-1;for(let e=this.charges.length-1;e>=0;--e)if(this.charges[e].commandId===t)return e;return-1}};function $(e){return e?.trim()??``}function We(e){return e.state===`ready`?e.commandCharges.hasOutstandingCharges?{detach:!1,reason:`command_in_flight`}:Q(e)?{detach:!1,reason:`main_thread_occupied`}:{detach:!0}:{detach:!1,reason:`runner_never_served_a_command`}}function Ge(e){return e.processRunning?e.state:`gone`}function Ke(e,t){return`${e}:${t}:${Date.now()}`}function qe(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}export{se as _,Q as a,de as b,Ge as c,H as d,Oe as f,oe as g,ce as h,He as i,G as l,ue as m,Ve as n,qe as o,le as p,Ke as r,We as s,Ue as t,Ae as u,fe as v,D as y};
@@ -1 +1 @@
1
- import{I as e,K as t,P as n}from"./sdk-contracts.js";import{u as r}from"./host.js";import{i}from"./runner-cache-metadata.js";import{o as a}from"./runner-session-types.js";import{N as o,k as s}from"./runner-error-classification.js";import{l as c}from"./runner-disposal.js";function l(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(u(n,t!==void 0))},n);s.unref?.();let c=o(e),l=c?AbortSignal.any([c,r.signal]):r.signal;return{phase:i(n,l),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function u(e,t){return new n(`COMMAND_FAILED`,`Apple runner start exceeded its ${t?`startup timeout`:`default start budget`} of ${e}ms`,{reason:`runner_start_budget_exhausted`,timeoutMs:e,retriable:!0,hint:t?"Raise the startup timeout, or run `prepare ios-runner` first so the runner is built before it is needed.":"Run `prepare ios-runner --timeout <ms>` so the cold build has a budget of your choosing; the session runner.log names the step that stalled."})}async function d(t,n,r){return n?await new Promise((i,a)=>{let o=()=>{a(e(void 0,n.reason)),s(n.reason)||c(r),t.catch(f)};n.aborted?o():n.addEventListener(`abort`,o,{once:!0}),t.then(i,a).finally(()=>n.removeEventListener(`abort`,o))}):await t}function f(e){if(t(e))return;let i=e instanceof n?e:void 0;r({level:`warn`,phase:`ios_runner_detached_start_failed`,data:{code:i?.code,reason:i?.details?.reason,error:e instanceof Error?e.message:String(e)}})}export{l as openRunnerStartBudget,d as raceRunnerStartAgainstCaller};
1
+ import{I as e,K as t,P as n}from"./sdk-contracts.js";import{u as r}from"./host.js";import{r as i}from"./runner-toolchain-probe.js";import{o as a}from"./runner-session-types.js";import{N as o,k as s}from"./runner-error-classification.js";import{S as c,f as l,l as u,u as d,v as f}from"./runner-disposal.js";function p(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(m(n,t!==void 0))},n);s.unref?.();let c=o(e),l=c?AbortSignal.any([c,r.signal]):r.signal;return{phase:i(n,l),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function m(e,t){return new n(`COMMAND_FAILED`,`Apple runner start exceeded its ${t?`startup timeout`:`default start budget`} of ${e}ms`,{reason:`runner_start_budget_exhausted`,timeoutMs:e,retriable:!0,hint:t?"Raise the startup timeout, or run `prepare ios-runner` first so the runner is built before it is needed.":"Run `prepare ios-runner --timeout <ms>` so the cold build has a budget of your choosing; the session runner.log names the step that stalled."})}async function h(t,n,r){return r?await new Promise((i,a)=>{let o=r.aborted?`already-spent`:d(n,r),p=()=>{if(a(e(void 0,r.reason)),t.catch(_),s(r.reason)){o===`interested`&&c(n,r),f(n);return}l(n,r)&&u(n.deviceId)};r.aborted?p():r.addEventListener(`abort`,p,{once:!0}),t.then(i,a).finally(()=>{r.removeEventListener(`abort`,p),o===`interested`&&c(n,r)})}):await t}function g(e,t){let n=t.signal?void 0:o(t);if(!n||d(e,n)!==`interested`)return()=>{};let r=()=>{l(e,n)&&u(e.deviceId)};return n.addEventListener(`abort`,r,{once:!0}),()=>{n.removeEventListener(`abort`,r),c(e,n)}}function _(e){if(t(e))return;let i=e instanceof n?e:void 0;r({level:`warn`,phase:`ios_runner_detached_start_failed`,data:{code:i?.code,reason:i?.details?.reason,error:e instanceof Error?e.message:String(e)}})}export{p as openRunnerStartBudget,h as raceRunnerStartAgainstCaller,g as reserveRunnerStartOwnerInterest};
@@ -0,0 +1,2 @@
1
+ import{I as e,K as t,P as n}from"./sdk-contracts.js";import{I as r,c as i,g as a,l as o,t as s}from"./host.js";import{c,t as l,u}from"./apple-runner-platform.js";function d(e,t){return{deadline:e!==void 0&&Number.isFinite(e)?s.fromTimeoutMs(Math.max(0,e)):void 0,signal:t}}function f(e,t){let n=e?.deadline;if(!n)return;let r=Math.floor(n.remainingMs());if(r<=0)throw p(t);return r}function p(e){return new n(`COMMAND_FAILED`,`The Apple runner budget ran out before this step began`,{phase:e,reason:`runner_phase_budget_exhausted`,retriable:!0})}function m(e){return e instanceof n&&e.details?.reason===`runner_phase_budget_exhausted`}function h(t){let n=t?.deadline,r=s.fromTimeoutMs(Math.min(45e3,n?n.remainingMs():1/0));return{attemptTimeoutMs:()=>Math.min(l,Math.floor(r.remainingMs())),throwIfCanceled:()=>{if(t?.signal?.aborted)throw e({phase:`apple_toolchain_probe`})}}}let g;function _(){return g??=o({ttlMs:6e5,scheduleExpiry:!0}),g}function v(e,t){let n=h(t);n.throwIfCanceled();let r=y(e),i=_().get(r);if(i)return _().set(r,i),i;let a=x(e,n);if(!a.ok)throw S(a.failures);return _().set(r,a.value),a.value}function y(e){return`${i()??``}\0${e}`}function b(e){return _().get(y(u(c(e),e.kind)))?.xcodeVersion}function x(e,t){let n=E(C(`xcodebuild`,[`-version`],t)),r=C(`xcrun`,[`--sdk`,e,`--show-sdk-version`],t),i=C(`xcrun`,[`--sdk`,e,`--show-sdk-build-version`],t);return!n.ok||!r.ok||!i.ok?{ok:!1,failures:[n,r,i].flatMap(e=>e.ok?[]:[e.failure])}:{ok:!0,value:{xcodeVersion:n.value.version,xcodeBuildVersion:n.value.buildVersion,sdkName:e,sdkVersion:r.value,sdkBuildVersion:i.value}}}function S(e){return new n(`COMMAND_FAILED`,`Could not read the Xcode toolchain versions the Apple runner cache is keyed on (${e.map(e=>`${e.probe}: ${e.detail}`).join(`; `)})`,{reason:`apple_toolchain_probe_unavailable`,retriable:!0,probes:e,hint:"The Apple runner cache is keyed on the toolchain version, so a cache decision cannot be made without it. Retry once the host is less loaded, or check `xcode-select -p` and `xcodebuild -version`."})}function C(e,n,r){let i=[e,...n].join(` `),a;try{a=w(e,n,r)}catch(e){if(r.throwIfCanceled(),t(e)||m(e))throw e;return D(i,`probe_error`,e instanceof Error?e.message:`${e}`)}if(a.exitCode!==0)return D(i,`nonzero_exit`,`exit ${a.exitCode}${a.stderr.trim()?`: ${a.stderr.trim()}`:``}`);let o=a.stdout.trim();return o?{ok:!0,value:o}:D(i,`empty_output`,`no output`)}function w(e,t,n){try{return T(e,t,n)}catch(r){if(!a(r))throw r;return T(e,t,n)}}function T(e,t,n){n.throwIfCanceled();let i=n.attemptTimeoutMs();if(i<=0)throw p(`apple_toolchain_probe`);return r(e,t,{allowFailure:!0,timeoutMs:i,maxBuffer:131072})}function E(e){if(!e.ok)return e;let t=e.value.match(/^Xcode\s+(.+)$/m)?.[1]?.trim(),n=e.value.match(/^Build version\s+(.+)$/m)?.[1]?.trim();return!t||!n?D(`xcodebuild -version`,`unparsable_output`,`unrecognized output: ${e.value.replaceAll(`
2
+ `,` `)}`):{ok:!0,value:{version:t,buildVersion:n}}}function D(e,t,n){return{ok:!1,failure:{probe:e,reason:t,detail:n.length>200?`${n.slice(0,200)}…`:n}}}export{f as i,v as n,d as r,b as t};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{B as t,P as n,rt as r,z as i}from"./sdk-contracts.js";import{k as a}from"./sdk-device.js";import{r as o}from"./touch-runtime.js";import{t as s}from"./runner-cache-metadata.js";import{AsyncLocalStorage as c}from"node:async_hooks";const l=new c;function u(e,t){return{runCommand:e,...t}}function d(e,t,n={}){let r=f(e,n);return m(r?r.provider:t)}function f(e,t={}){let n=l.getStore();return n&&n.deviceId===e.id&&(n.requestId?n.requestId===t.requestId:!t.requestId)?n:void 0}async function p(e,t,n){if(!e)return await n();let r={provider:m(e),deviceId:t.deviceId,requestId:t.requestId};return await l.run(r,n)}function m(e){return typeof e==`function`?{runCommand:e,hasLiveSession:()=>!0}:e}const h=[`tap`,`doubleTap`,`longPress`];function g(e){return typeof e==`string`&&h.includes(e)}function _(e,t){return i(new n(`INVALID_ARGS`,e,{...t,reason:`runner_sequence_invalid`}),`no`)}function v(e,t,n){return _(n,{stepIndex:e,kind:typeof t==`string`?t:void 0})}function y(e){if(!Array.isArray(e)||e.length===0)throw _(`sequence requires at least one step`,{stepCount:Array.isArray(e)?e.length:0});if(e.length>20)throw _(`sequence accepts at most 20 steps, received ${e.length}`,{stepCount:e.length,maxSteps:20});e.forEach((e,t)=>b(e,t))}function b(e,t){if(!g(e.kind))throw v(t,e.kind,`sequence step ${t} has unsupported kind "${String(e.kind)}"; allowed: ${h.join(`, `)}`);if(!Number.isFinite(e.x)||!Number.isFinite(e.y))throw v(t,e.kind,`sequence step ${t} (${e.kind}) requires finite x and y`);e.durationMs!==void 0&&x(e.durationMs,0,1e4,t,e.kind,`durationMs`),e.pauseMs!==void 0&&x(e.pauseMs,0,1e4,t,e.kind,`pauseMs`)}function x(e,t,n,r,i,a){if(!Number.isFinite(e)||e<t||e>n)throw v(r,i,`sequence step ${r} (${i}) ${a} must be between ${t} and ${n}`)}function S(e,t){return y(e),{command:`sequence`,steps:e,appBundleId:t}}async function C(e,n,r,i,a){let o=w(T(e,n,r),20).map(e=>S(e,i)),s,c,l=0,u=[],d=0;for(let e of o){let n;try{n=await a(e)}catch(e){throw t(e,l)}s??=n,c=n;let r;try{r=O(n)}catch(e){throw t(D(e,d),l+E(e))}l+=r.completedSteps,u.push(...r.results),d+=e.steps?.length??0}return{...s??{},completedSteps:l,sequenceResults:u,...c?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:c.gestureEndUptimeMs},timingMode:`runner-sequence`}}function w(e,t,n=2e4){let r=[],i=[],a=0;for(let o of e){let e=(o.durationMs??0)+(o.pauseMs??0)+250;i.length>0&&(i.length>=t||a+e>n)&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}function T(e,t,n){let r=n.doubleTap?`doubleTap`:n.holdMs>0?`longPress`:`tap`,i=r===`tap`&&a(e);return Array.from({length:n.count},(e,a)=>{let[s,c]=o(a,n.jitterPx);return{kind:r,x:t.x+s,y:t.y+c,...i?{synthesized:!0}:{},...n.holdMs>0?{durationMs:n.holdMs}:{},...a<n.count-1&&n.intervalMs>0?{pauseMs:n.intervalMs}:{}}})}function E(e){let t=e instanceof n?e.details?.completedSteps:void 0;return typeof t==`number`?t:0}function D(e,t){if(t===0||!(e instanceof n)||!e.details)return e;let r=e.details.failedStepIndex;if(typeof r!=`number`)return e;let i=e.details.completedSteps;return new n(e.code,e.message,{...e.details,failedStepIndex:r+t,chunkStepIndex:r,...typeof i==`number`?{completedSteps:t+i}:{}},e.cause)}function O(e){let t=A(e.sequenceResults),n=typeof e.completedSteps==`number`&&Number.isFinite(e.completedSteps)?e.completedSteps:t.filter(e=>e.ok).length,r=t.findIndex(e=>!e.ok),i=typeof e.failedStepIndex==`number`&&Number.isFinite(e.failedStepIndex)?e.failedStepIndex:r>=0?r:void 0;if(i!==void 0)throw k(t,n,i);return{results:t,completedSteps:n,failedStepIndex:i}}function k(e,t,i){let a=e[i],o=a?.kind??`step`,s=a?.errorMessage??`sequence step ${i} (${o}) failed`;return new n(r(a?.errorCode),s,{failedStepIndex:i,failedStepKind:o,completedSteps:t,sequenceResults:e,hint:`Run snapshot -i to inspect the current UI, then continue from the observed state.`})}function A(e){return Array.isArray(e)?e.map(e=>{let t=e??{};return{ok:t.ok===!0,kind:typeof t.kind==`string`?t.kind:`unknown`,errorCode:typeof t.errorCode==`string`?t.errorCode:void 0,errorMessage:typeof t.errorMessage==`string`?t.errorMessage:void 0,gestureStartUptimeMs:typeof t.gestureStartUptimeMs==`number`?t.gestureStartUptimeMs:void 0,gestureEndUptimeMs:typeof t.gestureEndUptimeMs==`number`?t.gestureEndUptimeMs:void 0}}):[]}var j=e({IOS_RUNNER_CONTAINER_BUNDLE_IDS:()=>s,withAppleRunnerProvider:()=>p});export{u as a,C as i,S as n,d as o,O as r,p as s,j as t};
1
+ import{r as e}from"./rolldown-runtime.js";import{B as t,P as n,rt as r,z as i}from"./sdk-contracts.js";import{j as a}from"./sdk-device.js";import{r as o}from"./touch-runtime.js";import{t as s}from"./runner-cache-metadata.js";import{AsyncLocalStorage as c}from"node:async_hooks";const l=new c;function u(e,t){return{runCommand:e,...t}}function d(e,t,n={}){let r=f(e,n);return m(r?r.provider:t)}function f(e,t={}){let n=l.getStore();return n&&n.deviceId===e.id&&(n.requestId?n.requestId===t.requestId:!t.requestId)?n:void 0}async function p(e,t,n){if(!e)return await n();let r={provider:m(e),deviceId:t.deviceId,requestId:t.requestId};return await l.run(r,n)}function m(e){return typeof e==`function`?{runCommand:e,hasLiveSession:()=>!0}:e}const h=[`tap`,`doubleTap`,`longPress`];function g(e){return typeof e==`string`&&h.includes(e)}function _(e,t){return i(new n(`INVALID_ARGS`,e,{...t,reason:`runner_sequence_invalid`}),`no`)}function v(e,t,n){return _(n,{stepIndex:e,kind:typeof t==`string`?t:void 0})}function y(e){if(!Array.isArray(e)||e.length===0)throw _(`sequence requires at least one step`,{stepCount:Array.isArray(e)?e.length:0});if(e.length>20)throw _(`sequence accepts at most 20 steps, received ${e.length}`,{stepCount:e.length,maxSteps:20});e.forEach((e,t)=>b(e,t))}function b(e,t){if(!g(e.kind))throw v(t,e.kind,`sequence step ${t} has unsupported kind "${String(e.kind)}"; allowed: ${h.join(`, `)}`);if(!Number.isFinite(e.x)||!Number.isFinite(e.y))throw v(t,e.kind,`sequence step ${t} (${e.kind}) requires finite x and y`);e.durationMs!==void 0&&x(e.durationMs,0,1e4,t,e.kind,`durationMs`),e.pauseMs!==void 0&&x(e.pauseMs,0,1e4,t,e.kind,`pauseMs`)}function x(e,t,n,r,i,a){if(!Number.isFinite(e)||e<t||e>n)throw v(r,i,`sequence step ${r} (${i}) ${a} must be between ${t} and ${n}`)}function S(e,t){return y(e),{command:`sequence`,steps:e,appBundleId:t}}async function C(e,n,r,i,a){let o=w(T(e,n,r),20).map(e=>S(e,i)),s,c,l=0,u=[],d=0;for(let e of o){let n;try{n=await a(e)}catch(e){throw t(e,l)}s??=n,c=n;let r;try{r=O(n)}catch(e){throw t(D(e,d),l+E(e))}l+=r.completedSteps,u.push(...r.results),d+=e.steps?.length??0}return{...s??{},completedSteps:l,sequenceResults:u,...c?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:c.gestureEndUptimeMs},timingMode:`runner-sequence`}}function w(e,t,n=2e4){let r=[],i=[],a=0;for(let o of e){let e=(o.durationMs??0)+(o.pauseMs??0)+250;i.length>0&&(i.length>=t||a+e>n)&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}function T(e,t,n){let r=n.doubleTap?`doubleTap`:n.holdMs>0?`longPress`:`tap`,i=r===`tap`&&a(e);return Array.from({length:n.count},(e,a)=>{let[s,c]=o(a,n.jitterPx);return{kind:r,x:t.x+s,y:t.y+c,...i?{synthesized:!0}:{},...n.holdMs>0?{durationMs:n.holdMs}:{},...a<n.count-1&&n.intervalMs>0?{pauseMs:n.intervalMs}:{}}})}function E(e){let t=e instanceof n?e.details?.completedSteps:void 0;return typeof t==`number`?t:0}function D(e,t){if(t===0||!(e instanceof n)||!e.details)return e;let r=e.details.failedStepIndex;if(typeof r!=`number`)return e;let i=e.details.completedSteps;return new n(e.code,e.message,{...e.details,failedStepIndex:r+t,chunkStepIndex:r,...typeof i==`number`?{completedSteps:t+i}:{}},e.cause)}function O(e){let t=A(e.sequenceResults),n=typeof e.completedSteps==`number`&&Number.isFinite(e.completedSteps)?e.completedSteps:t.filter(e=>e.ok).length,r=t.findIndex(e=>!e.ok),i=typeof e.failedStepIndex==`number`&&Number.isFinite(e.failedStepIndex)?e.failedStepIndex:r>=0?r:void 0;if(i!==void 0)throw k(t,n,i);return{results:t,completedSteps:n,failedStepIndex:i}}function k(e,t,i){let a=e[i],o=a?.kind??`step`,s=a?.errorMessage??`sequence step ${i} (${o}) failed`;return new n(r(a?.errorCode),s,{failedStepIndex:i,failedStepKind:o,completedSteps:t,sequenceResults:e,hint:`Run snapshot -i to inspect the current UI, then continue from the observed state.`})}function A(e){return Array.isArray(e)?e.map(e=>{let t=e??{};return{ok:t.ok===!0,kind:typeof t.kind==`string`?t.kind:`unknown`,errorCode:typeof t.errorCode==`string`?t.errorCode:void 0,errorMessage:typeof t.errorMessage==`string`?t.errorMessage:void 0,gestureStartUptimeMs:typeof t.gestureStartUptimeMs==`number`?t.gestureStartUptimeMs:void 0,gestureEndUptimeMs:typeof t.gestureEndUptimeMs==`number`?t.gestureEndUptimeMs:void 0}}):[]}var j=e({IOS_RUNNER_CONTAINER_BUNDLE_IDS:()=>s,withAppleRunnerProvider:()=>p});export{u as a,C as i,S as n,d as o,O as r,p as s,j as t};
@@ -0,0 +1 @@
1
+ import{P as e}from"./sdk-contracts.js";import{E as t}from"./sdk-device.js";import{nn as n}from"./sdk-batch.js";const r={support:`supported`},i={support:`unsupported`},a={lease:r,inventory:{support:`partial`,note:`Inventory exposes only the leased cloud device, not the provider catalog.`},install:{support:`partial`,note:`Requires provider-specific upload or a path visible to the remote Appium server.`},snapshot:{support:`partial`,note:`Uses Appium page source XML, not agent-device native snapshot backends.`},screenshot:r,tap:r,doubleTap:r,longPress:r,swipe:r,scroll:{support:`partial`,note:`Implemented as viewport-relative W3C pointer gestures.`},fill:r,type:r,keyboard:{support:`partial`,note:"Enter presses Android keycode 66 through `mobile: pressKey` and types a newline into the focused iOS field; dismiss uses the Appium hide-keyboard route, and Android status uses the Appium keyboard probe."},back:r,home:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},orientation:{support:`partial`,note:`Uses the WebDriver rotation/orientation endpoints; four-way rotation collapses to portrait/landscape on drivers that only accept the two-way endpoint. Rotates the current display, so an activity that does not pin its orientation may need rotating again once it is foreground.`},appSwitcher:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},tvRemote:i,"clipboard.read":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},"clipboard.write":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},settings:i,alert:i,pinch:i,rotateGesture:i,transformGesture:i,logs:i,record:i,artifacts:i,portReverse:i,nativeSnapshotBackend:{support:`unsupported`,note:`Cloud WebDriver cannot upload or run agent-device native runner/helper backends.`}};function o(e){return{provider:e.provider,platform:e.platform,snapshotBackend:e.platform===`ios`?`xctest`:`android`,snapshotSource:`appium-page-source`,operations:l(a,e.overrides)}}function s(e,t){return e.operations[t].support!==`unsupported`}function c(e,t){let n=e.operations[t],r=n.note?` ${n.note}`:``;return`${e.provider} WebDriver runtime does not support ${t}.${r}`}function l(e,t){let n={...e};for(let[r,i]of Object.entries(t??{}))n[r]=typeof i==`string`?{...e[r],support:i}:{...e[r],...i};return n}function u(e,t,n={}){return{platformName:e===`ios`?`iOS`:`Android`,"appium:deviceName":t,...n}}function d(e,t){let n=e?.bundleId??t?.appIdentifierHint,r=e?.packageName??t?.packageNameHint;return{bundleId:n,packageName:r,appName:e?.appName,launchTarget:p(e?.launchTarget,n,r)}}function f(e){return e===`ios`?`xctest`:`android`}function p(...e){return e.find(e=>e!==void 0)}const m=n(`owner-capability-missing`,`The WebDriver provider session is no longer active for this device.`);function h(e){let t=async(t,n,r,i,a)=>{let o=e.findSessionForDevice(t);if(!o)return;let s=await _(e,o,t,n,r.uploadPath,i,a);return await o.client.installApp(s?.appReference??r.appPath,a),d(s,i)},n=async(e,n,r,i,a)=>await t(e,n,{appPath:r,uploadPath:r},i,a);return Object.freeze({fact:t=>g(e.findSessionForDevice(t)),installApp:n,installInstallablePath:async(e,t,r,i)=>await n(e,``,t,r,i),deployApp:async(e,t,r)=>v(await n(e,t.app,t.appPath,{relaunch:t.replaceExisting,appIdentifierHint:t.app,packageNameHint:t.app},r),t.app),deployMaterializedApp:async(e,n,r)=>v(await t(e,``,{appPath:n.artifact.installablePath,uploadPath:n.artifact.uploadPath??n.artifact.installablePath},{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r))})}function g(e){return e?s(e.capabilities,`install`)?Object.freeze({available:!0}):n(`owner-capability-missing`,c(e.capabilities,`install`)):m}async function _(n,r,i,a,o,l,u){if(!s(r.capabilities,`install`))throw new e(`UNSUPPORTED_OPERATION`,c(r.capabilities,`install`),{provider:n.provider,deviceId:i.id,platform:t(i)});let d=r.prepared.uploadApp??n.uploadApp;if(d)return await d({provider:n.provider,lease:r.lease,device:i,app:a,appPath:o,options:l,signal:u})}function v(t,n){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session no longer supports app deployment.`);return{...t.bundleId?{bundleId:t.bundleId}:{},...t.packageName?{packageName:t.packageName}:{},...t.appName?{appName:t.appName}:{},...t.launchTarget??n?{launchTarget:t.launchTarget??n}:{}}}export{s as a,u as i,m as n,o,f as r,c as s,h as t};