agent-device 0.21.19 → 0.21.20

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 (114) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.19.apk → agent-device-android-ime-helper-0.21.20.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.20.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.19.manifest.json → agent-device-android-ime-helper-0.21.20.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.19.apk → agent-device-android-snapshot-helper-0.21.20.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.20.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.19.manifest.json → agent-device-android-snapshot-helper-0.21.20.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +12 -0
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -14
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +14 -16
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +40 -14
  11. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +20 -5
  12. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +2 -15
  13. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +10 -25
  14. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +1 -18
  15. package/dist/src/adapter.js +1 -1
  16. package/dist/src/adb-failure.js +1 -1
  17. package/dist/src/agent-browser-process-record.js +1 -1
  18. package/dist/src/agent-browser-provider.js +1 -1
  19. package/dist/src/agent-browser-tool.js +1 -1
  20. package/dist/src/agent-device-client.js +2 -2
  21. package/dist/src/alert-runtime.js +1 -1
  22. package/dist/src/alert.js +1 -0
  23. package/dist/src/android-input-ownership.js +1 -1
  24. package/dist/src/app-launch.js +2 -2
  25. package/dist/src/app-lifecycle.js +1 -1
  26. package/dist/src/app-resolution.js +2 -2
  27. package/dist/src/apple-runner-platform.js +1 -1
  28. package/dist/src/archive.js +2 -2
  29. package/dist/src/browser-launch.js +1 -1
  30. package/dist/src/cache.js +1 -1
  31. package/dist/src/cli-config.js +1 -1
  32. package/dist/src/cli-help.js +287 -301
  33. package/dist/src/cli-runner.js +1 -1
  34. package/dist/src/cli.js +1 -1
  35. package/dist/src/client-metro-companion.js +1 -1
  36. package/dist/src/client-metro.js +1 -1
  37. package/dist/src/client-types.d.ts +14 -2
  38. package/dist/src/{scroll-command.d.ts → cloud-artifacts.d.ts} +242 -238
  39. package/dist/src/command-schema.js +3 -3
  40. package/dist/src/command-tools.js +2 -2
  41. package/dist/src/command.js +1 -1
  42. package/dist/src/config.js +1 -1
  43. package/dist/src/connection-runtime.js +1 -1
  44. package/dist/src/daemon-client-lifecycle.js +1 -1
  45. package/dist/src/daemon-client-transport.js +1 -1
  46. package/dist/src/daemon-registration.js +1 -1
  47. package/dist/src/debug-symbols-facade.js +3 -3
  48. package/dist/src/device-rotation.js +1 -1
  49. package/dist/src/devicectl.js +1 -1
  50. package/dist/src/display-inventory.js +1 -1
  51. package/dist/src/exec.js +1 -1
  52. package/dist/src/hdc.js +1 -1
  53. package/dist/src/helper.js +2 -2
  54. package/dist/src/host.js +1 -1
  55. package/dist/src/index.d.ts +1 -1
  56. package/dist/src/interactor.js +5 -5
  57. package/dist/src/interactor2.js +1 -1
  58. package/dist/src/internal/bin.js +1 -1
  59. package/dist/src/internal/daemon.js +2 -2
  60. package/dist/src/launch-confirmation.js +1 -0
  61. package/dist/src/limrun-runtime-dependencies.js +1 -1
  62. package/dist/src/limrun.d.ts +50 -42
  63. package/dist/src/mechanics.js +16 -16
  64. package/dist/src/owner-identity.js +1 -1
  65. package/dist/src/perf-facade.js +1 -1
  66. package/dist/src/perf-target.js +1 -1
  67. package/dist/src/physical-device-control.js +1 -1
  68. package/dist/src/platform-runtime-android-adb-host.js +1 -1
  69. package/dist/src/platform-runtime-app-log-process.js +1 -1
  70. package/dist/src/platform-runtime-host.js +1 -1
  71. package/dist/src/platform-runtime-operation-host.js +2 -2
  72. package/dist/src/platform-runtime-runtime-hints.js +1 -1
  73. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  74. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  75. package/dist/src/provider-session-ownership.js +1 -1
  76. package/dist/src/provider-webdriver.js +1 -1
  77. package/dist/src/registry.js +20 -4
  78. package/dist/src/result-serialization.js +1 -1
  79. package/dist/src/runner-cache-metadata.js +3 -3
  80. package/dist/src/runner-client.js +1 -1
  81. package/dist/src/runner-dev-tools-security.js +1 -1
  82. package/dist/src/runner-device-readiness.js +1 -1
  83. package/dist/src/runner-disposal.js +1 -1
  84. package/dist/src/runner-error-classification.js +1 -1
  85. package/dist/src/runner-exchange.js +1 -1
  86. package/dist/src/runner-operations-facade.js +1 -1
  87. package/dist/src/runner-session-types.js +1 -1
  88. package/dist/src/runner-start-budget.js +1 -1
  89. package/dist/src/runner-startup-transport.js +1 -1
  90. package/dist/src/runner-xctestrun.js +1 -1
  91. package/dist/src/runtime.js +1 -1
  92. package/dist/src/runtime10.js +1 -1
  93. package/dist/src/runtime2.js +1 -1
  94. package/dist/src/runtime4.js +5 -5
  95. package/dist/src/screenshot-result.js +1 -1
  96. package/dist/src/screenshot-runtime.js +1 -1
  97. package/dist/src/screenshot3.js +1 -1
  98. package/dist/src/sdk-contracts.d.ts +2 -0
  99. package/dist/src/sdk-contracts.js +2 -2
  100. package/dist/src/sdk-selectors.d.ts +4 -4
  101. package/dist/src/session2.js +1 -1
  102. package/dist/src/simulator-boot.js +1 -1
  103. package/dist/src/simulator.js +1 -1
  104. package/dist/src/snapshot-runtime.js +1 -1
  105. package/dist/src/tool-provider.js +3 -3
  106. package/dist/src/tool-provider2.js +1 -1
  107. package/dist/src/tool-provider3.js +1 -1
  108. package/dist/src/toolchain-probe.js +1 -1
  109. package/dist/src/update-check.js +1 -1
  110. package/dist/src/video.js +1 -1
  111. package/package.json +1 -1
  112. package/server.json +2 -2
  113. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.19.apk.sha256 +0 -1
  114. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.19.apk.sha256 +0 -1
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{B as t,F as n,G as r,N as i,P as a,R as o}from"./sdk-contracts.js";import{_ as s}from"./sdk-batch-runner.js";import{d as c,p as l}from"./sdk-device.js";import{o as u}from"./sdk-remote-config.js";import{c as d,r as f}from"./diagnostics.js";import{C as p,k as m,m as h,p as g,t as _,v,w as ee,x as te}from"./owner-identity.js";import{a as ne,f as re,l as ie,m as ae,p as oe,r as se}from"./exec.js";import{n as ce,t as le}from"./file.js";import"./diagnostics2.js";import"./command.js";import{o as ue}from"./device-shell.js";import"./process.js";import{i as de,n as fe,r as pe}from"./retry.js";import{a as me,r as he}from"./version.js";import{t as ge}from"./ttl-memo.js";import{n as _e,t as ve}from"./boot-diagnostics.js";import{t as ye}from"./keyed-lock.js";import{i as be,r as xe}from"./request-cancel.js";import{t as Se}from"./request.js";import{a as Ce,o as we,r as Te}from"./tool-provider.js";import{t as Ee}from"./physical-device-control.js";import{a as De,o as Oe}from"./runner.js";import{A as ke,F as Ae,H as je,M as Me,a as Ne,g as Pe,l as y,r as Fe,t as Ie,u as Le,x as Re}from"./host.js";import{o as ze,s as b}from"./apple-runner-platform.js";import{c as Be,i as x,l as Ve,m as He,p as Ue,t as We}from"./runner-cache-metadata.js";import{t as Ge}from"./plist-xml.js";import{n as Ke,t as qe}from"./runner-owner-state.js";import{l as Je,n as Ye}from"./simctl.js";import{_ as Xe,a as Ze,b as Qe,c as $e,d as et,g as tt,h as nt,i as rt,l as it,n as at,o as ot,p as st,r as ct,s as lt,t as ut,v as dt,x as ft,y as pt}from"./runner-session-types.js";import{i as mt,r as ht,t as S}from"./runner-startup-transport.js";import{A as gt,D as _t,E as vt,N as C,O as yt,S as bt,_ as xt,a as w,b as T,f as St,g as Ct,h as wt,i as Tt,j as E,k as Et,l as Dt,n as Ot,o as kt,u as At,v as jt,w as D}from"./runner-error-classification.js";import{c as Mt,d as Nt,s as Pt,t as Ft}from"./runner-xctestrun.js";import{_ as It,a as Lt,c as Rt,d as zt,f as Bt,g as Vt,i as Ht,l as Ut,m as Wt,n as Gt,o as Kt,p as qt,r as Jt,t as O,u as Yt,v as Xt,y as k}from"./runner-disposal.js";import Zt from"node:path";import A from"node:fs";const Qt={runCmdStreaming:re,runCmdSync:oe,runCmdBackground:ie,requireExecSuccess:ne,isCommandTimeoutError:se,shellQuote:ue,emitDiagnostic:f,withDiagnosticTimer:d,retryWithPolicy:de,isEnvTruthy:pe,deadlineFromTimeoutMs:(e,t)=>fe.fromTimeoutMs(e,t),isProcessAlive:g,isProcessGroupAlive:h,readProcessStartTime:p,readProcessCommand:te,signalPidsBestEffort:ee,signalProcessGroupBestEffort:ae,findProjectRoot:he,readVersion:me,acquireProcessLock:le,withProcessLock:ce,withKeyedLock:ye,publishFileSync:m,classifyOwnerLiveness:_,readHostCpuArchSync:v,createTtlMemo:ge,parseBooleanLiteral:u,isRecord:s,emitRequestProgress:Se,getRequestSignal:xe,isRequestCanceled:be,classifyBootFailure:_e,bootFailureHint:ve,runAppleToolCommand:Ce,runXcrun:we,readApplePlistJson:Te,buildSimctlArgsForDevice:Ye,simulatorAddressFor:Je,resolveIosPhysicalDeviceControl:Ee,visitXmlPlistEntries:Ge,leaseOwnerStateDir:Ke,hasDeviceClaimAuthority:e=>qe()?.(e)??!1};function $t(e=process.env){return Re(e.AGENT_DEVICE_IOS_RUNNER_DETACH??``)!==!1}async function en(e,t){if(!$t())return null;let n=b(e),r=(t,r)=>(y({level:`debug`,phase:`ios_runner_lease_adoption_skipped`,data:{deviceId:e.id,lane:n.handoff?n.lane:void 0,runnerPid:r?.runnerPid,port:r?.port,reason:t}}),null);if(!n.handoff)return r(n.reason);let i=Wt(e.id);if(i.type===`absent`)return r(`lease_absent`);if(i.type===`refused`)return r(i.reason,i.lease);let a=i.lease;if(a.simulatorSetPath!==et(e))return r(`simulator_set_mismatch`,a);let o=tn(a,t.expectedRunnerSessionId);if(`refusal`in o)return r(o.refusal,a);let s=nn(e,a,t.budget);if(`refusal`in s)return r(s.refusal,a);let c=o.value,l=s.value,u=await rn(e,a.port,n.lane,t.budget);if(u!==`answered`)return r(u,a);if(!Bt(a,c))return r(`runner_pid_recycled`,a);let d=sn(e,a,c,l);try{k(d.lease)}catch{return r(`lease_write_failed`,a)}return y({level:`info`,phase:`ios_runner_lease_adopted`,data:{deviceId:e.id,lane:n.lane,sessionId:d.sessionId,runnerPid:c,port:a.port,previousOwnerPid:a.ownerPid}}),d}function tn(e,t){if(t!==void 0&&e.sessionId!==t)return{refusal:`session_identity_mismatch`};let n=e.runnerPid;return n?Pe(n)?It(e,n)?{value:n}:{refusal:`runner_pid_recycled`}:{refusal:`runner_process_dead`}:{refusal:`runner_pid_missing`}}function nn(e,t,n){let r=on(e,n);return r?t.xctestrunPath.startsWith(`${r}${Zt.sep}`)?{value:r}:{refusal:`artifact_fingerprint_mismatch`}:{refusal:`expected_derived_unresolved`}}async function rn(e,t,n,i){let a=n===`physical_coredevice`?5e3:500,o=an(i,a);if(o<=0)return`probe_budget_exhausted`;let s=Date.now(),c=!1;try{let n=await mt(e,t,C({command:`uptime`}),o,i?.signal);return c=Et(yt(await n.text())),c?`answered`:`probe_failed`}catch(e){if(r(e))throw e;return`probe_failed`}finally{y({level:`debug`,phase:`ios_runner_lease_adoption_probe`,durationMs:Date.now()-s,data:{deviceId:e.id,port:t,lane:n,budgetCapMs:a,timeoutMs:o,answered:c}})}}function an(e,t){return e?.deadline?Math.min(t,Math.floor(e.deadline.remainingMs())):t}function on(e,t){try{return Ue(e,Ve(e,void 0,t))}catch(e){if(r(e))throw e;return null}}function sn(e,t,n,r){let i=t.sessionId,a={xctestrunPath:t.xctestrunPath,derived:r,cache:`exact`,artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`,reason:`adopted_from_lease`},{child:o,wait:s}=cn(n);return{sessionId:i,device:e,deviceId:e.id,port:t.port,xctestrunPath:t.xctestrunPath,xctestrunArtifact:a,jsonPath:t.jsonPath,testPromise:s,child:o,runnerLogPath:t.runnerLogPath,state:`ready`,commandCharges:new ut,lease:Yt({device:e,sessionId:i,runnerPid:n,port:t.port,xctestrunPath:t.xctestrunPath,jsonPath:t.jsonPath,runnerLogPath:t.runnerLogPath})}}function cn(e){let t={pid:e,exitCode:null};return{child:t,wait:new Promise(n=>{let r=setInterval(()=>{Pe(e)||(clearInterval(r),t.exitCode=-1,n({stdout:``,stderr:``,exitCode:-1}))},1e3);r.unref?.()})}}function ln(){let e=new AbortController,t=!1,n=``;return{wake:e.signal,observe:r=>{if(t)return;let i=n+r;if(i.includes(`AGENT_DEVICE_RUNNER_LISTENER_READY`)){t=!0,n=``,e.abort();return}n=i.slice(-33)},finish:()=>{t=!0,n=``,e.abort()}}}function un(e){let t=e.logPath;A.mkdirSync(Zt.dirname(t),{recursive:!0});let n=A.openSync(t,`a`),r=nt(t,n),i=dn(()=>{try{A.closeSync(n)}catch{}}),a=ln();try{let t=Me(`xcodebuild`,[`test-without-building`,`-only-testing`,`AgentDeviceRunnerUITests/RunnerTests/testCommand`,`-parallel-testing-enabled`,`NO`,`-test-timeouts-enabled`,`NO`,`-collect-test-diagnostics`,`never`,He(e.device),`1`,`-destination-timeout`,`20`,`-xctestrun`,e.xctestrunPath,`-derivedDataPath`,e.derivedPath,...st(e.device,ze(e.device))],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(e.port)},detached:!0,signal:e.signal,stdio:[`ignore`,n,n],captureOutput:!1}),o=ft({file:r,onOutput:t=>{a.observe(t),(e.traceLogPath||e.verbose)&&dt(t,void 0,e.traceLogPath,e.verbose)}}),s=dn(()=>{o.stop(),i()}),c=()=>{o.drain(),i(),a.finish()};return t.wait.then(c,c),{...t,startupRetryWake:a.wake,endOutputObservation:s,readLogTail:e=>pt(r,e)}}catch(e){throw i(),e}}function dn(e){let t=!1;return()=>{t||(t=!0,e())}}const j=new Map,fn=new Map,M=new Map,pn=1e4;function N(e,t){return je(fn,e,t)}async function P(e,t){R(e.id);let n=N(e.id,async()=>{let{openRunnerStartBudget:n}=await import(`./runner-start-budget.js`),r=n(t);try{let n=j.get(e.id);if(n){gn(n,t.expectedRunnerSessionId);let i=await bn(e,n,r.phase);if(i)return i}return await Xt(e.id,async()=>await hn(e,t,r))}catch(e){throw r.exhausted.aborted?r.exhausted.reason:e}finally{r.close()}}),{raceRunnerStartAgainstCaller:r}=await import(`./runner-start-budget.js`);return await r(n,t.signal)}const mn=1e4;async function hn(e,t,r){let i={},a=r.phase,o=a.signal,s=Bn(t.runnerLeaseContext,e.id);y({level:`debug`,phase:`ios_runner_session_startup`,data:{deviceId:e.id,logicalLeaseContext:s}});let c=await V(i,`adopt_detached_runner`,async()=>await en(e,{budget:a,expectedRunnerSessionId:t.expectedRunnerSessionId}));if(c)return c.startupTimings=i,c.logicalLeaseContext=s,j.set(e.id,c),c;_n(t.expectedRunnerSessionId),await V(i,`cleanup_stale_xcodebuild`,async()=>{await qt(e,Kt,s)}),await V(i,`ensure_booted`,async()=>{await Pn(e)});let l=await V(i,`verify_device_readiness`,async()=>await(await import(`./runner-device-readiness.js`)).preflightIosRunnerDeviceReadiness(e,{budgetMs:Math.min(mn,a.deadline?.remainingMs()??mn),signal:o}));await V(i,`verify_host_dev_tools_security`,async()=>{let{assertDevToolsSecurityForIosRunner:t}=await import(`./runner-dev-tools-security.js`);await t(e)}),t.cleanStaleBundles?await V(i,`cleanup_stale_bundles`,async()=>{await xn(e)}):(i.cleanup_stale_bundles=0,y({level:`debug`,phase:`ios_runner_startup_cleanup_stale_bundles_skipped`}));let u,d,f,p,m=Qe(t.logPath,e.id),h;try{u=await V(i,`ensure_xctestrun`,async()=>await Ft(e,{...t,budget:x(Ln(t,r),o)})),i.build_xctestrun=u.buildMs,d=await V(i,`allocate_port`,async()=>await Xe()),{xctestrunPath:f,jsonPath:p}=await V(i,`prepare_xctestrun_env`,async()=>await Mt(u.xctestrunPath,{AGENT_DEVICE_RUNNER_PORT:String(d)},Pt({deviceId:e.id,ownerToken:Vt(),port:d}),{iosXctestEnvDir:t.iosXctestEnvDir})),u.buildMs>0&&Le({type:`command`,status:`progress`,message:`Starting XCTest runner...`}),h=await V(i,`launch_xcodebuild`,async()=>(await tt(m).catch(()=>{}),await un({device:e,port:d,xctestrunPath:f,derivedPath:u.derived,signal:o,logPath:m,traceLogPath:t.traceLogPath,verbose:t.verbose})))}catch(e){throw Tt(e,l)}let g=ct(e.id,d),_=Yt({device:e,sessionId:g,runnerPid:h.child.pid,port:d,xctestrunPath:f,jsonPath:p,runnerLogPath:m}),v={sessionId:g,device:e,deviceId:e.id,port:d,xctestrunPath:f,xctestrunArtifact:u,jsonPath:p,runnerLogPath:m,testPromise:h.wait,child:h.child,endOutputObservation:h.endOutputObservation,readLogTail:h.readLogTail,state:`starting`,commandCharges:new ut,startupRetryWake:h.startupRetryWake,launchDeadline:Ie.fromTimeoutMs(Rn(r)),startupTimings:i,startupDeviceStates:l,logicalLeaseContext:s,lease:_,speculative:t.speculative===!0};if(o?.aborted)throw await Ht(v,{graceful:!1,waitTimeoutMs:O,leaseLockHeld:!0}),n();try{k(_)}catch(t){throw await L(e.id,v,{graceful:!1,waitTimeoutMs:O,leaseLockHeld:!0}),t}return j.set(e.id,v),v}function gn(e,t){if(t!==void 0&&e.sessionId!==t)throw vn()}function _n(e){if(e!==void 0)throw vn()}function vn(){return new i(`COMMAND_FAILED`,`Apple runner session ownership changed before command dispatch`,{reason:`runner_session_ownership_changed`})}async function yn(e,t){let n=wn(t);return n===`gone`?(await V({},`stop_stale_session`,async()=>{await L(e.id,t,{graceful:!1,waitTimeoutMs:O})}),!1):n!==`starting`&&n!==`ready`?!1:n===`starting`&&t.launchDeadline?.isExpired()?(y({level:`warn`,phase:`ios_runner_session_invalidated`,data:{deviceId:e.id,sessionId:t.sessionId,reason:`runner_launch_budget_exhausted`}}),await V({},`stop_expired_starting_session`,async()=>{await L(e.id,t,{graceful:!1,waitTimeoutMs:O})}),!1):it(t.device,e)?!0:(await V({},`stop_other_simulator_set_session`,async()=>{await L(e.id,t)}),!1)}async function bn(e,t,n){if(!await yn(e,t))return null;let r=t.xctestrunArtifact;if(r?.cache===`external`)return y({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.state===`ready`,cache:r.cache,logicalLeaseContext:t.logicalLeaseContext}}),t;let i=Ue(e,Ve(e,void 0,n));return r?.derived===i?(y({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.state===`ready`,logicalLeaseContext:t.logicalLeaseContext}}),t):(y({level:`debug`,phase:`ios_runner_session_artifact_stale`,data:{deviceId:e.id,sessionId:t.sessionId,currentDerived:r?.derived,expectedDerived:i}}),await V({},`stop_stale_artifact_session`,async()=>{await L(e.id,t)}),null)}async function xn(e){e.kind===`simulator`&&await Promise.allSettled(We.map(async t=>{let n=await Sn(e,t);!n||Cn(n)}))}async function Sn(e,t){try{return await Ae(Ne(e,[`uninstall`,e.id,t]),{allowFailure:!0,timeoutMs:pn})}catch(n){y({level:`warn`,phase:`ios_runner_startup_cleanup_stale_bundle_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:pn,error:n instanceof Error?n.message:String(n)}});return}}function Cn(e){if(e.exitCode===0)return!0;let t=`${e.stdout}\n${e.stderr}`.toLowerCase();return t.includes(`not installed`)||t.includes(`found nothing`)||t.includes(`no such file`)||t.includes(`invalid device`)||t.includes(`could not find`)}function F(e){let t=j.get(e);return t?{sessionId:t.sessionId,liveness:wn(t)}:null}function wn(e){return $e({state:e.state,processRunning:Lt(e.child.pid)})}async function I(e,t){await N(e.deviceId,async()=>{j.get(e.deviceId)===e&&rt(e)&&(y({level:`warn`,phase:`ios_runner_session_invalidated`,data:{deviceId:e.deviceId,sessionId:e.sessionId,reason:t}}),await L(e.deviceId,e,{graceful:!1,waitTimeoutMs:O}))})}async function L(e,t,n={}){let r=t??j.get(e);r&&rt(r)&&(await Ht(r,n),j.get(e)===r&&j.delete(e))}function Tn(e){R(e);let t=En();if(t<=0||!j.has(e))return;let n=setTimeout(()=>{M.delete(e),y({level:`info`,phase:`ios_runner_idle_stop`,data:{deviceId:e,idleMs:t}}),z(e).catch(t=>{y({level:`warn`,phase:`ios_runner_idle_stop_failed`,data:{deviceId:e,error:t instanceof Error?t.message:String(t)}})})},t);n.unref?.(),M.set(e,n),y({level:`debug`,phase:`ios_runner_idle_stop_scheduled`,data:{deviceId:e,idleMs:t}})}function R(e){let t=M.get(e);t&&(clearTimeout(t),M.delete(e))}function En(e=process.env){let t=e.AGENT_DEVICE_IOS_RUNNER_IDLE_STOP_MS?.trim();if(t){let e=Number(t);if(Number.isFinite(e)&&e>=0)return Math.floor(e)}return 3e5}function Dn(e,t){e.speculative&&!bt(t)&&(e.speculative=!1)}async function On(e){return await N(e,async()=>{let t=j.get(e);return t?.speculative?(y({level:`debug`,phase:`ios_runner_speculative_released`,data:{deviceId:e,sessionId:t.sessionId,ready:t.state===`ready`}}),await z(e),!0):!1})}async function z(e){R(e),await N(e,async()=>{await Xt(e,async()=>{await L(e,void 0,{leaseLockHeld:!0}),await Jt(e)})})}async function kn(e,t){let n=j.get(e);if(t.retain&&!Ze(n)){Tn(e);return}t.retain&&y({level:`info`,phase:`ios_runner_retain_skipped_busy`,data:{deviceId:e}}),await z(e)}async function An(){let e=Array.from(j.values());await Gt(e);for(let t of e)j.get(t.deviceId)===t&&j.delete(t.deviceId)}async function jn(){if(!$t())return 0;let e=0;for(let[t,n]of j){let r=Mn(t,n);if(!r.detached){y({level:`debug`,phase:`ios_runner_session_detach_skipped`,data:{deviceId:t,sessionId:n.sessionId,lane:r.lane,reason:r.reason,outstandingCharges:n.commandCharges.outstandingChargeCount,hasAbandonedCharges:n.commandCharges.hasAbandonedCharges}});continue}e+=1,y({level:`info`,phase:`ios_runner_session_detached`,data:{deviceId:t,lane:r.lane,sessionId:n.sessionId,runnerPid:n.child.pid,port:n.port,runnerLogPath:n.runnerLogPath}})}return e}function Mn(e,t){let n=b(t.device);if(!n.handoff)return{detached:!1,lane:void 0,reason:n.reason};let r=n.lane,i=lt(t);if(!i.detach)return{detached:!1,lane:r,reason:i.reason};let a=t.lease;if(!a)return{detached:!1,lane:r,reason:`lease_absent`};if(!Lt(t.child.pid))return{detached:!1,lane:r,reason:`runner_process_dead`};try{k(Ut(a))}catch{return{detached:!1,lane:r,reason:`lease_write_failed`}}return t.endOutputObservation?.(),j.delete(e),R(e),at(t,`stopped`),{detached:!0,lane:r}}async function Nn(){await An();let e=Array.from(j.keys());await Promise.allSettled(e.map(async e=>{await z(e)})),await Rt()}function Pn(e){return e.kind===`simulator`?e.booted?(y({level:`debug`,phase:`ios_runner_startup_ensure_booted_skipped`,data:{deviceId:e.id}}),Promise.resolve()):Fn(e):Promise.resolve()}async function Fn(e){await Ae(Ne(e,[`bootstatus`,e.id,`-b`]),{timeoutMs:S})}function In(e){if(!c(e.platform))throw new i(`UNSUPPORTED_PLATFORM`,`Unsupported platform for iOS runner: ${e.platform}`);if(e.kind!==`simulator`&&e.kind!==`device`)throw new i(`UNSUPPORTED_OPERATION`,`Unsupported iOS device kind for runner: ${e.kind}`)}async function B(e,t,n,r,i,a){zn(t,n.command);let{executeRunnerExchange:o}=await import(`./runner-exchange.js`);return o(e,t,n,r,i,e=>I(t,e),a)}function Ln(e,t){let n=Be(t.phase,`runner_xctestrun_build`)??t.timeoutMs,r=ot(e.buildTimeoutMs);return r===void 0?n:Math.min(r,n)}function Rn(e){let t=Math.floor(e.phase.deadline?.remainingMs()??e.timeoutMs);return e.explicit?t:Math.min(S,t)}async function V(e,t,n){let r=Date.now();try{return await n()}finally{let n=Date.now()-r;e[t]=n,y({level:`debug`,phase:`ios_runner_startup_${t}`,durationMs:n})}}function zn(e,t){if(e.startupTimingsReported||!e.startupTimings)return;e.startupTimingsReported=!0;let n=Object.values(e.startupTimings).reduce((e,t)=>e+t,0);y({level:`info`,phase:`ios_runner_session_startup_timings`,durationMs:n,data:{command:t,sessionId:e.sessionId,ready:e.state===`ready`,logicalLeaseContext:e.logicalLeaseContext,timings:e.startupTimings}})}function Bn(e,t){if(!e)return;let n={leaseId:H(e.leaseId),clientId:H(e.clientId),tenantId:H(e.tenantId),runId:H(e.runId),leaseProvider:H(e.leaseProvider),deviceKey:H(e.deviceKey)??t},r=Object.entries(n).filter(([,e])=>e!==void 0);return r.length>0?Object.fromEntries(r):void 0}function H(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}async function Vn(e){let{device:t,session:n,command:r,transportError:i,options:a,signal:o,invalidationReason:s}=e;return await Hn(await Jn(t,n,r,i,a,o),{command:r,session:n,transportError:i,options:a,invalidationReason:s,invalidateSession:e.invalidateSession})}async function Hn(e,t){if(e.type===`recovered`)return Gn(e,t);let n=Un(e,t);if(e.type===`skipInvalidation`)throw Kn(e,t,n);return await qn(e,t,n)}function Un(e,t){return`runnerAnswer`in e?o(e.runnerAnswer,e.dispatched):T(t.command)?o(t.transportError,`unknown`):o(Wn(t,e.lostReply),`unknown`)}function Wn(e,t){let{command:n,transportError:r,options:a}=e,o=r.details?.reason,s=r.details?.hint;return new i(`COMMAND_FAILED`,`cause`in t?cr(n.command,t.cause):t.message,{command:n.command,commandId:n.commandId,...t.lifecycleState===void 0?{}:{lifecycleState:t.lifecycleState},reason:Ot,...o===void 0?{}:{transportReason:o},recovery:t.recovery,...W(r),hint:typeof s==`string`?s:t.hint,logPath:a.logPath??r.details?.logPath,transportError:r.message},r)}function Gn(e,t){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.data}function Kn(e,t,n){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),n}async function qn(e,t,n){throw K({command:t.command,session:t.session,transportError:t.transportError,decision:`retained`,reason:e.reason,lifecycleState:e.lifecycleState}),await t.invalidateSession(t.session,t.invalidationReason),n}async function Jn(e,t,n,r,i,a){if(n.command===`status`||!n.commandId?.trim())return{type:`retainInvalidation`,reason:`status_recovery_unavailable`,lostReply:{recovery:`status_recovery_unavailable`,cause:`status recovery was unavailable`,hint:G(n.command)}};let o=W(r),s;try{s=await B(e,t,{command:`status`,statusCommandId:n.commandId},i.logPath,3e3,a)}catch(e){return y({level:`debug`,phase:`ios_runner_command_status_recovery_failed`,data:{command:n.command,commandId:n.commandId,error:e instanceof Error?e.message:String(e),...o}}),{type:`retainInvalidation`,reason:`status_probe_failed`,lostReply:{recovery:`status_probe_failed`,cause:`the status probe failed`,hint:G(n.command)}}}let c=typeof s.lifecycleState==`string`?s.lifecycleState:``,l=Zn(t,n,c);return y({level:`debug`,phase:`ios_runner_command_status_recovery`,data:{command:n.command,commandId:n.commandId,lifecycleState:c,...o,...l===void 0?{}:{abandonedChargeSettled:l}}}),Qn(s,c,n,r,i)}const Yn=new Set([`completed`,`failed`]),Xn=new Set([`accepted`,`started`]);function Zn(e,t,n){if(Yn.has(n))return e.commandCharges.settleTerminalEvidence(t.commandId)}function Qn(e,t,n,r,i){if(t===`completed`)return $n(e,n,r);if(t===`failed`){let a=_t(typeof e.lifecycleErrorCode==`string`?e.lifecycleErrorCode:void 0);return{type:`skipInvalidation`,reason:`runner_reported_failure`,lifecycleState:t,dispatched:a.details.dispatched,runnerAnswer:er(e,a,n,r,i)}}return Xn.has(t)?{type:`skipInvalidation`,reason:`command_still_in_flight`,lifecycleState:t,lostReply:{recovery:`command_still_in_flight`,lifecycleState:t,message:`Runner command "${n.command}" is still ${t} after the transport response was lost.`,hint:ir(n.command,t,W(r))}}:{type:`retainInvalidation`,reason:t?`unknown_lifecycle_state`:`missing_lifecycle_state`,lifecycleState:t,lostReply:{recovery:`lifecycle_state_not_recoverable`,lifecycleState:t,cause:`lifecycle status was ${t?`"${t}"`:`missing`}`,hint:G(n.command)}}}function $n(e,t,n){let r=tr(e.lifecycleResponseJson);return r?{type:`recovered`,data:r,reason:`completed_with_retained_response`,lifecycleState:`completed`}:{type:`skipInvalidation`,reason:T(t)?`read_only_completed_without_retained_response`:`completed_without_retained_response`,lifecycleState:`completed`,lostReply:{recovery:`completed_without_retained_response`,lifecycleState:`completed`,message:`Runner command "${t.command}" completed after the transport response was lost, but no recoverable response was retained.`,hint:nr(t.command,W(n))}}}function er(e,t,n,r,a){let o=typeof e.lifecycleErrorMessage==`string`?e.lifecycleErrorMessage:`Runner command failed`,s=typeof e.lifecycleErrorHint==`string`?e.lifecycleErrorHint:void 0,c=W(r);return new i(t.code,o,{command:n.command,commandId:n.commandId,lifecycleState:`failed`,recovery:`runner_reported_failure`,...t.details,...c,hint:s??rr(n.command,c),logPath:a.logPath,transportError:r.message},r)}function tr(e){if(typeof e!=`string`||e.trim().length===0)return;let t;try{t=yt(e)}catch{return}return Et(t)?gt(t):void 0}function nr(e,t){return`${U(t)}The runner is still reachable and reports "${e}" already completed, so agent-device kept the session open and will not replay it. Run snapshot -i to inspect the current UI, then continue from that observed state.`}function rr(e,t){return`${U(t)}The runner is still reachable and reports "${e}" failed after the transport response was lost, so agent-device kept the session open and did not replay it. Run snapshot -i to inspect the current UI and retry with a selector visible in that snapshot.`}function ir(e,t,n){return`${U(n)}The runner is still reachable and reports "${e}" is ${t}, so agent-device kept the session open and will not replay it. Wait briefly, run snapshot -i to inspect the current UI, then continue from that observed state.`}function U(e){return e.readinessPreflightSkipped===!0?`This hot command skipped the uptime preflight because the runner had just completed a healthy interaction; status recovery confirmed the runner still observed it. `:``}function ar(e,t){let n=e.details?.[t];return typeof n==`boolean`?n:void 0}function or(e,t){let n=e.details?.[t];return typeof n==`string`?n:void 0}function sr(e,t){let n=e.details?.[t];return typeof n==`number`?n:void 0}function W(e){let t={},n=ar(e,`runnerReadinessPreflightSkipped`);n!==void 0&&(t.readinessPreflightSkipped=n);let r=or(e,`runnerReadinessPreflightSkipReason`);r!==void 0&&(t.readinessPreflightSkipReason=r);let i=sr(e,`runnerReadinessPreflightSkippedAgeMs`);return i!==void 0&&(t.readinessPreflightSkippedAgeMs=i),t}function cr(e,t){return`Runner command "${e}" lost its transport response and ${t}, so agent-device invalidated the runner session instead of replaying the command.`}function G(e){return`The runner did not confirm that "${e}" reached a safe terminal state, so agent-device kept the conservative invalidation path. Run snapshot -i before retrying if the UI may have changed.`}function K(e){let{command:t,session:n,transportError:r,decision:i,reason:a,lifecycleState:o}=e;y({level:i===`retained`?`warn`:`debug`,phase:`ios_runner_command_invalidation_decision`,data:{command:t.command,commandId:t.commandId,decision:i,reason:a,lifecycleState:o,runnerReachable:o!==void 0,sessionId:n.sessionId,transportError:r.message}})}const q=new Map;function lr(e,t){let n=e.requestId?.trim();if(n)return`request:${n}`;let r=t.commandId?.trim();if(r)return`command:${r}`}function ur(e){if(!e)return;let t=J(e);t.touchedSession=!0,Y(e,t)}function dr(e){return e?q.get(e)?.touchedSession===!0:!1}function fr(e){if(!e)return!0;let t=J(e);return t.recycles>=1?(Y(e,t),!1):(Y(e,t),!0)}function pr(e){if(!e)return;let t=J(e);t.recycles+=1,Y(e,t)}function mr(e,t){return y({level:`warn`,phase:`ios_runner_recycle_budget_exhausted`,data:{command:e.command,commandId:e.commandId,requestId:t.requestId,maxRecycles:1}}),o(new i(`COMMAND_FAILED`,`iOS runner was already restarted during this request and "${e.command}" still failed, so agent-device stopped instead of paying for another runner boot.`,{command:e.command,commandId:e.commandId,recovery:`runner_recycle_budget_exhausted`,hint:"Check the runner log for the underlying failure before retrying — a provisioning or code-signing error there means the runner cannot install on this device, and no retry will help. If the runner is healthy, the current screen is likely too heavy or animating for accessibility capture: the app session is preserved, so run `screenshot` for visual truth and interact by coordinates, or navigate to another screen.",logPath:t.logPath}),`no`)}function J(e){return hr(),q.get(e)??{touchedSession:!1,recycles:0,lastAtMs:Date.now()}}function Y(e,t){t.lastAtMs=Date.now(),q.delete(e),q.set(e,t)}function hr(){let e=Date.now()-6e5;for(let[t,n]of q)n.lastAtMs<e&&q.delete(t);for(;q.size>512;){let e=q.keys().next().value;if(e===void 0)break;q.delete(e)}}async function gr(e,t){D(t.requestId);let n=E(t),r=C({command:`uptime`}),a;for(let i=1;i<=2;i+=1){let o=await _r({device:e,command:r,options:t,signal:n,attempt:i,recoveryReason:a});if(o.kind===`prepared`)return o.result;a=o.recoveryReason}throw new i(`COMMAND_FAILED`,`iOS runner prepare failed`)}async function _r(e){let{device:t,command:n,options:r,signal:i,attempt:a,recoveryReason:o}=e,s=Date.now(),c=await P(t,{...r,cleanStaleBundles:a>1||r.cleanStaleBundles,...Er(r,`runner_session`)}),l=Date.now()-s;try{return{kind:`prepared`,result:jr(t,await Tr(t,c,n,r,i,l,{recoveryReason:o}))}}catch(e){return await vr({device:t,session:c,command:n,options:r,signal:i,attempt:a,error:e})}}async function vr(e){let{device:t,session:n,command:i,options:o,signal:s,attempt:c,error:l}=e,u=a(l,`COMMAND_FAILED`);if(r(u))throw await X(n,`prepare_runner_request_canceled`),l;if(c===1&&Or(u,n))return{kind:`prepared`,result:await yr({device:t,session:n,command:i,options:o,signal:s,error:u})};if(!br(u))throw l;let d=u.message||`runner_health_failed`;if(c>=2)throw await X(n,`prepare_runner_health_failed`),l;return D(o.requestId),await I(n,`prepare_runner_health_retry`),y({level:`warn`,phase:`ios_runner_prepare_health_retry`,data:{command:i.command,commandId:i.commandId,sessionId:n.sessionId,attempt:c,maxAttempts:2,reason:d}}),{kind:`retry`,recoveryReason:d}}async function yr(e){let{device:t,session:n,command:r,options:i,signal:a,error:o}=e,s=o.message||`runner_health_failed`;await I(n,`prepare_cached_runner_health_failed`),await Nt(n.xctestrunArtifact,s);let c=Date.now(),l=await P(t,{...i,cleanStaleBundles:!0,forceRunnerXctestrunRebuild:!0,...Er(i,`runner_rebuild`)}),u=Date.now()-c;try{let e=await Tr(t,l,r,i,a,u,{recoveryReason:s});return y({level:`info`,phase:`ios_runner_prepare_bad_cache_recovered`,data:{command:r.command,commandId:r.commandId,sessionId:l.sessionId,xctestrunPath:l.xctestrunArtifact?.xctestrunPath,reason:s}}),jr(t,e)}catch(e){await X(l,`prepare_rebuilt_runner_health_failed`);let n=kr(e,l,s);throw Mr(t,{cache:l.xctestrunArtifact?.cache,artifact:l.xctestrunArtifact?.artifact,buildMs:l.xctestrunArtifact?.buildMs,connectMs:u,healthCheckMs:0,xctestrunPath:l.xctestrunArtifact?.xctestrunPath,failureReason:n.message}),n}}async function X(e,t){try{await I(e,t)}catch{}}function br(e){return r(e)?!1:w(e)||jt(e)}async function xr(e,n,r){let i={entered:!1};try{return await Sr(e,n,r,i)}catch(e){let n=a(e);throw i.entered?Dt(n)?t(n,`no`):n:o(n,`no`)}}async function Sr(e,t,i,o){D(i.requestId);let s=E(i),c=lr(i,t),l,u=!1,d=F(e.id)?.liveness??`gone`;try{if((d===`gone`||d===`stopped`)&&dr(c)){if(!fr(c))throw mr(t,i);u=!0}l=await P(e,i),gn(l,i.expectedRunnerSessionId),Dn(l,t),u&&pr(c),ur(c);let n=ht;if(l.state!==`ready`){let{readRunnerStartupTimeoutMs:e}=await import(`./runner-exchange.js`);n=e(l)}return o.entered=!0,await B(e,l,t,i.logPath,n,s)}catch(o){if(i.expectedRunnerSessionId!==void 0)throw o;let c=a(o,`COMMAND_FAILED`);if((l?l.state===`starting`:d!==`ready`)&&r(c))throw l&&!vt(i)&&await X(l,`runner_startup_request_canceled`),n({...c.details,readinessPhase:`runner-start`},c);if(xt(c,t)&&l)return D(i.requestId),await Cr({device:e,session:l,command:t,options:i,signal:s,restartReason:`runner_connect_failed_before_command_send`,firstAttemptDispatched:St(c)});if(l&&Ct(c))return D(i.requestId),await Cr({device:e,session:l,command:t,options:i,signal:s,restartReason:`runner_readiness_preflight_failed_before_command_send`,recoveredDiagnosticPhase:`ios_runner_readiness_preflight_recovered`,firstAttemptDispatched:`no`});if(l&&w(c)&&!At(c))return await Vn({device:e,session:l,command:t,transportError:c,options:i,signal:s,invalidationReason:`transport_error_after_command_send`,invalidateSession:I});throw o}}async function Cr(e){let{device:t,command:n,options:r,signal:i,restartReason:s}=e,c=lr(r,n);if(!fr(c))throw o(mr(n,r),e.firstAttemptDispatched);await I(e.session,s);let l=await P(t,{...r,cleanStaleBundles:!0}).catch(t=>{throw Z(t,e)});pr(c);try{let a=await B(t,l,n,r.logPath,S,i);return e.recoveredDiagnosticPhase&&y({level:`debug`,phase:e.recoveredDiagnosticPhase,data:{command:n.command,commandId:n.commandId,recovery:`session_restarted`,sessionId:l.sessionId}}),a}catch(o){let s=a(o,`COMMAND_FAILED`);if(w(s)&&!At(s))try{return await Vn({device:t,session:l,command:n,transportError:s,options:r,signal:i,invalidationReason:`transport_error_after_retry_command_send`,invalidateSession:I})}catch(t){throw Z(t,e,l)}throw Z(o,e,l)}}function Z(e,t,n){return e instanceof i?wr(new i(e.code,e.message,{...e.details??{},runnerRestarted:!0,runnerRestartReason:t.restartReason,runnerRestartCommand:t.command.command,...t.command.commandId?{runnerRestartCommandId:t.command.commandId}:{},runnerInvalidatedSessionId:t.session.sessionId,...n?{runnerRestartSessionId:n.sessionId}:{},...e.details?.logPath===void 0&&t.options.logPath?{logPath:t.options.logPath}:{}},e.cause??e),t.firstAttemptDispatched,n):e}function wr(e,n,r){return!r||n===`unknown`?o(e,n):t(e,Dt(e)?`no`:`unknown`)}async function Tr(e,t,n,r,i,a,o){let s=Date.now(),c=Dr(r.prepareDeadline,r.healthTimeoutMs,`runner_health`);return Ar(await B(e,t,n,r.logPath,c,i),t,a,Date.now()-s,o)}function Er(e,t){if(!e.prepareDeadline)return{};let n=Dr(e.prepareDeadline,e.buildTimeoutMs,t);return{buildTimeoutMs:n,startupTimeoutMs:n}}function Dr(e,t,n){if(!e)return t??45e3;let r=Math.floor(e.remainingMs());if(r<=0)throw new i(`COMMAND_FAILED`,`prepare ios-runner timed out`,{phase:n,reason:`prepare_deadline_expired`});return r}function Or(e,t){let n=t.xctestrunArtifact;return!n||n.cache===`miss`?!1:wt(e)}function kr(e,t,n){let r=a(e,`COMMAND_FAILED`);return new i(r.code,`artifact restored but runner did not connect`,{...r.details??{},restoredFailureReason:n,xctestrunPath:t.xctestrunArtifact?.xctestrunPath,artifact:t.xctestrunArtifact?.artifact,cache:t.xctestrunArtifact?.cache,reason:r.message},r)}function Ar(e,t,n,r,i){let a=t.xctestrunArtifact,o={...i?.recoveryReason?{recoveryReason:i.recoveryReason}:{},...i?.failureReason?{failureReason:i.failureReason}:{}};return a?{runner:e,cache:a.cache,artifact:a.artifact,buildMs:a.buildMs,connectMs:Math.max(0,n),healthCheckMs:Math.max(0,r),xctestrunPath:a.xctestrunPath,...o}:{runner:e,connectMs:Math.max(0,n),healthCheckMs:Math.max(0,r),...o}}function jr(e,t){return Mr(e,t),t}function Mr(e,t){y({level:t.failureReason?`warn`:`info`,phase:`apple_runner_prepare`,data:{platform:e.platform,target:e.target,deviceId:e.id,cache:t.cache,artifact:t.artifact,buildMs:t.buildMs,connectMs:t.connectMs,healthCheckMs:t.healthCheckMs,timingContainment:t.buildMs===void 0?{healthCheckMs:[]}:{connectMs:[`buildMs`],healthCheckMs:[]},xctestrunPath:t.xctestrunPath,recoveryReason:t.recoveryReason,failureReason:t.failureReason}})}const Nr={maxAttempts:8,baseDelayMs:200,maxDelayMs:1e3,jitter:0};function Pr(e){return kt(e)?8:w(e)?3:1}async function Fr(e,t,n={}){In(e),D(n.requestId);let r=C(t),i=$(e,n);if(!T(r))return i.runCommand(e,r,n);let a;try{return await ke(()=>(D(n.requestId),i.runCommand(e,r,n)),{...Nr,shouldRetry:(e,t)=>(D(n.requestId),kt(e)&&(a=e),t<Pr(e))},{signal:E(n)})}catch(e){throw a&&vt(n)?a:e}}async function Ir(e,t={}){if(l(e))try{await Fr(e,{command:`targetReset`},t)}catch(t){y({level:`warn`,phase:`ios_runner_target_reset_failed`,data:{deviceId:e.id,error:t instanceof Error?t.message:String(t)}}),await z(e.id)}}function Lr(e,t={}){if(l(e))return Q({device:e,options:t,failurePhase:`ios_runner_cache_prewarm_failed`,task:async t=>{await Ft(e,{...t,budget:x(t.buildTimeoutMs,t.signal)})}})}function Rr(e,t={}){if(!l(e))return;let n=$(e,t).prewarm;if(!n){y({level:`debug`,phase:`ios_runner_session_prewarm_unavailable`,data:{deviceId:e.id}});return}return Q({device:e,options:t,failurePhase:`ios_runner_session_prewarm_failed`,task:async t=>{await n(e,t)}})}function Q(e){let{device:t,options:n,failurePhase:r,task:i}=e,{propagateError:a=!1,...o}=n;return i(o).catch(e=>{if(y({level:`warn`,phase:r,data:{deviceId:t.id,error:e instanceof Error?e.message:String(e)}}),a)throw e})}async function zr(e,t){In(e),D(t.requestId);let n=C({command:`uptime`}),r=$(e,t);if(r.prepare)return await r.prepare(e,t);let i=Date.now();return{runner:await r.runCommand(e,n,t),connectMs:0,healthCheckMs:Math.max(0,Date.now()-i)}}function $(e,t){return Oe(e,Hr,{requestId:t.requestId})}function Br(e,t={}){return l(e)?$(e,t).hasLiveSession(e):!1}async function Vr(e,t={}){if(!l(e))return!1;let n=$(e,t).releaseSpeculativeSession;return n?await n(e):!1}const Hr=De(xr,{prepare:gr,hasLiveSession:e=>F(e.id)?.liveness===`ready`,releaseSpeculativeSession:async e=>await On(e.id),prewarm:async(e,t)=>{let{healthCheck:n,...r}=t;if(n===!1){await P(e,{...r,speculative:!0});return}await gr(e,{...r,speculative:!0,healthTimeoutMs:ht})}});var Ur=e({cleanupRunnerLeasesForOwner:()=>zt,readRunnerSessionLiveness:()=>F});Fe(Qt);export{Lr as a,Fr as c,kn as d,Nn as f,zr as i,jn as l,Br as n,Rr as o,z as p,Ir as r,Vr as s,Ur as t,F as u};
1
+ import{r as e}from"./rolldown-runtime.js";import{B as t,F as n,G as r,N as i,P as a,R as o}from"./sdk-contracts.js";import{_ as s}from"./sdk-batch-runner.js";import{d as c,p as l}from"./sdk-device.js";import{o as u}from"./sdk-remote-config.js";import{c as d,r as f}from"./diagnostics.js";import{C as p,k as m,m as h,p as g,t as _,v,w as ee,x as te}from"./owner-identity.js";import{h as ne,i as re,m as ie,n as ae,o as oe,p as se,u as ce}from"./exec.js";import{n as le,t as ue}from"./file.js";import"./diagnostics2.js";import"./command.js";import{o as de}from"./device-shell.js";import"./process.js";import{i as fe,n as pe,r as me}from"./retry.js";import{a as he,r as ge}from"./version.js";import{t as _e}from"./ttl-memo.js";import{n as ve,t as ye}from"./boot-diagnostics.js";import{t as be}from"./keyed-lock.js";import{i as xe,r as Se}from"./request-cancel.js";import{t as Ce}from"./request.js";import{a as we,o as Te,r as Ee}from"./tool-provider.js";import{t as De}from"./physical-device-control.js";import{a as Oe,o as ke}from"./runner.js";import{I as Ae,N as je,S as Me,U as Ne,_ as Pe,a as y,d as Fe,j as Ie,r as Le,t as Re,u as b}from"./host.js";import{o as ze,s as x}from"./apple-runner-platform.js";import{c as Be,h as Ve,i as He,l as Ue,m as We,p as Ge,t as Ke}from"./runner-cache-metadata.js";import{t as qe}from"./plist-xml.js";import{n as Je,t as Ye}from"./runner-owner-state.js";import{l as Xe,n as Ze}from"./simctl.js";import{_ as Qe,a as $e,b as et,c as tt,d as nt,g as rt,h as it,i as at,l as ot,n as st,o as ct,p as lt,r as ut,s as dt,t as ft,v as pt,x as mt,y as ht}from"./runner-session-types.js";import{i as gt,r as _t,t as S}from"./runner-startup-transport.js";import{A as vt,D as yt,E as bt,N as C,O as xt,S as St,_ as Ct,a as w,b as T,f as wt,g as Tt,h as Et,i as Dt,j as E,k as Ot,l as kt,n as At,o as jt,u as Mt,v as Nt,w as D}from"./runner-error-classification.js";import{c as Pt,d as Ft,s as It,t as Lt}from"./runner-xctestrun.js";import{_ as Rt,a as zt,c as Bt,d as Vt,f as Ht,g as Ut,i as Wt,l as Gt,m as Kt,n as qt,o as Jt,p as Yt,r as Xt,t as O,u as Zt,v as Qt,y as k}from"./runner-disposal.js";import $t from"node:path";import A from"node:fs";const en={runCmdStreaming:se,runCmdSync:ie,runCmdBackground:ce,requireExecSuccess:oe,isCommandTimeoutError:re,commandDeveloperDir:ae,shellQuote:de,emitDiagnostic:f,withDiagnosticTimer:d,retryWithPolicy:fe,isEnvTruthy:me,deadlineFromTimeoutMs:(e,t)=>pe.fromTimeoutMs(e,t),isProcessAlive:g,isProcessGroupAlive:h,readProcessStartTime:p,readProcessCommand:te,signalPidsBestEffort:ee,signalProcessGroupBestEffort:ne,findProjectRoot:ge,readVersion:he,acquireProcessLock:ue,withProcessLock:le,withKeyedLock:be,publishFileSync:m,classifyOwnerLiveness:_,readHostCpuArchSync:v,createTtlMemo:_e,parseBooleanLiteral:u,isRecord:s,emitRequestProgress:Ce,getRequestSignal:Se,isRequestCanceled:xe,classifyBootFailure:ve,bootFailureHint:ye,runAppleToolCommand:we,runXcrun:Te,readApplePlistJson:Ee,buildSimctlArgsForDevice:Ze,simulatorAddressFor:Xe,resolveIosPhysicalDeviceControl:De,visitXmlPlistEntries:qe,leaseOwnerStateDir:Je,hasDeviceClaimAuthority:e=>Ye()?.(e)??!1};function tn(e=process.env){return Me(e.AGENT_DEVICE_IOS_RUNNER_DETACH??``)!==!1}async function nn(e,t){if(!tn())return null;let n=x(e),r=(t,r)=>(b({level:`debug`,phase:`ios_runner_lease_adoption_skipped`,data:{deviceId:e.id,lane:n.handoff?n.lane:void 0,runnerPid:r?.runnerPid,port:r?.port,reason:t}}),null);if(!n.handoff)return r(n.reason);let i=Kt(e.id);if(i.type===`absent`)return r(`lease_absent`);if(i.type===`refused`)return r(i.reason,i.lease);let a=i.lease;if(a.simulatorSetPath!==nt(e))return r(`simulator_set_mismatch`,a);let o=rn(a,t.expectedRunnerSessionId);if(`refusal`in o)return r(o.refusal,a);let s=an(e,a,t.budget);if(`refusal`in s)return r(s.refusal,a);let c=o.value,l=s.value,u=await on(e,a.port,n.lane,t.budget);if(u!==`answered`)return r(u,a);if(!Ht(a,c))return r(`runner_pid_recycled`,a);let d=ln(e,a,c,l);try{k(d.lease)}catch{return r(`lease_write_failed`,a)}return b({level:`info`,phase:`ios_runner_lease_adopted`,data:{deviceId:e.id,lane:n.lane,sessionId:d.sessionId,runnerPid:c,port:a.port,previousOwnerPid:a.ownerPid}}),d}function rn(e,t){if(t!==void 0&&e.sessionId!==t)return{refusal:`session_identity_mismatch`};let n=e.runnerPid;return n?Pe(n)?Rt(e,n)?{value:n}:{refusal:`runner_pid_recycled`}:{refusal:`runner_process_dead`}:{refusal:`runner_pid_missing`}}function an(e,t,n){let r=cn(e,n);return r?t.cacheKey!==r.cacheKey||!t.xctestrunPath.startsWith(`${r.derived}${$t.sep}`)?{refusal:`artifact_fingerprint_mismatch`}:{value:r}:{refusal:`expected_derived_unresolved`}}async function on(e,t,n,i){let a=n===`physical_coredevice`?5e3:500,o=sn(i,a);if(o<=0)return`probe_budget_exhausted`;let s=Date.now(),c=!1;try{let n=await gt(e,t,C({command:`uptime`}),o,i?.signal);return c=Ot(xt(await n.text())),c?`answered`:`probe_failed`}catch(e){if(r(e))throw e;return`probe_failed`}finally{b({level:`debug`,phase:`ios_runner_lease_adoption_probe`,durationMs:Date.now()-s,data:{deviceId:e.id,port:t,lane:n,budgetCapMs:a,timeoutMs:o,answered:c}})}}function sn(e,t){return e?.deadline?Math.min(t,Math.floor(e.deadline.remainingMs())):t}function cn(e,t){try{let n=Ue(e,void 0,t);return{derived:We(e,n),cacheKey:Ge(n)}}catch(e){if(r(e))throw e;return null}}function ln(e,t,n,r){let i=t.sessionId,a={xctestrunPath:t.xctestrunPath,...r,cache:`exact`,artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`,reason:`adopted_from_lease`},{child:o,wait:s}=un(n);return{sessionId:i,device:e,deviceId:e.id,port:t.port,xctestrunPath:t.xctestrunPath,xctestrunArtifact:a,jsonPath:t.jsonPath,testPromise:s,child:o,runnerLogPath:t.runnerLogPath,state:`ready`,commandCharges:new ft,lease:Zt({device:e,sessionId:i,runnerPid:n,port:t.port,xctestrunPath:t.xctestrunPath,cacheKey:r.cacheKey,jsonPath:t.jsonPath,runnerLogPath:t.runnerLogPath})}}function un(e){let t={pid:e,exitCode:null};return{child:t,wait:new Promise(n=>{let r=setInterval(()=>{Pe(e)||(clearInterval(r),t.exitCode=-1,n({stdout:``,stderr:``,exitCode:-1}))},1e3);r.unref?.()})}}function dn(){let e=new AbortController,t=!1,n=``;return{wake:e.signal,observe:r=>{if(t)return;let i=n+r;if(i.includes(`AGENT_DEVICE_RUNNER_LISTENER_READY`)){t=!0,n=``,e.abort();return}n=i.slice(-33)},finish:()=>{t=!0,n=``,e.abort()}}}function fn(e){let t=e.logPath;A.mkdirSync($t.dirname(t),{recursive:!0});let n=A.openSync(t,`a`),r=it(t,n),i=pn(()=>{try{A.closeSync(n)}catch{}}),a=dn();try{let t=je(`xcodebuild`,[`test-without-building`,`-only-testing`,`AgentDeviceRunnerUITests/RunnerTests/testCommand`,`-parallel-testing-enabled`,`NO`,`-test-timeouts-enabled`,`NO`,`-collect-test-diagnostics`,`never`,Ve(e.device),`1`,`-destination-timeout`,`20`,`-xctestrun`,e.xctestrunPath,`-derivedDataPath`,e.derivedPath,...lt(e.device,ze(e.device))],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(e.port)},detached:!0,signal:e.signal,stdio:[`ignore`,n,n],captureOutput:!1}),o=mt({file:r,onOutput:t=>{a.observe(t),(e.traceLogPath||e.verbose)&&pt(t,void 0,e.traceLogPath,e.verbose)}}),s=pn(()=>{o.stop(),i()}),c=()=>{o.drain(),i(),a.finish()};return t.wait.then(c,c),{...t,startupRetryWake:a.wake,endOutputObservation:s,readLogTail:e=>ht(r,e)}}catch(e){throw i(),e}}function pn(e){let t=!1;return()=>{t||(t=!0,e())}}const j=new Map,mn=new Map,M=new Map,hn=1e4;function N(e,t){return Ne(mn,e,t)}async function P(e,t){R(e.id);let n=N(e.id,async()=>{let{openRunnerStartBudget:n}=await import(`./runner-start-budget.js`),r=n(t);try{let n=j.get(e.id);if(n){vn(n,t.expectedRunnerSessionId);let i=await Sn(e,n,r.phase);if(i)return i}return await Qt(e.id,async()=>await _n(e,t,r))}catch(e){throw r.exhausted.aborted?r.exhausted.reason:e}finally{r.close()}}),{raceRunnerStartAgainstCaller:r}=await import(`./runner-start-budget.js`);return await r(n,t.signal)}const gn=1e4;async function _n(e,t,r){let i={},a=r.phase,o=a.signal,s=Hn(t.runnerLeaseContext,e.id);b({level:`debug`,phase:`ios_runner_session_startup`,data:{deviceId:e.id,logicalLeaseContext:s}});let c=await V(i,`adopt_detached_runner`,async()=>await nn(e,{budget:a,expectedRunnerSessionId:t.expectedRunnerSessionId}));if(c)return c.startupTimings=i,c.logicalLeaseContext=s,j.set(e.id,c),c;yn(t.expectedRunnerSessionId),await V(i,`cleanup_stale_xcodebuild`,async()=>{await Yt(e,Jt,s)}),await V(i,`ensure_booted`,async()=>{await In(e)});let l=await V(i,`verify_device_readiness`,async()=>await(await import(`./runner-device-readiness.js`)).preflightIosRunnerDeviceReadiness(e,{budgetMs:Math.min(gn,a.deadline?.remainingMs()??gn),signal:o}));await V(i,`verify_host_dev_tools_security`,async()=>{let{assertDevToolsSecurityForIosRunner:t}=await import(`./runner-dev-tools-security.js`);await t(e)}),t.cleanStaleBundles?await V(i,`cleanup_stale_bundles`,async()=>{await Cn(e)}):(i.cleanup_stale_bundles=0,b({level:`debug`,phase:`ios_runner_startup_cleanup_stale_bundles_skipped`}));let u,d,f,p,m=et(t.logPath,e.id),h;try{u=await V(i,`ensure_xctestrun`,async()=>await Lt(e,{...t,budget:He(zn(t,r),o)})),i.build_xctestrun=u.buildMs,d=await V(i,`allocate_port`,async()=>await Qe()),{xctestrunPath:f,jsonPath:p}=await V(i,`prepare_xctestrun_env`,async()=>await Pt(u.xctestrunPath,{AGENT_DEVICE_RUNNER_PORT:String(d)},It({deviceId:e.id,ownerToken:Ut(),port:d}),{iosXctestEnvDir:t.iosXctestEnvDir})),u.buildMs>0&&Fe({type:`command`,status:`progress`,message:`Starting XCTest runner...`}),h=await V(i,`launch_xcodebuild`,async()=>(await rt(m).catch(()=>{}),await fn({device:e,port:d,xctestrunPath:f,derivedPath:u.derived,signal:o,logPath:m,traceLogPath:t.traceLogPath,verbose:t.verbose})))}catch(e){throw Dt(e,l)}let g=ut(e.id,d),_=Zt({device:e,sessionId:g,runnerPid:h.child.pid,port:d,xctestrunPath:f,cacheKey:u.cacheKey,jsonPath:p,runnerLogPath:m}),v={sessionId:g,device:e,deviceId:e.id,port:d,xctestrunPath:f,xctestrunArtifact:u,jsonPath:p,runnerLogPath:m,testPromise:h.wait,child:h.child,endOutputObservation:h.endOutputObservation,readLogTail:h.readLogTail,state:`starting`,commandCharges:new ft,startupRetryWake:h.startupRetryWake,launchDeadline:Re.fromTimeoutMs(Bn(r)),startupTimings:i,startupDeviceStates:l,logicalLeaseContext:s,lease:_,speculative:t.speculative===!0};if(o?.aborted)throw await Wt(v,{graceful:!1,waitTimeoutMs:O,leaseLockHeld:!0}),n();try{k(_)}catch(t){throw await L(e.id,v,{graceful:!1,waitTimeoutMs:O,leaseLockHeld:!0}),t}return j.set(e.id,v),v}function vn(e,t){if(t!==void 0&&e.sessionId!==t)throw bn()}function yn(e){if(e!==void 0)throw bn()}function bn(){return new i(`COMMAND_FAILED`,`Apple runner session ownership changed before command dispatch`,{reason:`runner_session_ownership_changed`})}async function xn(e,t){let n=En(t);return n===`gone`?(await V({},`stop_stale_session`,async()=>{await L(e.id,t,{graceful:!1,waitTimeoutMs:O})}),!1):n!==`starting`&&n!==`ready`?!1:n===`starting`&&t.launchDeadline?.isExpired()?(b({level:`warn`,phase:`ios_runner_session_invalidated`,data:{deviceId:e.id,sessionId:t.sessionId,reason:`runner_launch_budget_exhausted`}}),await V({},`stop_expired_starting_session`,async()=>{await L(e.id,t,{graceful:!1,waitTimeoutMs:O})}),!1):ot(t.device,e)?!0:(await V({},`stop_other_simulator_set_session`,async()=>{await L(e.id,t)}),!1)}async function Sn(e,t,n){if(!await xn(e,t))return null;let r=t.xctestrunArtifact;if(r?.cache===`external`)return b({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.state===`ready`,cache:r.cache,logicalLeaseContext:t.logicalLeaseContext}}),t;let i=Ue(e,void 0,n),a=We(e,i),o=Ge(i);return r?.derived!==a||r.cacheKey!==o?(b({level:`debug`,phase:`ios_runner_session_artifact_stale`,data:{deviceId:e.id,sessionId:t.sessionId,currentDerived:r?.derived,expectedDerived:a,currentCacheKey:r?.cacheKey,expectedCacheKey:o}}),await V({},`stop_stale_artifact_session`,async()=>{await L(e.id,t)}),null):(b({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.state===`ready`,logicalLeaseContext:t.logicalLeaseContext}}),t)}async function Cn(e){e.kind===`simulator`&&await Promise.allSettled(Ke.map(async t=>{let n=await wn(e,t);!n||Tn(n)}))}async function wn(e,t){try{return await Ae(y(e,[`uninstall`,e.id,t]),{allowFailure:!0,timeoutMs:hn})}catch(n){b({level:`warn`,phase:`ios_runner_startup_cleanup_stale_bundle_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:hn,error:n instanceof Error?n.message:String(n)}});return}}function Tn(e){if(e.exitCode===0)return!0;let t=`${e.stdout}\n${e.stderr}`.toLowerCase();return t.includes(`not installed`)||t.includes(`found nothing`)||t.includes(`no such file`)||t.includes(`invalid device`)||t.includes(`could not find`)}function F(e){let t=j.get(e);return t?{sessionId:t.sessionId,liveness:En(t)}:null}function En(e){return tt({state:e.state,processRunning:zt(e.child.pid)})}async function I(e,t){await N(e.deviceId,async()=>{j.get(e.deviceId)===e&&at(e)&&(b({level:`warn`,phase:`ios_runner_session_invalidated`,data:{deviceId:e.deviceId,sessionId:e.sessionId,reason:t}}),await L(e.deviceId,e,{graceful:!1,waitTimeoutMs:O}))})}async function L(e,t,n={}){let r=t??j.get(e);r&&at(r)&&(await Wt(r,n),j.get(e)===r&&j.delete(e))}function Dn(e){R(e);let t=On();if(t<=0||!j.has(e))return;let n=setTimeout(()=>{M.delete(e),b({level:`info`,phase:`ios_runner_idle_stop`,data:{deviceId:e,idleMs:t}}),z(e).catch(t=>{b({level:`warn`,phase:`ios_runner_idle_stop_failed`,data:{deviceId:e,error:t instanceof Error?t.message:String(t)}})})},t);n.unref?.(),M.set(e,n),b({level:`debug`,phase:`ios_runner_idle_stop_scheduled`,data:{deviceId:e,idleMs:t}})}function R(e){let t=M.get(e);t&&(clearTimeout(t),M.delete(e))}function On(e=process.env){let t=e.AGENT_DEVICE_IOS_RUNNER_IDLE_STOP_MS?.trim();if(t){let e=Number(t);if(Number.isFinite(e)&&e>=0)return Math.floor(e)}return 3e5}function kn(e,t){e.speculative&&!St(t)&&(e.speculative=!1)}async function An(e){return await N(e,async()=>{let t=j.get(e);return t?.speculative?(b({level:`debug`,phase:`ios_runner_speculative_released`,data:{deviceId:e,sessionId:t.sessionId,ready:t.state===`ready`}}),await z(e),!0):!1})}async function z(e){R(e),await N(e,async()=>{await Qt(e,async()=>{await L(e,void 0,{leaseLockHeld:!0}),await Xt(e)})})}async function jn(e,t){let n=j.get(e);if(t.retain&&!$e(n)){Dn(e);return}t.retain&&b({level:`info`,phase:`ios_runner_retain_skipped_busy`,data:{deviceId:e}}),await z(e)}async function Mn(){let e=Array.from(j.values());await qt(e);for(let t of e)j.get(t.deviceId)===t&&j.delete(t.deviceId)}async function Nn(){if(!tn())return 0;let e=0;for(let[t,n]of j){let r=Pn(t,n);if(!r.detached){b({level:`debug`,phase:`ios_runner_session_detach_skipped`,data:{deviceId:t,sessionId:n.sessionId,lane:r.lane,reason:r.reason,outstandingCharges:n.commandCharges.outstandingChargeCount,hasAbandonedCharges:n.commandCharges.hasAbandonedCharges}});continue}e+=1,b({level:`info`,phase:`ios_runner_session_detached`,data:{deviceId:t,lane:r.lane,sessionId:n.sessionId,runnerPid:n.child.pid,port:n.port,runnerLogPath:n.runnerLogPath}})}return e}function Pn(e,t){let n=x(t.device);if(!n.handoff)return{detached:!1,lane:void 0,reason:n.reason};let r=n.lane,i=dt(t);if(!i.detach)return{detached:!1,lane:r,reason:i.reason};let a=t.lease;if(!a)return{detached:!1,lane:r,reason:`lease_absent`};if(!zt(t.child.pid))return{detached:!1,lane:r,reason:`runner_process_dead`};try{k(Gt(a))}catch{return{detached:!1,lane:r,reason:`lease_write_failed`}}return t.endOutputObservation?.(),j.delete(e),R(e),st(t,`stopped`),{detached:!0,lane:r}}async function Fn(){await Mn();let e=Array.from(j.keys());await Promise.allSettled(e.map(async e=>{await z(e)})),await Bt()}function In(e){return e.kind===`simulator`?e.booted?(b({level:`debug`,phase:`ios_runner_startup_ensure_booted_skipped`,data:{deviceId:e.id}}),Promise.resolve()):Ln(e):Promise.resolve()}async function Ln(e){await Ae(y(e,[`bootstatus`,e.id,`-b`]),{timeoutMs:S})}function Rn(e){if(!c(e.platform))throw new i(`UNSUPPORTED_PLATFORM`,`Unsupported platform for iOS runner: ${e.platform}`);if(e.kind!==`simulator`&&e.kind!==`device`)throw new i(`UNSUPPORTED_OPERATION`,`Unsupported iOS device kind for runner: ${e.kind}`)}async function B(e,t,n,r,i,a){Vn(t,n.command);let{executeRunnerExchange:o}=await import(`./runner-exchange.js`);return o(e,t,n,r,i,e=>I(t,e),a)}function zn(e,t){let n=Be(t.phase,`runner_xctestrun_build`)??t.timeoutMs,r=ct(e.buildTimeoutMs);return r===void 0?n:Math.min(r,n)}function Bn(e){let t=Math.floor(e.phase.deadline?.remainingMs()??e.timeoutMs);return e.explicit?t:Math.min(S,t)}async function V(e,t,n){let r=Date.now();try{return await n()}finally{let n=Date.now()-r;e[t]=n,b({level:`debug`,phase:`ios_runner_startup_${t}`,durationMs:n})}}function Vn(e,t){if(e.startupTimingsReported||!e.startupTimings)return;e.startupTimingsReported=!0;let n=Object.values(e.startupTimings).reduce((e,t)=>e+t,0);b({level:`info`,phase:`ios_runner_session_startup_timings`,durationMs:n,data:{command:t,sessionId:e.sessionId,ready:e.state===`ready`,logicalLeaseContext:e.logicalLeaseContext,timings:e.startupTimings}})}function Hn(e,t){if(!e)return;let n={leaseId:H(e.leaseId),clientId:H(e.clientId),tenantId:H(e.tenantId),runId:H(e.runId),leaseProvider:H(e.leaseProvider),deviceKey:H(e.deviceKey)??t},r=Object.entries(n).filter(([,e])=>e!==void 0);return r.length>0?Object.fromEntries(r):void 0}function H(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}async function Un(e){let{device:t,session:n,command:r,transportError:i,options:a,signal:o,invalidationReason:s}=e;return await Wn(await Xn(t,n,r,i,a,o),{command:r,session:n,transportError:i,options:a,invalidationReason:s,invalidateSession:e.invalidateSession})}async function Wn(e,t){if(e.type===`recovered`)return qn(e,t);let n=Gn(e,t);if(e.type===`skipInvalidation`)throw Jn(e,t,n);return await Yn(e,t,n)}function Gn(e,t){return`runnerAnswer`in e?o(e.runnerAnswer,e.dispatched):T(t.command)?o(t.transportError,`unknown`):o(Kn(t,e.lostReply),`unknown`)}function Kn(e,t){let{command:n,transportError:r,options:a}=e,o=r.details?.reason,s=r.details?.hint;return new i(`COMMAND_FAILED`,`cause`in t?ur(n.command,t.cause):t.message,{command:n.command,commandId:n.commandId,...t.lifecycleState===void 0?{}:{lifecycleState:t.lifecycleState},reason:At,...o===void 0?{}:{transportReason:o},recovery:t.recovery,...W(r),hint:typeof s==`string`?s:t.hint,logPath:a.logPath??r.details?.logPath,transportError:r.message},r)}function qn(e,t){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.data}function Jn(e,t,n){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),n}async function Yn(e,t,n){throw K({command:t.command,session:t.session,transportError:t.transportError,decision:`retained`,reason:e.reason,lifecycleState:e.lifecycleState}),await t.invalidateSession(t.session,t.invalidationReason),n}async function Xn(e,t,n,r,i,a){if(n.command===`status`||!n.commandId?.trim())return{type:`retainInvalidation`,reason:`status_recovery_unavailable`,lostReply:{recovery:`status_recovery_unavailable`,cause:`status recovery was unavailable`,hint:G(n.command)}};let o=W(r),s;try{s=await B(e,t,{command:`status`,statusCommandId:n.commandId},i.logPath,3e3,a)}catch(e){return b({level:`debug`,phase:`ios_runner_command_status_recovery_failed`,data:{command:n.command,commandId:n.commandId,error:e instanceof Error?e.message:String(e),...o}}),{type:`retainInvalidation`,reason:`status_probe_failed`,lostReply:{recovery:`status_probe_failed`,cause:`the status probe failed`,hint:G(n.command)}}}let c=typeof s.lifecycleState==`string`?s.lifecycleState:``,l=$n(t,n,c);return b({level:`debug`,phase:`ios_runner_command_status_recovery`,data:{command:n.command,commandId:n.commandId,lifecycleState:c,...o,...l===void 0?{}:{abandonedChargeSettled:l}}}),er(s,c,n,r,i)}const Zn=new Set([`completed`,`failed`]),Qn=new Set([`accepted`,`started`]);function $n(e,t,n){if(Zn.has(n))return e.commandCharges.settleTerminalEvidence(t.commandId)}function er(e,t,n,r,i){if(t===`completed`)return tr(e,n,r);if(t===`failed`){let a=yt(typeof e.lifecycleErrorCode==`string`?e.lifecycleErrorCode:void 0);return{type:`skipInvalidation`,reason:`runner_reported_failure`,lifecycleState:t,dispatched:a.details.dispatched,runnerAnswer:nr(e,a,n,r,i)}}return Qn.has(t)?{type:`skipInvalidation`,reason:`command_still_in_flight`,lifecycleState:t,lostReply:{recovery:`command_still_in_flight`,lifecycleState:t,message:`Runner command "${n.command}" is still ${t} after the transport response was lost.`,hint:or(n.command,t,W(r))}}:{type:`retainInvalidation`,reason:t?`unknown_lifecycle_state`:`missing_lifecycle_state`,lifecycleState:t,lostReply:{recovery:`lifecycle_state_not_recoverable`,lifecycleState:t,cause:`lifecycle status was ${t?`"${t}"`:`missing`}`,hint:G(n.command)}}}function tr(e,t,n){let r=rr(e.lifecycleResponseJson);return r?{type:`recovered`,data:r,reason:`completed_with_retained_response`,lifecycleState:`completed`}:{type:`skipInvalidation`,reason:T(t)?`read_only_completed_without_retained_response`:`completed_without_retained_response`,lifecycleState:`completed`,lostReply:{recovery:`completed_without_retained_response`,lifecycleState:`completed`,message:`Runner command "${t.command}" completed after the transport response was lost, but no recoverable response was retained.`,hint:ir(t.command,W(n))}}}function nr(e,t,n,r,a){let o=typeof e.lifecycleErrorMessage==`string`?e.lifecycleErrorMessage:`Runner command failed`,s=typeof e.lifecycleErrorHint==`string`?e.lifecycleErrorHint:void 0,c=W(r);return new i(t.code,o,{command:n.command,commandId:n.commandId,lifecycleState:`failed`,recovery:`runner_reported_failure`,...t.details,...c,hint:s??ar(n.command,c),logPath:a.logPath,transportError:r.message},r)}function rr(e){if(typeof e!=`string`||e.trim().length===0)return;let t;try{t=xt(e)}catch{return}return Ot(t)?vt(t):void 0}function ir(e,t){return`${U(t)}The runner is still reachable and reports "${e}" already completed, so agent-device kept the session open and will not replay it. Run snapshot -i to inspect the current UI, then continue from that observed state.`}function ar(e,t){return`${U(t)}The runner is still reachable and reports "${e}" failed after the transport response was lost, so agent-device kept the session open and did not replay it. Run snapshot -i to inspect the current UI and retry with a selector visible in that snapshot.`}function or(e,t,n){return`${U(n)}The runner is still reachable and reports "${e}" is ${t}, so agent-device kept the session open and will not replay it. Wait briefly, run snapshot -i to inspect the current UI, then continue from that observed state.`}function U(e){return e.readinessPreflightSkipped===!0?`This hot command skipped the uptime preflight because the runner had just completed a healthy interaction; status recovery confirmed the runner still observed it. `:``}function sr(e,t){let n=e.details?.[t];return typeof n==`boolean`?n:void 0}function cr(e,t){let n=e.details?.[t];return typeof n==`string`?n:void 0}function lr(e,t){let n=e.details?.[t];return typeof n==`number`?n:void 0}function W(e){let t={},n=sr(e,`runnerReadinessPreflightSkipped`);n!==void 0&&(t.readinessPreflightSkipped=n);let r=cr(e,`runnerReadinessPreflightSkipReason`);r!==void 0&&(t.readinessPreflightSkipReason=r);let i=lr(e,`runnerReadinessPreflightSkippedAgeMs`);return i!==void 0&&(t.readinessPreflightSkippedAgeMs=i),t}function ur(e,t){return`Runner command "${e}" lost its transport response and ${t}, so agent-device invalidated the runner session instead of replaying the command.`}function G(e){return`The runner did not confirm that "${e}" reached a safe terminal state, so agent-device kept the conservative invalidation path. Run snapshot -i before retrying if the UI may have changed.`}function K(e){let{command:t,session:n,transportError:r,decision:i,reason:a,lifecycleState:o}=e;b({level:i===`retained`?`warn`:`debug`,phase:`ios_runner_command_invalidation_decision`,data:{command:t.command,commandId:t.commandId,decision:i,reason:a,lifecycleState:o,runnerReachable:o!==void 0,sessionId:n.sessionId,transportError:r.message}})}const q=new Map;function dr(e,t){let n=e.requestId?.trim();if(n)return`request:${n}`;let r=t.commandId?.trim();if(r)return`command:${r}`}function fr(e){if(!e)return;let t=Y(e);t.touchedSession=!0,X(e,t)}function pr(e){return e?q.get(e)?.touchedSession===!0:!1}function mr(e){if(!e)return!0;let t=Y(e);return t.recycles>=1?(X(e,t),!1):(X(e,t),!0)}function J(e){if(!e)return;let t=Y(e);t.recycles+=1,X(e,t)}function hr(e,t){return b({level:`warn`,phase:`ios_runner_recycle_budget_exhausted`,data:{command:e.command,commandId:e.commandId,requestId:t.requestId,maxRecycles:1}}),o(new i(`COMMAND_FAILED`,`iOS runner was already restarted during this request and "${e.command}" still failed, so agent-device stopped instead of paying for another runner boot.`,{command:e.command,commandId:e.commandId,recovery:`runner_recycle_budget_exhausted`,hint:"Check the runner log for the underlying failure before retrying — a provisioning or code-signing error there means the runner cannot install on this device, and no retry will help. If the runner is healthy, the current screen is likely too heavy or animating for accessibility capture: the app session is preserved, so run `screenshot` for visual truth and interact by coordinates, or navigate to another screen.",logPath:t.logPath}),`no`)}function Y(e){return gr(),q.get(e)??{touchedSession:!1,recycles:0,lastAtMs:Date.now()}}function X(e,t){t.lastAtMs=Date.now(),q.delete(e),q.set(e,t)}function gr(){let e=Date.now()-6e5;for(let[t,n]of q)n.lastAtMs<e&&q.delete(t);for(;q.size>512;){let e=q.keys().next().value;if(e===void 0)break;q.delete(e)}}async function _r(e,t){D(t.requestId);let n=E(t),r=C({command:`uptime`}),a;for(let i=1;i<=2;i+=1){let o=await vr({device:e,command:r,options:t,signal:n,attempt:i,recoveryReason:a});if(o.kind===`prepared`)return o.result;a=o.recoveryReason}throw new i(`COMMAND_FAILED`,`iOS runner prepare failed`)}async function vr(e){let{device:t,command:n,options:r,signal:i,attempt:a,recoveryReason:o}=e,s=Date.now(),c=await P(t,{...r,cleanStaleBundles:a>1||r.cleanStaleBundles,...Dr(r,`runner_session`)}),l=Date.now()-s;try{return{kind:`prepared`,result:Mr(t,await Er(t,c,n,r,i,l,{recoveryReason:o}))}}catch(e){return await yr({device:t,session:c,command:n,options:r,signal:i,attempt:a,error:e})}}async function yr(e){let{device:t,session:n,command:i,options:o,signal:s,attempt:c,error:l}=e,u=a(l,`COMMAND_FAILED`);if(r(u))throw await Z(n,`prepare_runner_request_canceled`),l;if(c===1&&kr(u,n))return{kind:`prepared`,result:await br({device:t,session:n,command:i,options:o,signal:s,error:u})};if(!xr(u))throw l;let d=u.message||`runner_health_failed`;if(c>=2)throw await Z(n,`prepare_runner_health_failed`),l;return D(o.requestId),await I(n,`prepare_runner_health_retry`),b({level:`warn`,phase:`ios_runner_prepare_health_retry`,data:{command:i.command,commandId:i.commandId,sessionId:n.sessionId,attempt:c,maxAttempts:2,reason:d}}),{kind:`retry`,recoveryReason:d}}async function br(e){let{device:t,session:n,command:r,options:i,signal:a,error:o}=e,s=o.message||`runner_health_failed`;await I(n,`prepare_cached_runner_health_failed`),await Ft(n.xctestrunArtifact,s);let c=Date.now(),l=await P(t,{...i,cleanStaleBundles:!0,forceRunnerXctestrunRebuild:!0,...Dr(i,`runner_rebuild`)}),u=Date.now()-c;try{let e=await Er(t,l,r,i,a,u,{recoveryReason:s});return b({level:`info`,phase:`ios_runner_prepare_bad_cache_recovered`,data:{command:r.command,commandId:r.commandId,sessionId:l.sessionId,xctestrunPath:l.xctestrunArtifact?.xctestrunPath,reason:s}}),Mr(t,e)}catch(e){await Z(l,`prepare_rebuilt_runner_health_failed`);let n=Ar(e,l,s);throw Nr(t,{cache:l.xctestrunArtifact?.cache,artifact:l.xctestrunArtifact?.artifact,buildMs:l.xctestrunArtifact?.buildMs,connectMs:u,healthCheckMs:0,xctestrunPath:l.xctestrunArtifact?.xctestrunPath,failureReason:n.message}),n}}async function Z(e,t){try{await I(e,t)}catch{}}function xr(e){return r(e)?!1:w(e)||Nt(e)}async function Sr(e,n,r){let i={entered:!1};try{return await Cr(e,n,r,i)}catch(e){let n=a(e);throw i.entered?kt(n)?t(n,`no`):n:o(n,`no`)}}async function Cr(e,t,i,o){D(i.requestId);let s=E(i),c=dr(i,t),l,u=!1,d=F(e.id)?.liveness??`gone`;try{if((d===`gone`||d===`stopped`)&&pr(c)){if(!mr(c))throw hr(t,i);u=!0}l=await P(e,i),vn(l,i.expectedRunnerSessionId),kn(l,t),u&&J(c),fr(c);let n=_t;if(l.state!==`ready`){let{readRunnerStartupTimeoutMs:e}=await import(`./runner-exchange.js`);n=e(l)}return o.entered=!0,await B(e,l,t,i.logPath,n,s)}catch(o){if(i.expectedRunnerSessionId!==void 0)throw o;let c=a(o,`COMMAND_FAILED`);if((l?l.state===`starting`:d!==`ready`)&&r(c))throw l&&!bt(i)&&await Z(l,`runner_startup_request_canceled`),n({...c.details,readinessPhase:`runner-start`},c);if(Ct(c,t)&&l)return D(i.requestId),await wr({device:e,session:l,command:t,options:i,signal:s,restartReason:`runner_connect_failed_before_command_send`,firstAttemptDispatched:wt(c)});if(l&&Tt(c))return D(i.requestId),await wr({device:e,session:l,command:t,options:i,signal:s,restartReason:`runner_readiness_preflight_failed_before_command_send`,recoveredDiagnosticPhase:`ios_runner_readiness_preflight_recovered`,firstAttemptDispatched:`no`});if(l&&w(c)&&!Mt(c))return await Un({device:e,session:l,command:t,transportError:c,options:i,signal:s,invalidationReason:`transport_error_after_command_send`,invalidateSession:I});throw o}}async function wr(e){let{device:t,command:n,options:r,signal:i,restartReason:s}=e,c=dr(r,n);if(!mr(c))throw o(hr(n,r),e.firstAttemptDispatched);await I(e.session,s);let l=await P(t,{...r,cleanStaleBundles:!0}).catch(t=>{throw Q(t,e)});J(c);try{let a=await B(t,l,n,r.logPath,S,i);return e.recoveredDiagnosticPhase&&b({level:`debug`,phase:e.recoveredDiagnosticPhase,data:{command:n.command,commandId:n.commandId,recovery:`session_restarted`,sessionId:l.sessionId}}),a}catch(o){let s=a(o,`COMMAND_FAILED`);if(w(s)&&!Mt(s))try{return await Un({device:t,session:l,command:n,transportError:s,options:r,signal:i,invalidationReason:`transport_error_after_retry_command_send`,invalidateSession:I})}catch(t){throw Q(t,e,l)}throw Q(o,e,l)}}function Q(e,t,n){return e instanceof i?Tr(new i(e.code,e.message,{...e.details??{},runnerRestarted:!0,runnerRestartReason:t.restartReason,runnerRestartCommand:t.command.command,...t.command.commandId?{runnerRestartCommandId:t.command.commandId}:{},runnerInvalidatedSessionId:t.session.sessionId,...n?{runnerRestartSessionId:n.sessionId}:{},...e.details?.logPath===void 0&&t.options.logPath?{logPath:t.options.logPath}:{}},e.cause??e),t.firstAttemptDispatched,n):e}function Tr(e,n,r){return!r||n===`unknown`?o(e,n):t(e,kt(e)?`no`:`unknown`)}async function Er(e,t,n,r,i,a,o){let s=Date.now(),c=Or(r.prepareDeadline,r.healthTimeoutMs,`runner_health`);return jr(await B(e,t,n,r.logPath,c,i),t,a,Date.now()-s,o)}function Dr(e,t){if(!e.prepareDeadline)return{};let n=Or(e.prepareDeadline,e.buildTimeoutMs,t);return{buildTimeoutMs:n,startupTimeoutMs:n}}function Or(e,t,n){if(!e)return t??45e3;let r=Math.floor(e.remainingMs());if(r<=0)throw new i(`COMMAND_FAILED`,`prepare ios-runner timed out`,{phase:n,reason:`prepare_deadline_expired`});return r}function kr(e,t){let n=t.xctestrunArtifact;return!n||n.cache===`miss`?!1:Et(e)}function Ar(e,t,n){let r=a(e,`COMMAND_FAILED`);return new i(r.code,`artifact restored but runner did not connect`,{...r.details??{},restoredFailureReason:n,xctestrunPath:t.xctestrunArtifact?.xctestrunPath,artifact:t.xctestrunArtifact?.artifact,cache:t.xctestrunArtifact?.cache,reason:r.message},r)}function jr(e,t,n,r,i){let a=t.xctestrunArtifact,o={...i?.recoveryReason?{recoveryReason:i.recoveryReason}:{},...i?.failureReason?{failureReason:i.failureReason}:{}};return a?{runner:e,cache:a.cache,artifact:a.artifact,buildMs:a.buildMs,connectMs:Math.max(0,n),healthCheckMs:Math.max(0,r),xctestrunPath:a.xctestrunPath,...o}:{runner:e,connectMs:Math.max(0,n),healthCheckMs:Math.max(0,r),...o}}function Mr(e,t){return Nr(e,t),t}function Nr(e,t){b({level:t.failureReason?`warn`:`info`,phase:`apple_runner_prepare`,data:{platform:e.platform,target:e.target,deviceId:e.id,cache:t.cache,artifact:t.artifact,buildMs:t.buildMs,connectMs:t.connectMs,healthCheckMs:t.healthCheckMs,timingContainment:t.buildMs===void 0?{healthCheckMs:[]}:{connectMs:[`buildMs`],healthCheckMs:[]},xctestrunPath:t.xctestrunPath,recoveryReason:t.recoveryReason,failureReason:t.failureReason}})}const Pr={maxAttempts:8,baseDelayMs:200,maxDelayMs:1e3,jitter:0};function Fr(e){return jt(e)?8:w(e)?3:1}async function Ir(e,t,n={}){Rn(e),D(n.requestId);let r=C(t),i=$(e,n);if(!T(r))return i.runCommand(e,r,n);let a;try{return await Ie(()=>(D(n.requestId),i.runCommand(e,r,n)),{...Pr,shouldRetry:(e,t)=>(D(n.requestId),jt(e)&&(a=e),t<Fr(e))},{signal:E(n)})}catch(e){throw a&&bt(n)?a:e}}async function Lr(e,t={}){if(l(e))try{await Ir(e,{command:`targetReset`},t)}catch(t){b({level:`warn`,phase:`ios_runner_target_reset_failed`,data:{deviceId:e.id,error:t instanceof Error?t.message:String(t)}}),await z(e.id)}}function Rr(e,t={}){if(l(e))return Br({device:e,options:t,failurePhase:`ios_runner_cache_prewarm_failed`,task:async t=>{await Lt(e,{...t,budget:He(t.buildTimeoutMs,t.signal)})}})}function zr(e,t={}){if(!l(e))return;let n=$(e,t).prewarm;if(!n){b({level:`debug`,phase:`ios_runner_session_prewarm_unavailable`,data:{deviceId:e.id}});return}return Br({device:e,options:t,failurePhase:`ios_runner_session_prewarm_failed`,task:async t=>{await n(e,t)}})}function Br(e){let{device:t,options:n,failurePhase:r,task:i}=e,{propagateError:a=!1,...o}=n;return i(o).catch(e=>{if(b({level:`warn`,phase:r,data:{deviceId:t.id,error:e instanceof Error?e.message:String(e)}}),a)throw e})}async function Vr(e,t){Rn(e),D(t.requestId);let n=C({command:`uptime`}),r=$(e,t);if(r.prepare)return await r.prepare(e,t);let i=Date.now();return{runner:await r.runCommand(e,n,t),connectMs:0,healthCheckMs:Math.max(0,Date.now()-i)}}function $(e,t){return ke(e,Wr,{requestId:t.requestId})}function Hr(e,t={}){return l(e)?$(e,t).hasLiveSession(e):!1}async function Ur(e,t={}){if(!l(e))return!1;let n=$(e,t).releaseSpeculativeSession;return n?await n(e):!1}const Wr=Oe(Sr,{prepare:_r,hasLiveSession:e=>F(e.id)?.liveness===`ready`,releaseSpeculativeSession:async e=>await An(e.id),prewarm:async(e,t)=>{let{healthCheck:n,...r}=t;if(n===!1){await P(e,{...r,speculative:!0});return}await _r(e,{...r,speculative:!0,healthTimeoutMs:_t})}});var Gr=e({cleanupRunnerLeasesForOwner:()=>Vt,readRunnerSessionLiveness:()=>F});Le(en);export{Rr as a,Ir as c,jn as d,Fn as f,Vr as i,Nn as l,Hr as n,zr as o,z as p,Lr as r,Ur as s,Gr as t,F as u};
@@ -1 +1 @@
1
- import{N as e}from"./sdk-contracts.js";import{p as t}from"./sdk-device.js";import{j as n}from"./host.js";import{r}from"./runner-error-classification.js";const i=`Developer mode is disabled for Apple development tools`;async function a(e){if(!t(e)||e.kind!==`device`)return;let r=await n(`DevToolsSecurity`,[`-status`],{allowFailure:!0,timeoutMs:2e3}),i=`${r.stdout}\n${r.stderr}`;if(/developer mode is currently disabled/i.test(i))throw o(i.trim())}function o(t){let n=new e(`COMMAND_FAILED`,i,{devToolsSecurityStatus:t}),{reason:a,hint:o}=r(n);return new e(`COMMAND_FAILED`,i,{reason:a,hint:o,devToolsSecurityStatus:t})}export{a as assertDevToolsSecurityForIosRunner};
1
+ import{N as e}from"./sdk-contracts.js";import{p as t}from"./sdk-device.js";import{M as n}from"./host.js";import{r}from"./runner-error-classification.js";const i=`Developer mode is disabled for Apple development tools`;async function a(e){if(!t(e)||e.kind!==`device`)return;let r=await n(`DevToolsSecurity`,[`-status`],{allowFailure:!0,timeoutMs:2e3}),i=`${r.stdout}\n${r.stderr}`;if(/developer mode is currently disabled/i.test(i))throw o(i.trim())}function o(t){let n=new e(`COMMAND_FAILED`,i,{devToolsSecurityStatus:t}),{reason:a,hint:o}=r(n);return new e(`COMMAND_FAILED`,i,{reason:a,hint:o,devToolsSecurityStatus:t})}export{a as assertDevToolsSecurityForIosRunner};
@@ -1 +1 @@
1
- import{N as e}from"./sdk-contracts.js";import{p as t}from"./sdk-device.js";import{k as n}from"./host.js";import"./runner-error-classification.js";async function r(r,a){if(!t(r)||r.kind!==`device`)return;let o=await n(r).readDeviceReadiness(r,a.budgetMs,a.signal);if(a.signal?.throwIfAborted(),!o.available)return;let s=i(o);if(s)throw new e(`COMMAND_FAILED`,s.message,{reason:s.reason,hint:s.hint,deviceId:r.id,developerMode:o.developerMode,developerDiskImage:o.developerDiskImage});return{developerMode:o.developerMode,developerDiskImage:o.developerDiskImage,developerDiskImageHint:o.remedies.developerDiskImageUnavailable}}function i(e){if(e.developerMode===`disabled`)return{reason:`device_developer_mode_disabled`,message:`The iOS device reports that Developer Mode is turned off`,hint:e.remedies.developerModeOff}}export{r as preflightIosRunnerDeviceReadiness};
1
+ import{N as e}from"./sdk-contracts.js";import{p as t}from"./sdk-device.js";import{A as n}from"./host.js";import"./runner-error-classification.js";async function r(r,a){if(!t(r)||r.kind!==`device`)return;let o=await n(r).readDeviceReadiness(r,a.budgetMs,a.signal);if(a.signal?.throwIfAborted(),!o.available)return;let s=i(o);if(s)throw new e(`COMMAND_FAILED`,s.message,{reason:s.reason,hint:s.hint,deviceId:r.id,developerMode:o.developerMode,developerDiskImage:o.developerDiskImage});return{developerMode:o.developerMode,developerDiskImage:o.developerDiskImage,developerDiskImageHint:o.remedies.developerDiskImageUnavailable}}function i(e){if(e.developerMode===`disabled`)return{reason:`device_developer_mode_disabled`,message:`The iOS device reports that Developer Mode is turned off`,hint:e.remedies.developerModeOff}}export{r as preflightIosRunnerDeviceReadiness};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{m as n}from"./sdk-device.js";import{E as r,F as i,I as a,L as ee,R as te,S as ne,T as re,U as ie,_ as ae,a as oe,b as se,g as o,j as s,l as c,n as ce,p as le,s as ue}from"./host.js";import{t as de}from"./runner-cache-metadata.js";import{d as fe,m as l,n as u}from"./runner-session-types.js";import{n as pe}from"./runner-startup-transport.js";import{N as me}from"./runner-error-classification.js";import{a as he,i as d,o as ge}from"./runner-xctestrun.js";import f from"node:path";import p from"node:fs";import _e from"node:crypto";import ve from"node:os";const m=process.pid;let h;function g(){return h??={value:r(process.pid)},h.value}function _(){return Be(m,g())}function ye(e){let t=A(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:_(),ownerPid:m,ownerStartTime:g(),ownerStateDir:x(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?r(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...j(fe(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function v(e,t){return await ie({acquire:()=>ce({lockDirPath:`${E(e)}.lock`,owner:{pid:m,startTime:g(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,ownerGraceMs:5e3,description:`iOS runner lease for ${e}`}),task:t})}function y(e){try{return O(JSON.parse(p.readFileSync(E(e),`utf8`)),e)}catch{return null}}function b(e){if(!e)return{type:`empty`};if(e.ownerToken===_())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 be(e,n,r){let i=e.id,a=b(y(i));if(a.type===`empty`){await n.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(xe(a.lease)){await P(a.lease,`same-state-dir`,n);return}if(Se(a.lease,e)){await P(a.lease,`device-claim-takeover`,n);return}if(Ce(a.lease,r)){await P(a.lease,`logical-lease-takeover`,n);return}throw new t(`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:Te(a.lease,r)})}await P(a.lease,a.type,n)}function xe(e){let t=x();return!t||!e.ownerStateDir?!1:f.resolve(t)===f.resolve(e.ownerStateDir)}function Se(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&le(t)}function Ce(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:we(t.deviceKey,e.deviceId)}function we(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function x(){return se()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function Te(e,t){let n=Ee(e),r=De(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 Ee(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function De(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${Oe(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function Oe(e,t){return`${e}=${a(t)}`}function S(e){let t=b(y(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 ke(e){let t=S(e);return t.type===`adoptable`?t.lease:null}function C(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function w(e,t){let n=b(y(e));n.type===`owned`&&await P(n.lease,`owned`,t)}async function Ae(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Pe(e);await Promise.all(n.map(async e=>{await P(e,`owned`,t)}))}function je(e){return y(e)?.ownerToken??null}function T(e){e&&Ne({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function Me(e){let t=E(e.deviceId);p.mkdirSync(f.dirname(t),{recursive:!0}),ne({destination:t,contents:JSON.stringify(e,null,2)})}function Ne(e){let t=y(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{p.unlinkSync(E(e.deviceId))}catch{}}function E(e){return f.join(D(),`${Ve(e)}.json`)}function D(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?f.resolve(e):f.join(ve.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Pe(e){let t,n=D();try{t=p.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=Fe(f.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function Fe(e){try{let t=JSON.parse(p.readFileSync(e,`utf8`)),n=k(t.deviceId);return n?O(t,n):null}catch{return null}}function O(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=Ie(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:M(n.ownerStartTime),ownerStateDir:M(n.ownerStateDir)??void 0,runnerPid:N(n.runnerPid),runnerStartTime:M(n.runnerStartTime),runnerLogPath:A(n.runnerLogPath),...j(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Ie(e){let t={ownerToken:k(e.ownerToken),ownerPid:N(e.ownerPid),sessionId:k(e.sessionId),port:N(e.port),xctestrunPath:k(e.xctestrunPath),jsonPath:k(e.jsonPath),createdAtMs:Le(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 A(e){return k(e)??void 0}function j(e){let t=k(e);return t?{simulatorSetPath:t}:{}}function M(e){return typeof e==`string`?e:null}function N(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function Le(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function P(e,t,n){c({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(F(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(F(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),T(e)}function Re(e,t){return o(t)&&I(e,t)}function F(e){let t=e.runnerPid??void 0;if(!(!t||!o(t))){if(I(e,t))return t;c({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function I(e,t){return e.runnerStartTime?r(t)===e.runnerStartTime:ze(re(t))}function ze(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function Be(e,t){let n=_e.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function Ve(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var He=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>L,abortRunnerSessionsAndPrepProcesses:()=>H,cleanupOwnedIosRunnerLease:()=>V,disposeRunnerSession:()=>B,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>z,stopRunnerPrepProcesses:()=>U});const L=1e3,R=2e3,z={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Ke,cleanupTempFile:l};async function B(e,t={}){u(e,`draining`);let r=!1;if(t.graceful!==!1)r=await Ue(e);else if(n(e.device)){await G([e]),await q(e,t);return}else await $(e.child.pid,`SIGTERM`);r||(await W(e,t.waitTimeoutMs??1e4),Y(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await q(e,t)}async function V(e){await w(e,z)}async function H(e){let t=Array.from(d),r=e.filter(e=>n(e.device)),i=e.filter(e=>!n(e.device));for(let t of e)u(t,`draining`);await Z(i,`SIGINT`),await Q(t,`SIGINT`),await Z(i,`SIGTERM`),await Q(t,`SIGTERM`),await Z(i,`SIGKILL`),await Q(t,`SIGKILL`),await G(r),await Promise.allSettled(e.map(async e=>{await q(e)}))}async function U(){let e=Array.from(d);await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{d.delete(e)}}))}async function Ue(e){try{return await pe(e.device,e.port,me({command:`shutdown`}),void 0,15e3),!1}catch{return n(e.device)?(await G([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function W(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 G(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await K(e,5e3);await Z(t,`SIGTERM`),await Z(await K(t,2e3),`SIGKILL`)}async function K(e,t){let n=await Promise.all(e.map(async e=>await W(e,t)));return e.filter((e,t)=>!n[t])}async function q(e,t={}){await J(e,t),l(e.xctestrunPath),l(e.jsonPath),u(e,`stopped`)}async function J(e,t){let n=async()=>{if(!We(e))try{await Ge(e.device)}finally{T(e.lease)}};if(t.leaseLockHeld){await n();return}try{await v(e.deviceId,n)}catch(t){c({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 We(e){let t=je(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Ge(e){e.kind===`simulator`&&await Promise.allSettled(de.map(async t=>{try{await i(oe(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:R})}catch(n){c({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:R,error:n instanceof Error?n.message:String(n)}})}}))}function Y(e){return e?X(e)||ae(e):!1}function X(e){return e?o(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`&&d.delete(e)}))}async function $(e,t){if(!e||e<=0)return;te(e,t),ee([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await s(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Ke(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${ge(e.xctestrunPath)??he(t)}`;for(let e of[`TERM`,`KILL`])try{await s(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){c({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{I as _,X as a,U as c,Ae as d,Re as f,_ as g,ke as h,B as i,C as l,S as m,H as n,z as o,be as p,V as r,He as s,L as t,ye as u,v,Me as y};
1
+ import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{m as n}from"./sdk-device.js";import{C as r,D as i,E as a,I as ee,L as te,M as o,R as ne,W as re,_ as s,a as ie,m as ae,n as oe,s as se,u as c,v as ce,x as le,z as ue}from"./host.js";import{t as de}from"./runner-cache-metadata.js";import{d as l,m as u,n as d}from"./runner-session-types.js";import{n as fe}from"./runner-startup-transport.js";import{N as pe}from"./runner-error-classification.js";import{a as me,i as f,o as he}from"./runner-xctestrun.js";import p from"node:path";import m from"node:fs";import ge from"node:crypto";import _e from"node:os";const h=process.pid;let g;function _(){return g??={value:i(process.pid)},g.value}function v(){return ze(h,_())}function ve(e){let t=j(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:v(),ownerPid:h,ownerStartTime:_(),ownerStateDir:S(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?i(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...M(l(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function y(e,t){return await re({acquire:()=>oe({lockDirPath:`${D(e)}.lock`,owner:{pid:h,startTime:_(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,ownerGraceMs:5e3,description:`iOS runner lease for ${e}`}),task:t})}function b(e){try{return k(JSON.parse(m.readFileSync(D(e),`utf8`)),e)}catch{return null}}function x(e){if(!e)return{type:`empty`};if(e.ownerToken===v())return{type:`owned`,lease:e};let t=se({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 ye(e,n,r){let i=e.id,a=x(b(i));if(a.type===`empty`){await n.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(be(a.lease)){await F(a.lease,`same-state-dir`,n);return}if(xe(a.lease,e)){await F(a.lease,`device-claim-takeover`,n);return}if(Se(a.lease,r)){await F(a.lease,`logical-lease-takeover`,n);return}throw new t(`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:we(a.lease,r)})}await F(a.lease,a.type,n)}function be(e){let t=S();return!t||!e.ownerStateDir?!1:p.resolve(t)===p.resolve(e.ownerStateDir)}function xe(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&ae(t)}function Se(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:Ce(t.deviceKey,e.deviceId)}function Ce(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function S(){return le()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function we(e,t){let n=Te(e),r=Ee(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 Te(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function Ee(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${De(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function De(e,t){return`${e}=${te(t)}`}function C(e){let t=x(b(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 Oe(e){let t=C(e);return t.type===`adoptable`?t.lease:null}function w(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function T(e,t){let n=x(b(e));n.type===`owned`&&await F(n.lease,`owned`,t)}async function ke(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Ne(e);await Promise.all(n.map(async e=>{await F(e,`owned`,t)}))}function Ae(e){return b(e)?.ownerToken??null}function E(e){e&&Me({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function je(e){let t=D(e.deviceId);m.mkdirSync(p.dirname(t),{recursive:!0}),r({destination:t,contents:JSON.stringify(e,null,2)})}function Me(e){let t=b(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{m.unlinkSync(D(e.deviceId))}catch{}}function D(e){return p.join(O(),`${Be(e)}.json`)}function O(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?p.resolve(e):p.join(_e.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Ne(e){let t,n=O();try{t=m.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=Pe(p.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function Pe(e){try{let t=JSON.parse(m.readFileSync(e,`utf8`)),n=A(t.deviceId);return n?k(t,n):null}catch{return null}}function k(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=Fe(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:N(n.ownerStartTime),ownerStateDir:N(n.ownerStateDir)??void 0,runnerPid:P(n.runnerPid),runnerStartTime:N(n.runnerStartTime),runnerLogPath:j(n.runnerLogPath),cacheKey:j(n.cacheKey),...M(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Fe(e){let t={ownerToken:A(e.ownerToken),ownerPid:P(e.ownerPid),sessionId:A(e.sessionId),port:P(e.port),xctestrunPath:A(e.xctestrunPath),jsonPath:A(e.jsonPath),createdAtMs:Ie(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function A(e){return typeof e==`string`&&e.length>0?e:null}function j(e){return A(e)??void 0}function M(e){let t=A(e);return t?{simulatorSetPath:t}:{}}function N(e){return typeof e==`string`?e:null}function P(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function Ie(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function F(e,t,n){c({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(I(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(I(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),E(e)}function Le(e,t){return s(t)&&L(e,t)}function I(e){let t=e.runnerPid??void 0;if(!(!t||!s(t))){if(L(e,t))return t;c({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function L(e,t){return e.runnerStartTime?i(t)===e.runnerStartTime:Re(a(t))}function Re(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function ze(e,t){let n=ge.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function Be(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var Ve=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>R,abortRunnerSessionsAndPrepProcesses:()=>U,cleanupOwnedIosRunnerLease:()=>H,disposeRunnerSession:()=>V,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>B,stopRunnerPrepProcesses:()=>W});const R=1e3,z=2e3,B={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Ke,cleanupTempFile:u};async function V(e,t={}){d(e,`draining`);let r=!1;if(t.graceful!==!1)r=await He(e);else if(n(e.device)){await K([e]),await J(e,t);return}else await $(e.child.pid,`SIGTERM`);r||(await G(e,t.waitTimeoutMs??1e4),Y(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await J(e,t)}async function H(e){await T(e,B)}async function U(e){let t=Array.from(f),r=e.filter(e=>n(e.device)),i=e.filter(e=>!n(e.device));for(let t of e)d(t,`draining`);await Z(i,`SIGINT`),await Q(t,`SIGINT`),await Z(i,`SIGTERM`),await Q(t,`SIGTERM`),await Z(i,`SIGKILL`),await Q(t,`SIGKILL`),await K(r),await Promise.allSettled(e.map(async e=>{await J(e)}))}async function W(){let e=Array.from(f);await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{f.delete(e)}}))}async function He(e){try{return await fe(e.device,e.port,pe({command:`shutdown`}),void 0,15e3),!1}catch{return n(e.device)?(await K([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function G(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 K(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await q(e,5e3);await Z(t,`SIGTERM`),await Z(await q(t,2e3),`SIGKILL`)}async function q(e,t){let n=await Promise.all(e.map(async e=>await G(e,t)));return e.filter((e,t)=>!n[t])}async function J(e,t={}){await Ue(e,t),u(e.xctestrunPath),u(e.jsonPath),d(e,`stopped`)}async function Ue(e,t){let n=async()=>{if(!We(e))try{await Ge(e.device)}finally{E(e.lease)}};if(t.leaseLockHeld){await n();return}try{await y(e.deviceId,n)}catch(t){c({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 We(e){let t=Ae(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Ge(e){e.kind===`simulator`&&await Promise.allSettled(de.map(async t=>{try{await ee(ie(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:z})}catch(n){c({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:z,error:n instanceof Error?n.message:String(n)}})}}))}function Y(e){return e?X(e)||ce(e):!1}function X(e){return e?s(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`&&f.delete(e)}))}async function $(e,t){if(!e||e<=0)return;ue(e,t),ne([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await o(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Ke(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${he(e.xctestrunPath)??me(t)}`;for(let e of[`TERM`,`KILL`])try{await o(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){c({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{L as _,X as a,W as c,ke as d,Le as f,v as g,Oe as h,V as i,w as l,C as m,U as n,B as o,ye as p,H as r,Ve as s,R as t,ve as u,y as v,je as y};
@@ -1,3 +1,3 @@
1
- import{F as e,N as t,W as n,et as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{f as a,m as o,y 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=a(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)||a(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&d(e.signal.reason)}function re(e){let t=a(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 n;try{n=JSON.parse(e)}catch{throw new t(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!h(n))throw new t(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return n}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,n){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 t(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:n})}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(t){if(s(t))throw e()}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=e=>e.runnerReadinessPreflightFailed===!0&&!n(e),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{F as e,N as t,W as n,et as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{b as a,h as o,p 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=s(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 a(e.requestId)||s(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&d(e.signal.reason)}function re(e){let t=s(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 n;try{n=JSON.parse(e)}catch{throw new t(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!h(n))throw new t(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return n}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,n){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 t(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:n})}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(t){if(a(t))throw e()}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=e=>e.runnerReadinessPreflightFailed===!0&&!n(e),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,n){if(e instanceof t){for(let t of H)if(t.verdicts[n]!==void 0&&U(e,t.match))return t.verdicts[n]}}function he(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`?!1:G(e,`retryable`)??!1}function ge(e){return K(e)?!0:e instanceof t&&e.details?.runnerErrorCode===`MAIN_THREAD_TIMEOUT`}function K(e){return G(e,`drainResend`)??!1}function _e(e){return e instanceof t&&e.details?.runner!==void 0}function ve(e){return!(e instanceof t)||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 t&&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 t)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,n){if(!n||!(e instanceof t))return e;let r=we(e)===void 0&&n.developerDiskImage===`unavailable`&&!Ee(e)&&!Te(e);return new t(e.code,e.message,{...e.details??{},...r?{reason:`device_developer_disk_image_unavailable`,hint:n.developerDiskImageHint}:{},developerDiskImage:n.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:o(e)}function Ee(e){let t=e.details?.startupRuleMatched;return typeof t==`boolean`?t:Q(e).matched}export{_ as A,f as C,m as D,ne as E,re as M,b as N,oe as O,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,te as j,g 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{N as e}from"./sdk-contracts.js";import{V as t,l as n,t as r}from"./host.js";import{g as i,n as a}from"./runner-session-types.js";import{i as o,n as s,t as c}from"./runner-startup-transport.js";import{A as l,N as u,O as d,S as f,T as p,b as m,c as h,k 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,n,i,a,o,s){let c=await C(i,{timeoutMs:a,signal:s}),l=u(n),d=m(l),f=r.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:d})}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:a,logPath:c,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:a.command,commandId:a.commandId,readOnly:!0,sessionReady:i.state===`ready`,timeoutMs:m}:{command:a.command,commandId:a.commandId},g=!f(a);g&&i.commandCharges.charge(a.commandId);try{return await t(`ios_runner_command_send`,async()=>p?await s(r,i.port,a,c,m,i,d):await o(r,i.port,a,m,d),h)}catch(e){throw g&&i.commandCharges.markAbandoned(a.commandId),e}}async function R(e){let{device:n,session:r,runnerCommand:i,logAttempt:a,deadline:o,signal:c,decision:l}=e,d=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 s(n,r.port,u({command:`uptime`}),d,f,r,c),{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,r){n({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:r.reason,lastHealthyMutationAgeMs:r.reason===`recent_healthy_mutation`?r.lastHealthyMutationAgeMs:void 0,sessionReady:t.state===`ready`}})}async function B(e,t,n){let r=d(await e.text());if(!g(r))throw await w({error:p(r,n?.logPath),logSince:n});a(t,`ready`);let i=l(r);return V(i),i}function V(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&n({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())):c}export{M as executeRunnerExchange,K as readRunnerStartupTimeoutMs};
1
+ import{N as e}from"./sdk-contracts.js";import{H as t,t as n,u as r}from"./host.js";import{g as i,n as a}from"./runner-session-types.js";import{i as o,n as s,t as c}from"./runner-startup-transport.js";import{A as l,N as u,O as d,S as f,T as p,b as m,c as h,k 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=u(r),d=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:d})}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:a,logPath:c,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:a.command,commandId:a.commandId,readOnly:!0,sessionReady:i.state===`ready`,timeoutMs:m}:{command:a.command,commandId:a.commandId},g=!f(a);g&&i.commandCharges.charge(a.commandId);try{return await t(`ios_runner_command_send`,async()=>p?await s(r,i.port,a,c,m,i,d):await o(r,i.port,a,m,d),h)}catch(e){throw g&&i.commandCharges.markAbandoned(a.commandId),e}}async function R(e){let{device:n,session:r,runnerCommand:i,logAttempt:a,deadline:o,signal:c,decision:l}=e,d=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 s(n,r.port,u({command:`uptime`}),d,f,r,c),{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=d(await e.text());if(!g(r))throw await w({error:p(r,n?.logPath),logSince:n});a(t,`ready`);let i=l(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())):c}export{M as executeRunnerExchange,K as readRunnerStartupTimeoutMs};
@@ -1 +1 @@
1
- import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,d as r,f as i,g as a,h as o,l 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{f as S,l as C,n as w,p as T,u as E}from"./runner-xctestrun.js";import{_ as D,h 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{C as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,w 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,O as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,S as requireCertifiedRunnerCacheArtifacts,c as requireRunnerBuildSettingsMatchBuildLog,E as resolveExistingRunnerProductPaths,s as resolveExpectedRunnerCacheMetadata,l as resolveRunnerAppBundleId,r as resolveRunnerArchBuildSettings,i as resolveRunnerBundleBuildSettings,o as resolveRunnerPerformanceBuildSettings,a as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,n as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,D as verifyLeaseRunnerPidIdentity,T as writeRunnerCacheMetadataForArtifacts};
1
+ import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,d as r,f as i,g as a,l as o,s,u as c,v 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{f as S,l as C,n as w,p as T,u as E}from"./runner-xctestrun.js";import{_ as D,h 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{C as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,w 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,O as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,S as requireCertifiedRunnerCacheArtifacts,s as requireRunnerBuildSettingsMatchBuildLog,E as resolveExistingRunnerProductPaths,o as resolveExpectedRunnerCacheMetadata,c as resolveRunnerAppBundleId,r as resolveRunnerArchBuildSettings,i as resolveRunnerBundleBuildSettings,a as resolveRunnerPerformanceBuildSettings,n as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,l as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,D as verifyLeaseRunnerPidIdentity,T as writeRunnerCacheMetadataForArtifacts};
@@ -1 +1 @@
1
- import{N as e}from"./sdk-contracts.js";import{z as t}from"./host.js";import{o as n}from"./runner-cache-metadata.js";import r from"node:path";import i from"node:fs";import a from"node:os";import o from"node:net";async function s(){return await new Promise((t,n)=>{let r=o.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let e=i.port;r.close(()=>t(e))}else r.close(()=>n(new e(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,n)})}function c(e,t,n,r){t&&d(t,e),n&&d(n,e),r&&process.stderr.write(e)}const l=new Map,u=new Map;function d(e,t){let n=(l.get(e)??Promise.resolve()).then(()=>f(e,t),()=>f(e,t)).then(()=>{u.delete(e)},t=>{u.set(e,t)}).finally(()=>{l.get(e)===n&&l.delete(e)});l.set(e,n)}async function f(e,t){await i.promises.mkdir(r.dirname(e),{recursive:!0}),await i.promises.appendFile(e,t)}async function p(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=l.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=u.get(e);if(i!==void 0)throw i}function m(e){try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function h(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return r.join(a.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function g(e,t){let n=0;try{n=i.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function _(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,a=null,o=null,s=!1,c=()=>{if(!s)try{a??=i.openSync(e.file.logPath,`r`);let t=i.fstatSync(a).size;for(t<r&&(r=0);r<t;){let o=Math.min(n.length,t-r),s=i.readSync(a,n,0,o,r);if(s<=0)break;r+=s,e.onOutput(n.toString(`utf8`,0,s)),t=i.fstatSync(a).size}}catch{u()}},l=()=>{s||(o=setTimeout(()=>{c(),l()},t),o.unref?.())};function u(){if(!s&&(s=!0,o&&clearTimeout(o),o=null,a!==null)){try{i.closeSync(a)}catch{}a=null}}return l(),{drain:()=>{c(),u()},stop:u}}function v(e,t){if(!e)return``;let n=null;try{n=i.openSync(e.logPath,`r`);let r=i.fstatSync(n).size,a=Math.max(e.startOffset,r-t),o=r-a;if(o<=0)return``;let s=Buffer.alloc(o),c=i.readSync(n,s,0,o,a);return s.toString(`utf8`,0,Math.max(c,0))}catch{return``}finally{if(n!==null)try{i.closeSync(n)}catch{}}}function y(e){return t(e).simulatorSetPath}function b(e,n){let r=t(e),i=t(n);return r.udid===i.udid&&r.simulatorSetPath===i.simulatorSetPath}function x(e,t){let n=y(e);return n===void 0?[`-destination`,t]:[`-destination`,t,`-DVTSimulatorSetLocation=${n}`]}function S(e){let t=y(e);if(t===void 0)return{};let r=n(e);return r===void 0?{simulatorSetPath:t}:{simulatorSetPath:t,xcodeVersion:r}}function C(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 w={starting:[`ready`,`draining`,`stopped`],ready:[`draining`,`stopped`],draining:[`stopped`],stopped:[]};function T(e,t){w[e.state].includes(t)&&(e.state=t)}function E(e){return e.state===`starting`||e.state===`ready`}function D(e){return e?.runnerMainThreadBusy===!0}var O=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:k(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=k(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=k(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 k(e){return e?.trim()??``}function A(e){return e.state===`ready`?e.commandCharges.hasOutstandingCharges?{detach:!1,reason:`command_in_flight`}:D(e)?{detach:!1,reason:`main_thread_occupied`}:{detach:!0}:{detach:!1,reason:`runner_never_served_a_command`}}function j(e){return e.processRunning?e.state:`gone`}function M(e,t){return`${e}:${t}:${Date.now()}`}function N(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}export{s as _,D as a,h as b,j as c,y as d,C as f,p as g,g as h,E as i,b as l,m,T as n,N as o,x as p,M as r,A as s,O as t,S as u,c as v,_ as x,v as y};
1
+ import{N as e}from"./sdk-contracts.js";import{B as t}from"./host.js";import{o as n}from"./runner-cache-metadata.js";import r from"node:path";import i from"node:fs";import a from"node:os";import o from"node:net";async function s(){return await new Promise((t,n)=>{let r=o.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let e=i.port;r.close(()=>t(e))}else r.close(()=>n(new e(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,n)})}function c(e,t,n,r){t&&d(t,e),n&&d(n,e),r&&process.stderr.write(e)}const l=new Map,u=new Map;function d(e,t){let n=(l.get(e)??Promise.resolve()).then(()=>f(e,t),()=>f(e,t)).then(()=>{u.delete(e)},t=>{u.set(e,t)}).finally(()=>{l.get(e)===n&&l.delete(e)});l.set(e,n)}async function f(e,t){await i.promises.mkdir(r.dirname(e),{recursive:!0}),await i.promises.appendFile(e,t)}async function p(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=l.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=u.get(e);if(i!==void 0)throw i}function m(e){try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function h(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return r.join(a.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function g(e,t){let n=0;try{n=i.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function _(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,a=null,o=null,s=!1,c=()=>{if(!s)try{a??=i.openSync(e.file.logPath,`r`);let t=i.fstatSync(a).size;for(t<r&&(r=0);r<t;){let o=Math.min(n.length,t-r),s=i.readSync(a,n,0,o,r);if(s<=0)break;r+=s,e.onOutput(n.toString(`utf8`,0,s)),t=i.fstatSync(a).size}}catch{u()}},l=()=>{s||(o=setTimeout(()=>{c(),l()},t),o.unref?.())};function u(){if(!s&&(s=!0,o&&clearTimeout(o),o=null,a!==null)){try{i.closeSync(a)}catch{}a=null}}return l(),{drain:()=>{c(),u()},stop:u}}function v(e,t){if(!e)return``;let n=null;try{n=i.openSync(e.logPath,`r`);let r=i.fstatSync(n).size,a=Math.max(e.startOffset,r-t),o=r-a;if(o<=0)return``;let s=Buffer.alloc(o),c=i.readSync(n,s,0,o,a);return s.toString(`utf8`,0,Math.max(c,0))}catch{return``}finally{if(n!==null)try{i.closeSync(n)}catch{}}}function y(e){return t(e).simulatorSetPath}function b(e,n){let r=t(e),i=t(n);return r.udid===i.udid&&r.simulatorSetPath===i.simulatorSetPath}function x(e,t){let n=y(e);return n===void 0?[`-destination`,t]:[`-destination`,t,`-DVTSimulatorSetLocation=${n}`]}function S(e){let t=y(e);if(t===void 0)return{};let r=n(e);return r===void 0?{simulatorSetPath:t}:{simulatorSetPath:t,xcodeVersion:r}}function C(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 w={starting:[`ready`,`draining`,`stopped`],ready:[`draining`,`stopped`],draining:[`stopped`],stopped:[]};function T(e,t){w[e.state].includes(t)&&(e.state=t)}function E(e){return e.state===`starting`||e.state===`ready`}function D(e){return e?.runnerMainThreadBusy===!0}var O=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:k(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=k(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=k(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 k(e){return e?.trim()??``}function A(e){return e.state===`ready`?e.commandCharges.hasOutstandingCharges?{detach:!1,reason:`command_in_flight`}:D(e)?{detach:!1,reason:`main_thread_occupied`}:{detach:!0}:{detach:!1,reason:`runner_never_served_a_command`}}function j(e){return e.processRunning?e.state:`gone`}function M(e,t){return`${e}:${t}:${Date.now()}`}function N(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}export{s as _,D as a,h as b,j as c,y as d,C as f,p as g,g as h,E as i,b as l,m,T as n,N as o,x as p,M as r,A as s,O as t,S as u,c as v,_ as x,v as y};
@@ -1 +1 @@
1
- import{F as e,G as t,N as n}from"./sdk-contracts.js";import{l as r}from"./host.js";import{i}from"./runner-cache-metadata.js";import{o as a}from"./runner-session-types.js";import{M as o}from"./runner-error-classification.js";import"./runner-xctestrun.js";function s(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(c(n,t!==void 0))},n);s.unref?.();let l=o(e),u=l?AbortSignal.any([l,r.signal]):r.signal;return{phase:i(n,u),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function c(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 l(t,n){return n?await new Promise((r,i)=>{let a=()=>{i(e(void 0,n.reason)),t.catch(u)};n.aborted?a():n.addEventListener(`abort`,a,{once:!0}),t.then(r,i).finally(()=>n.removeEventListener(`abort`,a))}):await t}function u(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{s as openRunnerStartBudget,l as raceRunnerStartAgainstCaller};
1
+ import{F as e,G as t,N 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{M as o}from"./runner-error-classification.js";import"./runner-xctestrun.js";function s(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(c(n,t!==void 0))},n);s.unref?.();let l=o(e),u=l?AbortSignal.any([l,r.signal]):r.signal;return{phase:i(n,u),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function c(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 l(t,n){return n?await new Promise((r,i)=>{let a=()=>{i(e(void 0,n.reason)),t.catch(u)};n.aborted?a():n.addEventListener(`abort`,a,{once:!0}),t.then(r,i).finally(()=>n.removeEventListener(`abort`,a))}):await t}function u(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{s as openRunnerStartBudget,l as raceRunnerStartAgainstCaller};
@@ -1 +1 @@
1
- import{B as e,F as t,G as n,N as r,R as i}from"./sdk-contracts.js";import{n as a}from"./entities.js";import{t as o}from"./parser.js";import{A as s,F as c,O as l,a as u,i as d,k as f,o as p,t as m}from"./host.js";import{f as h,u as g}from"./runner-session-types.js";import{d as _,i as v,m as y,r as ee,s as te,t as ne,v as b}from"./runner-error-classification.js";import re from"node:net";import x from"node:http";const S=new Map;function C(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return T(e,t,null,!1);let o=f(e);if(o.backend===`xctest`||!r)return ie(e,t);if(!a){let r=ae(e.id);if(r)return T(e,t,r,!0);if(n!==void 0)return T(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&oe(e.id,s),T(e,t,s,!1)}}}function w(e){S.delete(e)}function ie(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function T(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 ae(e){let t=S.get(e);return t?t.expiresAt<=Date.now()?(S.delete(e),null):t.ip:null}function oe(e,t){S.set(e,{ip:t,expiresAt:Date.now()+3e4})}const E=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function D(e,t,n,r,i){let a=m.fromTimeoutMs(r);return await se(e,t,await O(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function O(e,t,n,i){let a=await k(e,n,i);try{await A(a,1,M(`ListDevices`));let e=ce((await j(a,n,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new r(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:E})}finally{a.destroy()}}async function se(e,t,n,r,i,a){let o=await k(e,i,a);try{await A(o,2,M(`Connect`,{DeviceID:n,PortNumber:I(r)}));let e=ue((await j(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw F({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function k(e,n,i){if(L(n,`connect to usbmuxd`),i?.aborted)throw t();return await new Promise((a,o)=>{let s=re.createConnection(e),c=!1,l=setTimeout(()=>{p(new r(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:n}))},n),u=()=>p(),d=e=>p(e),f=()=>p(t()),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 A(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 j(e,n,i){if(L(n,`read usbmuxd response`),i?.aborted)throw t();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new r(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:n})),n),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new r(`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 r(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(t()),m=(t,n)=>{c||(c=!0,clearTimeout(l),e.off(`data`,u),e.off(`error`,d),e.off(`close`,f),i?.removeEventListener(`abort`,p),e.pause(),t?o(t):a(n))};e.on(`data`,u),e.once(`error`,d),e.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),e.resume()})}function M(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 ce(e,t){for(let n of P(o(e))){let e=le(n);if(e?.udid===t)return e.id}}function le(e){if(e.name!==`dict`)return;let t=N(e,`Properties`);if(t?.name!==`dict`)return;let n=N(t,`SerialNumber`)?.text,r=Number(N(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function ue(e,t){for(let n of P(o(e))){if(n.name!==`dict`)continue;let e=N(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function N(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*P(e){for(let t of e)yield t,yield*P(t.children)}function F(e){let{result:t,udid:n,deviceId:i,port:a}=e;return t===2?new r(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:n,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:E}):t===3?new r(`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 r(`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 I(e){return(e&255)<<8|e>>>8&255}function L(e,t){if(!(e>0))throw new r(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function R(e){return{postCommand:async(t,n,a,o,s)=>{let c=m.fromTimeoutMs(o),l=await D(e,t,n,c.remainingMs(),s).catch(e=>{throw e instanceof r?i(e,`no`):e});try{return await B(l,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const z=R(`/var/run/usbmuxd`);async function B(e,n,i,a){if(de(i),a?.aborted)throw t();let o=Buffer.from(JSON.stringify(n),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new x.Agent;l.createConnection=(t,n)=>(n?.(null,e),e);try{let t=await V(l,e,o,c);return new Response((await H(t)).toString(`utf8`),{status:t.statusCode??500})}catch(e){throw a?.aborted?t():s.aborted?new r(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):e}finally{l.destroy(),e.destroy()}}async function V(e,t,n,r){return await new Promise((i,a)=>{let o=x.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 H(e){let t=[],n=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(n+=e.length,n>67108864)throw new r(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function de(e){if(!(e>0))throw new r(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const U=45e3;async function fe(e,n,i,a=U,o){if(o?.aborted)throw t();let s=m.fromTimeoutMs(a),c=C(e,n),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await pe(e,n,i,s,o)}catch(t){if(!W(e,t))throw t;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new r(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:n,endpoints:l.endpoints});return await G(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function pe(e,t,n,i,a){let o=i.remainingMs();if(o<=0)throw new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await z.postCommand(e.id,t,n,o,a)}function W(e,t){return _(t)?f(e).backend!==`xctest`:!1}async function G(e,t,n,i){let a=AbortSignal.timeout(n),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:n},e):e}}const K=45e3,q=2e4;async function me(e,r,i,a,o=K,c,l){let u=m.fromTimeoutMs(o),{resolveRoute:d,markUsbmuxUnattached:f}=C(e,r),p=await d(u.remainingMs()),h=null,g=!1,v=Math.max(1,Math.ceil(o/250));try{return await s(async({deadline:t})=>{let n=await he({device:e,port:r,command:i,timeoutMs:o,logPath:a,session:c,route:p,resolveRoute:d,markUsbmuxUnattached:f,signal:l,attemptDeadline:t,setRoute:e=>{p=e},setLastError:e=>{h=e,te(e)||(g=!0)}});if(n)return n;throw ye({port:r,endpoints:p.endpoints,lastError:h,signal:l})},{maxAttempts:v,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:b},{deadline:u,phase:`ios_runner_connect`,signal:l,retryWakeSignal:e.kind===`simulator`?c?.startupRetryWake:void 0})}catch(e){if(l?.aborted||n(e))throw t();if(_(e))throw e;h||=e}if(l?.aborted)throw t();if(e.kind===`simulator`){let t=u.remainingMs();if(t<=0)throw J(Q({port:r,endpoints:p.endpoints,logPath:a,lastError:h}),g);let n=await Z(e,r,i,t,l).catch(e=>{throw J(e,g)});return new Response(n.body,{status:n.status})}throw c?.child.exitCode!==null&&c?.child.exitCode!==void 0?J(await $({session:c,port:r,logPath:a}),g):J(Q({port:r,endpoints:p.endpoints,logPath:a,lastError:h,deviceStates:c?.startupDeviceStates}),g)}function J(t,n){return t instanceof r?n?i(t,`unknown`):e(t,`no`):t}async function he(e){await ge(e);let t=await _e(e);return t.response?t.response:await ve(e)||await Y(e,t.usedCachedTunnelIp)}async function ge(e){if(e.attemptDeadline?.isExpired())throw new r(`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 $({session:e.session,port:e.port,logPath:e.logPath})}async function _e(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&&w(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 ve(e){return e.device.kind!==`simulator`||e.session?.state!==`ready`?null:await xe(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Y(e,t){if(e.device.kind!==`device`||!t)return null;w(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 ye(e){if(e.signal?.aborted)throw t();return new r(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,endpoints:e.endpoints,lastError:e.lastError?String(e.lastError):void 0,...y(`runner_endpoint_probe_exhausted`)})}async function X(e,a,o){if(a.kind===`network`)return await be(a.endpoints,o);let s=a.endpoints[0];try{let t=o.attemptDeadline?.remainingMs()??o.timeoutMs;if(t<=0)throw i(new r(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o.port,timeoutMs:o.timeoutMs}),`no`);return await z.postCommand(e.id,o.port,o.command,Math.min(q,t),o.signal)}catch(r){if(o.signal?.aborted||n(r))throw t();if(_(r)){if(!W(e,r))throw r;return o.onUsbmuxUnattached?.(),null}return o.onError(s,r),null}}async function be(e,a){let{command:o,port:s,timeoutMs:c,signal:l,attemptDeadline:u,onError:d}=a;for(let a of e)try{let e=u?.remainingMs()??c;if(e<=0)throw i(new r(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:s,timeoutMs:c}),`no`);return await G(a,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(o)},Math.min(q,e),l)}catch(e){if(l?.aborted||n(e))throw t();d(a,e)}return null}async function xe(e,r,i,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let t=await Z(e,r,i,l,o);return new Response(t.body,{status:t.status})}catch(e){if(o?.aborted||n(e))throw t();return c(e),null}}async function Z(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:l(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),...y(`runner_connect_refused`),dispatched:e.exitCode===7?`no`:`unknown`}}).stdout}}function Se(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)} ${ne}`}function Q(e){let{port:t,endpoints:n,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new r(`COMMAND_FAILED`,s,{port:t,endpoints:n,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`),...y(`runner_connect_refused`)});return v(c,o)}async function $(e){let{session:t,port:n,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=g(t.device),u=ee(new r(`COMMAND_FAILED`,o,{stderr:s,...l})),d=u.reason===`simulator_set_destination_not_found`,f=new r(`COMMAND_FAILED`,d?h(o,t.device,l):o,{port:n,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:d?u.reason:c,hint:d?u.hint:Se(o,s,s,c),...l,...y(`xcodebuild_exited_early`)});return v(f,t.startupDeviceStates)}export{fe as i,me as n,U as r,K as t};
1
+ import{B as e,F as t,G as n,N as r,R as i}from"./sdk-contracts.js";import{n as a}from"./entities.js";import{t as o}from"./parser.js";import{A as s,I as c,a as l,i as u,j as d,k as f,o as p,t as m}from"./host.js";import{f as h,u as g}from"./runner-session-types.js";import{d as _,i as v,m as y,r as ee,s as te,t as ne,v as b}from"./runner-error-classification.js";import re from"node:net";import x from"node:http";const S=new Map;function C(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return T(e,t,null,!1);let o=s(e);if(o.backend===`xctest`||!r)return ie(e,t);if(!a){let r=ae(e.id);if(r)return T(e,t,r,!0);if(n!==void 0)return T(e,t,n,!1)}let{tunnelIp:c}=await o.resolveTunnel(e,i);return n=c,c&&oe(e.id,c),T(e,t,c,!1)}}}function w(e){S.delete(e)}function ie(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function T(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 ae(e){let t=S.get(e);return t?t.expiresAt<=Date.now()?(S.delete(e),null):t.ip:null}function oe(e,t){S.set(e,{ip:t,expiresAt:Date.now()+3e4})}const E=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function D(e,t,n,r,i){let a=m.fromTimeoutMs(r);return await se(e,t,await O(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function O(e,t,n,i){let a=await k(e,n,i);try{await A(a,1,M(`ListDevices`));let e=ce((await j(a,n,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new r(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:E})}finally{a.destroy()}}async function se(e,t,n,r,i,a){let o=await k(e,i,a);try{await A(o,2,M(`Connect`,{DeviceID:n,PortNumber:I(r)}));let e=ue((await j(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw F({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function k(e,n,i){if(L(n,`connect to usbmuxd`),i?.aborted)throw t();return await new Promise((a,o)=>{let s=re.createConnection(e),c=!1,l=setTimeout(()=>{p(new r(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:n}))},n),u=()=>p(),d=e=>p(e),f=()=>p(t()),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 A(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 j(e,n,i){if(L(n,`read usbmuxd response`),i?.aborted)throw t();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new r(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:n})),n),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new r(`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 r(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(t()),m=(t,n)=>{c||(c=!0,clearTimeout(l),e.off(`data`,u),e.off(`error`,d),e.off(`close`,f),i?.removeEventListener(`abort`,p),e.pause(),t?o(t):a(n))};e.on(`data`,u),e.once(`error`,d),e.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),e.resume()})}function M(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 ce(e,t){for(let n of P(o(e))){let e=le(n);if(e?.udid===t)return e.id}}function le(e){if(e.name!==`dict`)return;let t=N(e,`Properties`);if(t?.name!==`dict`)return;let n=N(t,`SerialNumber`)?.text,r=Number(N(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function ue(e,t){for(let n of P(o(e))){if(n.name!==`dict`)continue;let e=N(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function N(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*P(e){for(let t of e)yield t,yield*P(t.children)}function F(e){let{result:t,udid:n,deviceId:i,port:a}=e;return t===2?new r(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:n,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:E}):t===3?new r(`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 r(`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 I(e){return(e&255)<<8|e>>>8&255}function L(e,t){if(!(e>0))throw new r(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function R(e){return{postCommand:async(t,n,a,o,s)=>{let c=m.fromTimeoutMs(o),l=await D(e,t,n,c.remainingMs(),s).catch(e=>{throw e instanceof r?i(e,`no`):e});try{return await B(l,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const z=R(`/var/run/usbmuxd`);async function B(e,n,i,a){if(de(i),a?.aborted)throw t();let o=Buffer.from(JSON.stringify(n),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new x.Agent;l.createConnection=(t,n)=>(n?.(null,e),e);try{let t=await V(l,e,o,c);return new Response((await H(t)).toString(`utf8`),{status:t.statusCode??500})}catch(e){throw a?.aborted?t():s.aborted?new r(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):e}finally{l.destroy(),e.destroy()}}async function V(e,t,n,r){return await new Promise((i,a)=>{let o=x.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 H(e){let t=[],n=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(n+=e.length,n>67108864)throw new r(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function de(e){if(!(e>0))throw new r(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const U=45e3;async function fe(e,n,i,a=U,o){if(o?.aborted)throw t();let s=m.fromTimeoutMs(a),c=C(e,n),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await pe(e,n,i,s,o)}catch(t){if(!W(e,t))throw t;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new r(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:n,endpoints:l.endpoints});return await G(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function pe(e,t,n,i,a){let o=i.remainingMs();if(o<=0)throw new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await z.postCommand(e.id,t,n,o,a)}function W(e,t){return _(t)?s(e).backend!==`xctest`:!1}async function G(e,t,n,i){let a=AbortSignal.timeout(n),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:n},e):e}}const K=45e3,q=2e4;async function me(e,r,i,a,o=K,s,c){let l=m.fromTimeoutMs(o),{resolveRoute:u,markUsbmuxUnattached:f}=C(e,r),p=await u(l.remainingMs()),h=null,g=!1,v=Math.max(1,Math.ceil(o/250));try{return await d(async({deadline:t})=>{let n=await he({device:e,port:r,command:i,timeoutMs:o,logPath:a,session:s,route:p,resolveRoute:u,markUsbmuxUnattached:f,signal:c,attemptDeadline:t,setRoute:e=>{p=e},setLastError:e=>{h=e,te(e)||(g=!0)}});if(n)return n;throw ye({port:r,endpoints:p.endpoints,lastError:h,signal:c})},{maxAttempts:v,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:b},{deadline:l,phase:`ios_runner_connect`,signal:c,retryWakeSignal:e.kind===`simulator`?s?.startupRetryWake:void 0})}catch(e){if(c?.aborted||n(e))throw t();if(_(e))throw e;h||=e}if(c?.aborted)throw t();if(e.kind===`simulator`){let t=l.remainingMs();if(t<=0)throw J(Q({port:r,endpoints:p.endpoints,logPath:a,lastError:h}),g);let n=await Z(e,r,i,t,c).catch(e=>{throw J(e,g)});return new Response(n.body,{status:n.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?J(await $({session:s,port:r,logPath:a}),g):J(Q({port:r,endpoints:p.endpoints,logPath:a,lastError:h,deviceStates:s?.startupDeviceStates}),g)}function J(t,n){return t instanceof r?n?i(t,`unknown`):e(t,`no`):t}async function he(e){await ge(e);let t=await _e(e);return t.response?t.response:await ve(e)||await Y(e,t.usedCachedTunnelIp)}async function ge(e){if(e.attemptDeadline?.isExpired())throw new r(`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 $({session:e.session,port:e.port,logPath:e.logPath})}async function _e(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&&w(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 ve(e){return e.device.kind!==`simulator`||e.session?.state!==`ready`?null:await xe(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Y(e,t){if(e.device.kind!==`device`||!t)return null;w(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 ye(e){if(e.signal?.aborted)throw t();return new r(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,endpoints:e.endpoints,lastError:e.lastError?String(e.lastError):void 0,...y(`runner_endpoint_probe_exhausted`)})}async function X(e,a,o){if(a.kind===`network`)return await be(a.endpoints,o);let s=a.endpoints[0];try{let t=o.attemptDeadline?.remainingMs()??o.timeoutMs;if(t<=0)throw i(new r(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o.port,timeoutMs:o.timeoutMs}),`no`);return await z.postCommand(e.id,o.port,o.command,Math.min(q,t),o.signal)}catch(r){if(o.signal?.aborted||n(r))throw t();if(_(r)){if(!W(e,r))throw r;return o.onUsbmuxUnattached?.(),null}return o.onError(s,r),null}}async function be(e,a){let{command:o,port:s,timeoutMs:c,signal:l,attemptDeadline:u,onError:d}=a;for(let a of e)try{let e=u?.remainingMs()??c;if(e<=0)throw i(new r(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:s,timeoutMs:c}),`no`);return await G(a,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(o)},Math.min(q,e),l)}catch(e){if(l?.aborted||n(e))throw t();d(a,e)}return null}async function xe(e,r,i,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let t=await Z(e,r,i,l,o);return new Response(t.body,{status:t.status})}catch(e){if(o?.aborted||n(e))throw t();return c(e),null}}async function Z(e,t,n,r,i){let a=JSON.stringify(n),o=l(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:f(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:u(n),...y(`runner_connect_refused`),dispatched:e.exitCode===7?`no`:`unknown`}}).stdout}}function Se(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`?u(a):`${u(a)} ${ne}`}function Q(e){let{port:t,endpoints:n,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new r(`COMMAND_FAILED`,s,{port:t,endpoints:n,logPath:i,lastError:a?String(a):void 0,reason:p({error:a,message:s,context:{platform:`ios`,phase:`connect`}}),hint:u(`IOS_RUNNER_CONNECT_TIMEOUT`),...y(`runner_connect_refused`)});return v(c,o)}async function $(e){let{session:t,port:n,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=g(t.device),u=ee(new r(`COMMAND_FAILED`,o,{stderr:s,...l})),d=u.reason===`simulator_set_destination_not_found`,f=new r(`COMMAND_FAILED`,d?h(o,t.device,l):o,{port:n,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:d?u.reason:c,hint:d?u.hint:Se(o,s,s,c),...l,...y(`xcodebuild_exited_early`)});return v(f,t.startupDeviceStates)}export{fe as i,me as n,U as r,K as t};
@@ -1 +1 @@
1
- import{G as e,N as t,P as n}from"./sdk-contracts.js";import{m as r}from"./sdk-device.js";import{t as i}from"./parser.js";import{B as a,C as o,E as s,H as c,N as l,O as u,U as d,d as f,h as p,j as m,l as ee,m as te,n as ne,u as re,v as h}from"./host.js";import{d as g,r as _}from"./apple-runner-platform.js";import{_ as ie,a as ae,c as oe,d as se,f as ce,g as le,h as ue,l as v,m as de,n as y,p as b,r as x,v as S,y as fe}from"./runner-cache-metadata.js";import{f as pe,p as me,u as he,v as C}from"./runner-session-types.js";import{r as ge}from"./runner-error-classification.js";import w from"node:path";import T from"node:fs";import _e from"node:crypto";import ve from"node:os";const E=new Set;function D(e){return w.join(e,y)}function ye(e,t){T.mkdirSync(e,{recursive:!0}),T.writeFileSync(D(e),`${JSON.stringify(t,null,2)}\n`)}async function be(e,t){if(e.cache===`external`){P(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}E.add(e.derived),await d({acquire:()=>O(e.derived),task:async()=>{P(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),M(e.derived),j(e.derived)}})}async function O(e){return await ne({lockDirPath:xe(e),owner:{pid:process.pid,startTime:s(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,ownerGraceMs:5e3,description:`iOS runner cache lock`})}function xe(e){return w.join(w.dirname(e),`${w.basename(e)}.lock`)}function Se(e,t){!De()&&!t&&!E.has(e)||(P(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),M(e),j(e),E.delete(e))}async function k(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return ye(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(P(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function A(e,n){if(e)throw new t(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:e.reason,refusingPath:e.path??n,...e.reason===`root_unusable`?{}:{resolvesTo:e.target},derived:n,hint:`Inspect ${e.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 j(e){try{if(!T.existsSync(e))return;if(w.basename(e)!==`derived`){T.rmSync(e,{recursive:!0,force:!0});return}for(let t of T.readdirSync(e,{withFileTypes:!0}))we(t.name)&&T.rmSync(w.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Ce=new Set([y,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function we(e){return Ce.has(e)}function Te(e){try{let t=JSON.parse(T.readFileSync(D(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function Ee(e,t){let n=Te(e);return n?S(x(n))===S(x(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:ae(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function De(){return p(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function M(e,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!Oe(e))throw new t(`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 ${w.join(f(),`.tmp`)}.`})}function Oe(e){let t=w.resolve(f(),`.tmp`),n=w.relative(t,w.resolve(e));return n!==``&&!n.startsWith(`..`)&&!w.isAbsolute(n)}async function N(e){let t=Ee(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 ke(e,t){P(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function P(e,t,n){ee({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const Ae=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),F=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function I(e,n,i){if(!r(e))return;if(n.length===0)throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:i});let a=Array.from(new Set(n)).sort((e,t)=>t.length-e.length);for(let e of a)if(!T.existsSync(e))throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:i});for(let e of a)await R(e)||await je(e,i)}async function je(e,t){try{let t=w.join(e,`Contents`,`Frameworks`),n=T.existsSync(t)?T.readdirSync(t).sort().map(e=>w.join(t,e)):[];for(let e of n)await m(`codesign`,[...F,e]);await m(`codesign`,[...F,e])}catch(r){let i=n(r,`COMMAND_FAILED`);throw L(e,t,i.message,i.details)}if(!await R(e))throw L(e,t,`Product still fails code signature verification after re-signing`)}function L(e,n,r,i){return new t(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:n,error:r,details:i})}function Me(e){if(!(e instanceof t))return!1;let n=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof n==`string`&&Ae.has(n)}async function R(e){return(await m(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const z=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function B(e){let t=await Fe(e);if(!t||t.length===0)return null;let n=w.dirname(e),r=new Set,i=Ne(t,n);for(let e of i.testRootPaths){if(!T.existsSync(e))return null;r.add(e)}for(let e of Pe(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Ne(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(w.join(t,e));let o=Ve(e);o&&r.add(w.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function Pe(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>T.existsSync(w.join(e,t)));return n?w.join(n,t):null})}async function Fe(e){let t=await o(e);if(t)return Ie(t);if(process.platform===`darwin`)return null;try{return Be(T.readFileSync(e,`utf8`))}catch{return null}}function Ie(e){let t=new Set;for(let n of[e,...Le(e),...Re(e)])for(let e of ze(n))t.add(e);return Array.from(t)}function Le(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 Re(e){return Object.values(e).filter(e=>h(e)&&`TestBundlePath`in e)}function ze(e){let t=new Set;for(let[n,r]of Object.entries(e))if(z.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 Be(e){return V(i(e))}function V(e){let t=new Set;return a(e,(e,n)=>{if(z.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 Ve(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const He=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function Ue(e){await H(tt(e))}async function H(e){let t=e.filter(et);if(t.length===0)return;let n=e.filter(e=>W(e)&&!U(e));for(let e of t){let t=$e(e,n);t&&await We(t,e)}}async function We(e,t){let n=Ge(e,t),r=await Ke(e,t);(n||r)&&(await Ye(t),Qe(t))}function Ge(e,t){let n=!1;for(let r of T.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!Ze(r.name)||Xe(w.join(e,r.name),w.join(t,r.name))&&(n=!0);return n}async function Ke(e,t){let n=w.join(e,`Info.plist`),r=w.join(t,`Info.plist`),i=await o(n),a=await o(r);if(!i||!a)return!1;let s=qe(i,a);if(s.length===0)return!1;for(let e of s)await Je(r,e.key,e.value,e.shouldInsert);return!0}function qe(e,t){return He.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 Je(e,t,n,r){u(await m(`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 Ye(e){u(await m(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function Xe(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 Ze(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function Qe(e){let t=new Date;T.utimesSync(e,t,t)}function $e(e,t){let n=w.dirname(e);return t.find(e=>w.dirname(e)===n&&w.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>w.dirname(t)===n&&t!==e)??null}function et(e){return W(e)&&U(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function U(e){return w.basename(e).endsWith(`-Runner.app`)}function W(e){return w.basename(e).endsWith(`.app`)}function tt(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=w.join(e,r.name);if(W(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const G=`AgentDeviceRunner.env`,K=`session`,nt=`${J(`${G}.${K}`)}-`;function rt(e){return q(`${K}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function it(e){return`${nt}${J(q(e))}-[0-9]`}function at(e){let t=e?w.basename(e):``;if(t.startsWith(`${G}.`))return J(t)}function q(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function J(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const ot={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function st(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?w.resolve(i):w.dirname(e);T.mkdirSync(a,{recursive:!0});let o=q(n),s=w.join(a,`${G}.${o}.json`),c=w.join(a,`${G}.${o}.xctestrun`),l=await ct(e);return Y(l,e=>ut(e,t)),dt(l),await lt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function ct(e){let n=await m(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(n.exitCode!==0||!n.stdout.trim())throw new t(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:n.stderr});try{let e=JSON.parse(n.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(n){throw new t(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(n)})}}async function lt(e,t,n){T.writeFileSync(t,JSON.stringify(e,null,2)),u(await m(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function ut(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function dt(e){Y(e,e=>Object.assign(e,ot),{requireTestBundlePath:!0})}function Y(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||ft(e.TestTargets,t,n);for(let n of Object.values(e)){let e=X(n,{requireTestBundlePath:!0});e&&t(e)}}function ft(e,t,n){if(Array.isArray(e))for(let r of e){let e=X(r,n);e&&t(e)}}function X(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const pt=new Map,Z=new Set;async function mt(e,t){let n=ht(t);if(n)return n;let r=f(),i=v(e,r,t.budget),a=b(e,i);return await c(pt,a,async()=>await d({acquire:()=>O(a),task:()=>_t({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function ht(e){let n=e.iosXctestrunFile?.trim();if(!n)return null;let r=w.resolve(n);if(!T.existsSync(r))throw new t(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:r});let i=e.iosXctestDerivedDataPath?.trim(),a=i?w.resolve(i):gt(r);return P(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:r}),{xctestrunPath:r,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function gt(e){let t=_e.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return w.join(ve.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function _t(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;Se(a,e.forceRebuild);let o=await N({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await vt({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&ke(o,a),o.reason!==`cache_metadata_missing`&&(M(a),j(a)),await yt({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function vt(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await bt(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function yt(e){let{device:n,options:r,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=fe(i);if(!T.existsSync(l))throw new t(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=oe(r.budget,`runner_xctestrun_build`),d=Date.now();re({type:`command`,status:`progress`,message:`Building Apple runner...`}),await wt(n,l,o,r,u);let f=Math.max(0,Date.now()-d),p=Q(o,n);if(!p)throw new t(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await B(p);if(!m)throw new t(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await I(n,m,p),await H(m),A(await k(o,a,p,m),o),P(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function bt(e,t,n,r){try{return await I(e,r.productPaths,r.xctestrunPath),A(await k(t,n,r.xctestrunPath,r.productPaths),t),P(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!Me(e))throw e;return P(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function xt(e){try{let t=f(),n=v(e,t);return(await N({derived:b(e,n),expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function Q(e,t){let n=St(e);return n.length===0?null:(n.sort((e,n)=>Ct(e,n,t)),n[0]?.path??null)}function St(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=w.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 Ct(e,t,n){if(n){let r=$(t.path,n)-$(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function $(e,t){let n=0,r=e.toLowerCase();w.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${w.sep}macos${w.sep}`)&&(n-=5e3);let i=g(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 wt(n,r,i,a,o){let s=ce(process.env),c=ie(process.env,n.kind===`device`,n),u=n.kind===`device`?[`-allowProvisioningUpdates`]:[],d=ue(),f=se(process.env),p=le();try{await l(`xcodebuild`,[`build-for-testing`,`-project`,r,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,de(n),`1`,...me(n,_(n)),`-derivedDataPath`,i,...d,...f,...p,...s,...u,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:e=>{Z.add(e),e.on(`close`,()=>{Z.delete(e)})},onStdoutChunk:e=>{C(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{C(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(r){if(e(r))throw r;let i=r instanceof t?r:new t(`COMMAND_FAILED`,String(r)),o=he(n),{reason:s,hint:c,matched:l}=ge(new t(i.code,i.message,{...i.details,...o})),u=te(i),d=`xcodebuild build-for-testing failed`;throw new t(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?pe(d,n,o):d,{reason:s,error:i.message,details:i.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}export{it as a,st as c,be as d,A as f,Z as i,Ue as l,Q as n,at as o,k as p,xt as r,rt as s,mt as t,B as u};
1
+ import{G as e,N as t,P as n}from"./sdk-contracts.js";import{m as r}from"./sdk-device.js";import{t as i}from"./parser.js";import{D as a,M as o,P as s,U as c,V as l,W as u,d,f,g as p,h as m,k as h,n as ee,u as te,w as g,y as _}from"./host.js";import{d as ne,r as re}from"./apple-runner-platform.js";import{_ as ie,a as ae,b as oe,c as se,d as ce,f as le,g as ue,h as de,l as v,m as y,n as b,p as x,r as S,v as fe,y as C}from"./runner-cache-metadata.js";import{f as pe,p as me,u as he,v as w}from"./runner-session-types.js";import{r as ge}from"./runner-error-classification.js";import T from"node:path";import E from"node:fs";import _e from"node:crypto";import ve from"node:os";const D=new Set;function O(e){return T.join(e,b)}function ye(e,t){E.mkdirSync(e,{recursive:!0}),E.writeFileSync(O(e),`${JSON.stringify(t,null,2)}\n`)}async function be(e,t){if(e.cache===`external`){F(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}D.add(e.derived),await u({acquire:()=>k(e.derived),task:async()=>{F(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),N(e.derived),M(e.derived)}})}async function k(e){return await ee({lockDirPath:xe(e),owner:{pid:process.pid,startTime:a(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,ownerGraceMs:5e3,description:`iOS runner cache lock`})}function xe(e){return T.join(T.dirname(e),`${T.basename(e)}.lock`)}function Se(e,t){!De()&&!t&&!D.has(e)||(F(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),N(e),M(e),D.delete(e))}async function A(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return ye(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(F(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function j(e,n){if(e)throw new t(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:e.reason,refusingPath:e.path??n,...e.reason===`root_unusable`?{}:{resolvesTo:e.target},derived:n,hint:`Inspect ${e.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 M(e){try{if(!E.existsSync(e))return;if(T.basename(e)!==`derived`){E.rmSync(e,{recursive:!0,force:!0});return}for(let t of E.readdirSync(e,{withFileTypes:!0}))we(t.name)&&E.rmSync(T.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Ce=new Set([b,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function we(e){return Ce.has(e)}function Te(e){try{let t=JSON.parse(E.readFileSync(O(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function Ee(e,t){let n=Te(e);return n?C(S(n))===C(S(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:ae(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function De(){return p(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function N(e,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!Oe(e))throw new t(`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 ${T.join(f(),`.tmp`)}.`})}function Oe(e){let t=T.resolve(f(),`.tmp`),n=T.relative(t,T.resolve(e));return n!==``&&!n.startsWith(`..`)&&!T.isAbsolute(n)}async function P(e){let t=Ee(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 ke(e,t){F(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function F(e,t,n){te({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const Ae=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),I=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function L(e,n,i){if(!r(e))return;if(n.length===0)throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:i});let a=Array.from(new Set(n)).sort((e,t)=>t.length-e.length);for(let e of a)if(!E.existsSync(e))throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:i});for(let e of a)await z(e)||await je(e,i)}async function je(e,t){try{let t=T.join(e,`Contents`,`Frameworks`),n=E.existsSync(t)?E.readdirSync(t).sort().map(e=>T.join(t,e)):[];for(let e of n)await o(`codesign`,[...I,e]);await o(`codesign`,[...I,e])}catch(r){let i=n(r,`COMMAND_FAILED`);throw R(e,t,i.message,i.details)}if(!await z(e))throw R(e,t,`Product still fails code signature verification after re-signing`)}function R(e,n,r,i){return new t(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:n,error:r,details:i})}function Me(e){if(!(e instanceof t))return!1;let n=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof n==`string`&&Ae.has(n)}async function z(e){return(await o(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const B=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function V(e){let t=await Fe(e);if(!t||t.length===0)return null;let n=T.dirname(e),r=new Set,i=Ne(t,n);for(let e of i.testRootPaths){if(!E.existsSync(e))return null;r.add(e)}for(let e of Pe(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Ne(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(T.join(t,e));let o=He(e);o&&r.add(T.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function Pe(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>E.existsSync(T.join(e,t)));return n?T.join(n,t):null})}async function Fe(e){let t=await g(e);if(t)return Ie(t);if(process.platform===`darwin`)return null;try{return Be(E.readFileSync(e,`utf8`))}catch{return null}}function Ie(e){let t=new Set;for(let n of[e,...Le(e),...Re(e)])for(let e of ze(n))t.add(e);return Array.from(t)}function Le(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!_(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(_))}return n}function Re(e){return Object.values(e).filter(e=>_(e)&&`TestBundlePath`in e)}function ze(e){let t=new Set;for(let[n,r]of Object.entries(e))if(B.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 Be(e){return Ve(i(e))}function Ve(e){let t=new Set;return l(e,(e,n)=>{if(B.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 He(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const Ue=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function We(e){await H(nt(e))}async function H(e){let t=e.filter(tt);if(t.length===0)return;let n=e.filter(e=>W(e)&&!U(e));for(let e of t){let t=et(e,n);t&&await Ge(t,e)}}async function Ge(e,t){let n=Ke(e,t),r=await qe(e,t);(n||r)&&(await Xe(t),$e(t))}function Ke(e,t){let n=!1;for(let r of E.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!Qe(r.name)||Ze(T.join(e,r.name),T.join(t,r.name))&&(n=!0);return n}async function qe(e,t){let n=T.join(e,`Info.plist`),r=T.join(t,`Info.plist`),i=await g(n),a=await g(r);if(!i||!a)return!1;let o=Je(i,a);if(o.length===0)return!1;for(let e of o)await Ye(r,e.key,e.value,e.shouldInsert);return!0}function Je(e,t){return Ue.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 Ye(e,t,n,r){h(await o(`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 Xe(e){h(await o(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function Ze(e,t){if(E.existsSync(t)){let n=E.readFileSync(e),r=E.readFileSync(t);return!n.equals(r)&&(E.copyFileSync(e,t),!0)}return E.copyFileSync(e,t),!0}function Qe(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function $e(e){let t=new Date;E.utimesSync(e,t,t)}function et(e,t){let n=T.dirname(e);return t.find(e=>T.dirname(e)===n&&T.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>T.dirname(t)===n&&t!==e)??null}function tt(e){return W(e)&&U(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function U(e){return T.basename(e).endsWith(`-Runner.app`)}function W(e){return T.basename(e).endsWith(`.app`)}function nt(e){if(!E.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of E.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=T.join(e,r.name);if(W(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const G=`AgentDeviceRunner.env`,K=`session`,rt=`${J(`${G}.${K}`)}-`;function it(e){return q(`${K}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function at(e){return`${rt}${J(q(e))}-[0-9]`}function ot(e){let t=e?T.basename(e):``;if(t.startsWith(`${G}.`))return J(t)}function q(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function J(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const st={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function ct(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?T.resolve(i):T.dirname(e);E.mkdirSync(a,{recursive:!0});let o=q(n),s=T.join(a,`${G}.${o}.json`),c=T.join(a,`${G}.${o}.xctestrun`),l=await lt(e);return Y(l,e=>dt(e,t)),ft(l),await ut(l,s,c),{xctestrunPath:c,jsonPath:s}}async function lt(e){let n=await o(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(n.exitCode!==0||!n.stdout.trim())throw new t(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:n.stderr});try{let e=JSON.parse(n.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(n){throw new t(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(n)})}}async function ut(e,t,n){E.writeFileSync(t,JSON.stringify(e,null,2)),h(await o(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function dt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function ft(e){Y(e,e=>Object.assign(e,st),{requireTestBundlePath:!0})}function Y(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||pt(e.TestTargets,t,n);for(let n of Object.values(e)){let e=X(n,{requireTestBundlePath:!0});e&&t(e)}}function pt(e,t,n){if(Array.isArray(e))for(let r of e){let e=X(r,n);e&&t(e)}}function X(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const mt=new Map,Z=new Set;async function ht(e,t){let n=gt(t);if(n)return n;let r=f(),i=v(e,r,t.budget),a=y(e,i);return await c(mt,a,async()=>await u({acquire:()=>k(a),task:()=>vt({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function gt(e){let n=e.iosXctestrunFile?.trim();if(!n)return null;let r=T.resolve(n);if(!E.existsSync(r))throw new t(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:r});let i=e.iosXctestDerivedDataPath?.trim(),a=i?T.resolve(i):_t(r);return F(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:r}),{xctestrunPath:r,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function _t(e){let t=_e.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return T.join(ve.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function vt(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;Se(a,e.forceRebuild);let o=await P({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await yt({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&ke(o,a),o.reason!==`cache_metadata_missing`&&(N(a),M(a)),await bt({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function yt(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await xt(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:x(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function bt(e){let{device:n,options:r,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=oe(i);if(!E.existsSync(l))throw new t(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=se(r.budget,`runner_xctestrun_build`),f=Date.now();d({type:`command`,status:`progress`,message:`Building Apple runner...`}),await Tt(n,l,o,r,u);let p=Math.max(0,Date.now()-f),m=Q(o,n);if(!m)throw new t(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let h=await V(m);if(!h)throw new t(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:m});return await L(n,h,m),await H(h),j(await A(o,a,m,h),o),F(`build`,`built_new`,{derived:o,xctestrunPath:m}),{xctestrunPath:m,derived:o,cache:s,cacheKey:x(a),artifact:`rebuilt`,buildMs:p,xctestrunPathSource:`build`,reason:c}}async function xt(e,t,n,r){try{return await L(e,r.productPaths,r.xctestrunPath),j(await A(t,n,r.xctestrunPath,r.productPaths),t),F(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!Me(e))throw e;return F(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function St(e){try{let t=f(),n=v(e,t);return(await P({derived:y(e,n),expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function Q(e,t){let n=Ct(e);return n.length===0?null:(n.sort((e,n)=>wt(e,n,t)),n[0]?.path??null)}function Ct(e){if(!E.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=E.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=T.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=E.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function wt(e,t,n){if(n){let r=$(t.path,n)-$(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function $(e,t){let n=0,r=e.toLowerCase();T.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${T.sep}macos${T.sep}`)&&(n-=5e3);let i=ne(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 Tt(n,r,i,a,o){let c=le(process.env),l=fe(process.env,n.kind===`device`,n),u=n.kind===`device`?[`-allowProvisioningUpdates`]:[],d=ue(),f=ce(process.env),p=ie();try{await s(`xcodebuild`,[`build-for-testing`,`-project`,r,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,de(n),`1`,...me(n,re(n)),`-derivedDataPath`,i,...d,...f,...p,...c,...u,...l],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:e=>{Z.add(e),e.on(`close`,()=>{Z.delete(e)})},onStdoutChunk:e=>{w(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{w(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(r){if(e(r))throw r;let i=r instanceof t?r:new t(`COMMAND_FAILED`,String(r)),o=he(n),{reason:s,hint:c,matched:l}=ge(new t(i.code,i.message,{...i.details,...o})),u=m(i),d=`xcodebuild build-for-testing failed`;throw new t(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?pe(d,n,o):d,{reason:s,error:i.message,details:i.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}export{at as a,ct as c,be as d,j as f,Z as i,We as l,Q as n,ot as o,A as p,St as r,it as s,ht as t,V as u};