agent-device 0.21.21 → 0.21.23

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 (61) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.21.apk → agent-device-android-ime-helper-0.21.23.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.23.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.21.manifest.json → agent-device-android-ime-helper-0.21.23.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.21.manifest.json → agent-device-android-snapshot-helper-0.21.23.manifest.json} +6 -6
  7. package/dist/src/android-input-ownership.js +1 -1
  8. package/dist/src/app-log-reconnect.js +1 -1
  9. package/dist/src/app-log-runtime2.js +3 -3
  10. package/dist/src/back-mode.js +1 -1
  11. package/dist/src/client-metro-companion.js +1 -1
  12. package/dist/src/client-metro.js +1 -1
  13. package/dist/src/client-options.js +3 -3
  14. package/dist/src/cloud-artifacts.d.ts +6 -0
  15. package/dist/src/code-signature-cache.js +1 -1
  16. package/dist/src/connection-runtime.js +1 -1
  17. package/dist/src/daemon-registration-owner.js +1 -1
  18. package/dist/src/device-session.js +3 -1
  19. package/dist/src/dispatch-resolve.js +1 -1
  20. package/dist/src/doctor-facade.js +1 -1
  21. package/dist/src/durable-capture-resource.js +1 -1
  22. package/dist/src/file.js +1 -1
  23. package/dist/src/helper.js +2 -2
  24. package/dist/src/ime-rebind.js +1 -0
  25. package/dist/src/ime-state.js +1 -0
  26. package/dist/src/instance-client.js +1 -1
  27. package/dist/src/interactor.js +1 -1
  28. package/dist/src/internal/bin.js +1 -1
  29. package/dist/src/internal/daemon.js +1 -1
  30. package/dist/src/ios-client.js +4 -4
  31. package/dist/src/ios-settings.js +1 -1
  32. package/dist/src/ios-snapshot-engine.js +1 -1
  33. package/dist/src/log-stream.js +33 -0
  34. package/dist/src/mechanics.js +16 -16
  35. package/dist/src/node-http.js +1 -0
  36. package/dist/src/owner-identity.js +1 -1
  37. package/dist/src/perf-runtime-plan.js +1 -1
  38. package/dist/src/platform-runtime-app-log-process.js +1 -1
  39. package/dist/src/platform-runtime-operation-host.js +1 -1
  40. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
  41. package/dist/src/process.js +1 -1
  42. package/dist/src/proxy.js +2 -2
  43. package/dist/src/registry.js +1 -1
  44. package/dist/src/runner-client.js +1 -1
  45. package/dist/src/runner-disposal.js +1 -1
  46. package/dist/src/runner-operations-facade.js +1 -1
  47. package/dist/src/runner-start-budget.js +1 -1
  48. package/dist/src/runtime10.js +1 -1
  49. package/dist/src/screenshot-overlay-draw.js +1 -1
  50. package/dist/src/screenshot-runtime.js +1 -1
  51. package/dist/src/script.js +1 -1
  52. package/dist/src/sdk-batch.js +2 -2
  53. package/dist/src/sdk-contracts.d.ts +5 -4
  54. package/dist/src/simctl-settings.js +1 -1
  55. package/dist/src/store.js +1 -1
  56. package/package.json +11 -8
  57. package/server.json +2 -2
  58. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.21.apk.sha256 +0 -1
  59. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.21.apk +0 -0
  60. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.21.apk.sha256 +0 -1
  61. package/dist/src/session-stream.js +0 -27
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{F as t,I as n,K as r,P as i,V as a,z as o}from"./sdk-contracts.js";import{v as s}from"./sdk-batch-runner.js";import{c,r as l}from"./diagnostics.js";import"./diagnostics2.js";import{d as u,p as d}from"./sdk-device.js";import{o as f}from"./sdk-remote-config.js";import{A as p,S as m,T as h,h as g,m as _,t as v,w as ee,y 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{a as le,t as ue}from"./file.js";import"./command.js";import"./process.js";import{a as de,r as fe}from"./version.js";import{t as pe}from"./ttl-memo.js";import{i as me,n as he,r as ge}from"./retry.js";import{o as _e}from"./device-shell.js";import{t as ve}from"./keyed-lock.js";import{n as ye,t as be}from"./boot-diagnostics.js";import{i as xe,r as Se}from"./request-cancel.js";import{t as Ce}from"./request.js";import{a as we,n as Te,o as Ee,r as De}from"./tool-provider.js";import{t as Oe}from"./physical-device-control.js";import{a as ke,o as Ae}from"./runner.js";import{C as je,L as Me,M as Ne,P as Pe,W as Fe,a as y,d as Ie,h as Le,r as Re,t as ze,u as b,v as x}from"./host.js";import{o as Be,s as Ve}from"./apple-runner-platform.js";import{c as He,g as Ue,h as We,i as Ge,l as Ke,m as qe,t as Je}from"./runner-cache-metadata.js";import{t as Ye}from"./plist-xml.js";import{n as Xe,t as Ze}from"./runner-owner-state.js";import{l as Qe,n as $e}from"./simctl.js";import{C as et,S as tt,T as nt,_ as rt,a as it,b as at,c as ot,d as st,f as ct,h as lt,i as ut,l as S,n as dt,o as ft,p as pt,r as mt,s as ht,t as gt,w as _t,x as vt,y as yt}from"./runner-session-types.js";import{A as bt,D as xt,E as St,M as C,O as Ct,P as w,S as wt,_ as Tt,a as T,b as E,f as Et,g as Dt,h as Ot,i as kt,j as At,l as jt,n as Mt,o as Nt,u as Pt,v as Ft,w as D}from"./runner-error-classification.js";import{O as It,T as Lt,_ as Rt,a as zt,b as O,c as Bt,d as Vt,f as Ht,h as Ut,i as Wt,m as Gt,n as Kt,o as qt,p as Jt,r as Yt,t as k,u as Xt,v as Zt,w as Qt,x as $t,y as en}from"./runner-disposal.js";import A from"node:fs";import tn from"node:path";const nn={runCmdStreaming:se,runCmdSync:ie,runCmdBackground:ce,requireExecSuccess:oe,isCommandTimeoutError:re,commandDeveloperDir:ae,shellQuote:_e,emitDiagnostic:l,withDiagnosticTimer:c,retryWithPolicy:me,isEnvTruthy:ge,deadlineFromTimeoutMs:(e,t)=>he.fromTimeoutMs(e,t),isProcessAlive:_,isProcessGroupAlive:g,readProcessStartTime:ee,readProcessCommand:m,signalPidsBestEffort:h,signalProcessGroupBestEffort:ne,findProjectRoot:fe,readVersion:de,acquireProcessLock:ue,withProcessLock:le,withKeyedLock:ve,publishFileSync:p,classifyOwnerLiveness:v,readHostCpuArchSync:te,createTtlMemo:pe,parseBooleanLiteral:f,isRecord:s,emitRequestProgress:Ce,getRequestSignal:Se,isRequestCanceled:xe,classifyBootFailure:ye,bootFailureHint:be,runAppleToolCommand:we,runXcrun:Ee,readApplePlistJson:De,hasScopedAppleToolProvider:Te,buildSimctlArgsForDevice:$e,simulatorAddressFor:Qe,resolveIosPhysicalDeviceControl:Oe,visitXmlPlistEntries:Ye,leaseOwnerStateDir:Xe,hasDeviceClaimAuthority:e=>Ze()?.(e)??!1};function rn(e=process.env){return je(e.AGENT_DEVICE_IOS_RUNNER_DETACH??``)!==!1}async function an(e,t){if(!rn())return null;let n=Ve(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=Ut(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!==lt(e))return r(`simulator_set_mismatch`,a);let o=on(a,t.expectedRunnerSessionId);if(`refusal`in o)return r(o.refusal,a);let s=sn(e,a,t.budget);if(`refusal`in s)return r(s.refusal,a);let c=o.value,l=s.value,u=await cn(e,a.port,n.lane,t.budget);if(u!==`answered`)return r(u,a);if(!Jt(a,c))return r(`runner_pid_recycled`,a);let d=dn(e,a,c,l);try{O(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 on(e,t){if(t!==void 0&&e.sessionId!==t)return{refusal:`session_identity_mismatch`};let n=e.runnerPid;return n?x(n)?Zt(e,n)?{value:n}:{refusal:`runner_pid_recycled`}:{refusal:`runner_process_dead`}:{refusal:`runner_pid_missing`}}function sn(e,t,n){let r=un(e,n);return r?t.cacheKey!==r.cacheKey||!t.xctestrunPath.startsWith(`${r.derived}${tn.sep}`)?{refusal:`artifact_fingerprint_mismatch`}:{value:r}:{refusal:`expected_derived_unresolved`}}async function cn(e,t,n,i){let a=n===`physical_coredevice`?5e3:500,o=ln(i,a);if(o<=0)return`probe_budget_exhausted`;let s=Date.now(),c=!1;try{let n=await ct(e,t,w({command:`uptime`}),o,i?.signal);return c=bt(Ct(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 ln(e,t){return e?.deadline?Math.min(t,Math.floor(e.deadline.remainingMs())):t}function un(e,t){try{let n=Ke(e,void 0,t);return{derived:We(e,n),cacheKey:qe(n)}}catch(e){if(r(e))throw e;return null}}function dn(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}=fn(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 gt,lease:Vt({device:e,sessionId:i,runnerPid:n,port:t.port,xctestrunPath:t.xctestrunPath,cacheKey:r.cacheKey,jsonPath:t.jsonPath,runnerLogPath:t.runnerLogPath})}}function fn(e){let t={pid:e,exitCode:null};return{child:t,wait:new Promise(n=>{let r=setInterval(()=>{x(e)||(clearInterval(r),t.exitCode=-1,n({stdout:``,stderr:``,exitCode:-1}))},1e3);r.unref?.()})}}function pn(){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 mn(e){let t=e.logPath;A.mkdirSync(tn.dirname(t),{recursive:!0});let n=A.openSync(t,`a`),r=yt(t,n),i=hn(()=>{try{A.closeSync(n)}catch{}}),a=pn();try{let t=Pe(`xcodebuild`,[`test-without-building`,`-only-testing`,`AgentDeviceRunnerUITests/RunnerTests/testCommand`,`-parallel-testing-enabled`,`NO`,`-test-timeouts-enabled`,`NO`,`-collect-test-diagnostics`,`never`,Ue(e.device),`1`,`-destination-timeout`,`20`,`-xctestrun`,e.xctestrunPath,`-derivedDataPath`,e.derivedPath,...rt(e.device,Be(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=nt({file:r,onOutput:t=>{a.observe(t),(e.traceLogPath||e.verbose)&&tt(t,void 0,e.traceLogPath,e.verbose)}}),s=hn(()=>{o.stop(),i()}),c=()=>{o.drain(),i(),a.finish()};return t.wait.then(c,c),{...t,startupRetryWake:a.wake,endOutputObservation:s,readLogTail:e=>et(r,e)}}catch(e){throw i(),e}}function hn(e){let t=!1;return()=>{t||(t=!0,e())}}const j=new Map,gn=new Map,M=new Map,_n=1e4;function N(e,t){return Fe(gn,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){bn(n,t.expectedRunnerSessionId);let i=await wn(e,n,r.phase);if(i)return i}return await en(e.id,async()=>await yn(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,e.id)}const vn=1e4;async function yn(e,t,r){let i={},a=r.phase,o=a.signal,s=Wn(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 an(e,{budget:a,expectedRunnerSessionId:t.expectedRunnerSessionId}));if(c)return c.startupTimings=i,c.logicalLeaseContext=s,j.set(e.id,c),c;xn(t.expectedRunnerSessionId),await V(i,`cleanup_stale_xcodebuild`,async()=>{await Gt(e,qt,s)}),await V(i,`ensure_booted`,async()=>{await Rn(e)});let l=await V(i,`verify_device_readiness`,async()=>await(await import(`./runner-device-readiness.js`)).preflightIosRunnerDeviceReadiness(e,{budgetMs:Math.min(vn,a.deadline?.remainingMs()??vn),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 Tn(e)}):(i.cleanup_stale_bundles=0,b({level:`debug`,phase:`ios_runner_startup_cleanup_stale_bundles_skipped`}));let u,d,f,p,m=_t(t.logPath,e.id),h;try{u=await V(i,`ensure_xctestrun`,async()=>await $t(e,{...t,budget:Ge(Vn(t,r),o)})),i.build_xctestrun=u.buildMs,d=await V(i,`allocate_port`,async()=>await vt()),{xctestrunPath:f,jsonPath:p}=await V(i,`prepare_xctestrun_env`,async()=>await Lt(u.xctestrunPath,{AGENT_DEVICE_RUNNER_PORT:String(d)},Qt({deviceId:e.id,ownerToken:Rt(),port:d}),{iosXctestEnvDir:t.iosXctestEnvDir})),u.buildMs>0&&Ie({type:`command`,status:`progress`,message:`Starting XCTest runner...`}),h=await V(i,`launch_xcodebuild`,async()=>(await at(m).catch(()=>{}),await mn({device:e,port:d,xctestrunPath:f,derivedPath:u.derived,signal:o,logPath:m,traceLogPath:t.traceLogPath,verbose:t.verbose})))}catch(e){throw kt(e,l)}let g=mt(e.id,d),_=Vt({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 gt,startupRetryWake:h.startupRetryWake,launchDeadline:ze.fromTimeoutMs(Hn(r)),startupTimings:i,startupDeviceStates:l,logicalLeaseContext:s,lease:_,speculative:t.speculative===!0};if(o?.aborted)throw await Wt(v,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),n();try{O(_)}catch(t){throw await L(e.id,v,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),t}return j.set(e.id,v),v}function bn(e,t){if(t!==void 0&&e.sessionId!==t)throw Sn()}function xn(e){if(e!==void 0)throw Sn()}function Sn(){return new i(`COMMAND_FAILED`,`Apple runner session ownership changed before command dispatch`,{reason:`runner_session_ownership_changed`})}async function Cn(e,t){let n=On(t);return n===`gone`?(await V({},`stop_stale_session`,async()=>{await L(e.id,t,{graceful:!1,waitTimeoutMs:k})}),!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:k})}),!1):pt(t.device,e)?!0:(await V({},`stop_other_simulator_set_session`,async()=>{await L(e.id,t)}),!1)}async function wn(e,t,n){if(!await Cn(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=Ke(e,void 0,n),a=We(e,i),o=qe(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 Tn(e){e.kind===`simulator`&&await Promise.allSettled(Je.map(async t=>{let n=await En(e,t);!n||Dn(n)}))}async function En(e,t){try{return await Me(y(e,[`uninstall`,e.id,t]),{allowFailure:!0,timeoutMs:_n})}catch(n){b({level:`warn`,phase:`ios_runner_startup_cleanup_stale_bundle_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:_n,error:n instanceof Error?n.message:String(n)}});return}}function Dn(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:On(t)}:null}function On(e){return ot({state:e.state,processRunning:zt(e.child.pid)})}async function I(e,t){await N(e.deviceId,async()=>{j.get(e.deviceId)===e&&ut(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:k}))})}async function L(e,t,n={}){let r=t??j.get(e);r&&ut(r)&&(await Wt(r,n),j.get(e)===r&&j.delete(e))}function kn(e){R(e);let t=An();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 An(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 jn(e,t){e.speculative&&!wt(t)&&(e.speculative=!1)}async function Mn(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 en(e,async()=>{await L(e,void 0,{leaseLockHeld:!0}),await Yt(e)})})}async function Nn(e,t){let n=j.get(e);if(t.retain&&!it(n)){kn(e);return}t.retain&&b({level:`info`,phase:`ios_runner_retain_skipped_busy`,data:{deviceId:e}}),await Bt(e),await z(e)}async function Pn(){let e=Array.from(j.values());await Kt(e);for(let t of e)j.get(t.deviceId)===t&&j.delete(t.deviceId)}async function Fn(){if(!rn())return 0;let e=0;for(let[t,n]of j){let r=In(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 In(e,t){let n=Ve(t.device);if(!n.handoff)return{detached:!1,lane:void 0,reason:n.reason};let r=n.lane,i=ht(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{O(Xt(a))}catch{return{detached:!1,lane:r,reason:`lease_write_failed`}}return t.endOutputObservation?.(),j.delete(e),R(e),dt(t,`stopped`),{detached:!0,lane:r}}async function Ln(){await Pn();let e=Array.from(j.keys());await Promise.allSettled(e.map(async e=>{await z(e)})),await Bt()}function Rn(e){return e.kind===`simulator`?e.booted?(b({level:`debug`,phase:`ios_runner_startup_ensure_booted_skipped`,data:{deviceId:e.id}}),Promise.resolve()):zn(e):Promise.resolve()}async function zn(e){await Me(y(e,[`bootstatus`,e.id,`-b`]),{timeoutMs:S})}function Bn(e){if(!u(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){Un(t,n.command);let{executeRunnerExchange:o}=await import(`./runner-exchange.js`);return o(e,t,n,r,i,e=>I(t,e),a)}function Vn(e,t){let n=He(t.phase,`runner_xctestrun_build`)??t.timeoutMs,r=ft(e.buildTimeoutMs);return r===void 0?n:Math.min(r,n)}function Hn(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 Un(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 Wn(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 Gn(e){let{device:t,session:n,command:r,transportError:i,options:a,signal:o,invalidationReason:s}=e;return await Kn(await Qn(t,n,r,i,a,o),{command:r,session:n,transportError:i,options:a,invalidationReason:s,invalidateSession:e.invalidateSession})}async function Kn(e,t){if(e.type===`recovered`)return Yn(e,t);let n=qn(e,t);if(e.type===`skipInvalidation`)throw Xn(e,t,n);return await Zn(e,t,n)}function qn(e,t){return`runnerAnswer`in e?o(e.runnerAnswer,e.dispatched):E(t.command)?o(t.transportError,`unknown`):o(Jn(t,e.lostReply),`unknown`)}function Jn(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?fr(n.command,t.cause):t.message,{command:n.command,commandId:n.commandId,...t.lifecycleState===void 0?{}:{lifecycleState:t.lifecycleState},reason:Mt,...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 Yn(e,t){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.data}function Xn(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 Zn(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 Qn(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=tr(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}}}),nr(s,c,n,r,i)}const $n=new Set([`completed`,`failed`]),er=new Set([`accepted`,`started`]);function tr(e,t,n){if($n.has(n))return e.commandCharges.settleTerminalEvidence(t.commandId)}function nr(e,t,n,r,i){if(t===`completed`)return rr(e,n,r);if(t===`failed`){let a=xt(typeof e.lifecycleErrorCode==`string`?e.lifecycleErrorCode:void 0);return{type:`skipInvalidation`,reason:`runner_reported_failure`,lifecycleState:t,dispatched:a.details.dispatched,runnerAnswer:ir(e,a,n,r,i)}}return er.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:cr(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 rr(e,t,n){let r=ar(e.lifecycleResponseJson);return r?{type:`recovered`,data:r,reason:`completed_with_retained_response`,lifecycleState:`completed`}:{type:`skipInvalidation`,reason:E(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:or(t.command,W(n))}}}function ir(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??sr(n.command,c),logPath:a.logPath,transportError:r.message},r)}function ar(e){if(typeof e!=`string`||e.trim().length===0)return;let t;try{t=Ct(e)}catch{return}return bt(t)?At(t):void 0}function or(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 sr(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 cr(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 lr(e,t){let n=e.details?.[t];return typeof n==`boolean`?n:void 0}function ur(e,t){let n=e.details?.[t];return typeof n==`string`?n:void 0}function dr(e,t){let n=e.details?.[t];return typeof n==`number`?n:void 0}function W(e){let t={},n=lr(e,`runnerReadinessPreflightSkipped`);n!==void 0&&(t.readinessPreflightSkipped=n);let r=ur(e,`runnerReadinessPreflightSkipReason`);r!==void 0&&(t.readinessPreflightSkipReason=r);let i=dr(e,`runnerReadinessPreflightSkippedAgeMs`);return i!==void 0&&(t.readinessPreflightSkippedAgeMs=i),t}function fr(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 pr(e,t){let n=e.requestId?.trim();if(n)return`request:${n}`;let r=t.commandId?.trim();if(r)return`command:${r}`}function mr(e){if(!e)return;let t=J(e);t.touchedSession=!0,Y(e,t)}function hr(e){return e?q.get(e)?.touchedSession===!0:!1}function gr(e){if(!e)return!0;let t=J(e);return t.recycles>=1?(Y(e,t),!1):(Y(e,t),!0)}function _r(e){if(!e)return;let t=J(e);t.recycles+=1,Y(e,t)}function vr(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 J(e){return yr(),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 yr(){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 br(e,t){D(t.requestId);let n=C(t),r=w({command:`uptime`}),a;for(let i=1;i<=2;i+=1){let o=await xr({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 xr(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,...Ar(r,`runner_session`)}),l=Date.now()-s;try{return{kind:`prepared`,result:Fr(t,await kr(t,c,n,r,i,l,{recoveryReason:o}))}}catch(e){return await Sr({device:t,session:c,command:n,options:r,signal:i,attempt:a,error:e})}}async function Sr(e){let{device:n,session:i,command:a,options:o,signal:s,attempt:c,error:l}=e,u=t(l,`COMMAND_FAILED`);if(r(u))throw await X(i,`prepare_runner_request_canceled`),l;if(c===1&&Mr(u,i))return{kind:`prepared`,result:await Cr({device:n,session:i,command:a,options:o,signal:s,error:u})};if(!wr(u))throw l;let d=u.message||`runner_health_failed`;if(c>=2)throw await X(i,`prepare_runner_health_failed`),l;return D(o.requestId),await I(i,`prepare_runner_health_retry`),b({level:`warn`,phase:`ios_runner_prepare_health_retry`,data:{command:a.command,commandId:a.commandId,sessionId:i.sessionId,attempt:c,maxAttempts:2,reason:d}}),{kind:`retry`,recoveryReason:d}}async function Cr(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 It(n.xctestrunArtifact,s);let c=Date.now(),l=await P(t,{...i,cleanStaleBundles:!0,forceRunnerXctestrunRebuild:!0,...Ar(i,`runner_rebuild`)}),u=Date.now()-c;try{let e=await kr(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}}),Fr(t,e)}catch(e){await X(l,`prepare_rebuilt_runner_health_failed`);let n=Nr(e,l,s);throw Ir(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 wr(e){return r(e)?!1:T(e)||Ft(e)}async function Tr(e,n,r){let i={entered:!1};try{return await Er(e,n,r,i)}catch(e){let n=t(e);throw i.entered?jt(n)?a(n,`no`):n:o(n,`no`)}}async function Er(e,i,a,o){D(a.requestId);let s=C(a),c=pr(a,i),l,u=!1,d=F(e.id)?.liveness??`gone`;try{if((d===`gone`||d===`stopped`)&&hr(c)){if(!gr(c))throw vr(i,a);u=!0}l=await P(e,a),bn(l,a.expectedRunnerSessionId),jn(l,i),u&&_r(c),mr(c);let t=st;if(l.state!==`ready`){let{readRunnerStartupTimeoutMs:e}=await import(`./runner-exchange.js`);t=e(l)}return o.entered=!0,await B(e,l,i,a.logPath,t,s)}catch(o){if(a.expectedRunnerSessionId!==void 0)throw o;let c=t(o,`COMMAND_FAILED`);if((l?l.state===`starting`:d!==`ready`)&&r(c))throw l&&!St(a)&&await X(l,`runner_startup_request_canceled`),n({...c.details,readinessPhase:`runner-start`},c);if(Tt(c,i)&&l)return D(a.requestId),await Dr({device:e,session:l,command:i,options:a,signal:s,restartReason:`runner_connect_failed_before_command_send`,firstAttemptDispatched:Et(c)});if(l&&Dt(c))return D(a.requestId),await Dr({device:e,session:l,command:i,options:a,signal:s,restartReason:`runner_readiness_preflight_failed_before_command_send`,recoveredDiagnosticPhase:`ios_runner_readiness_preflight_recovered`,firstAttemptDispatched:`no`});if(l&&T(c)&&!Pt(c))return await Gn({device:e,session:l,command:i,transportError:c,options:a,signal:s,invalidationReason:`transport_error_after_command_send`,invalidateSession:I});throw o}}async function Dr(e){let{device:n,command:r,options:i,signal:a,restartReason:s}=e,c=pr(i,r);if(!gr(c))throw o(vr(r,i),e.firstAttemptDispatched);await I(e.session,s);let l=await P(n,{...i,cleanStaleBundles:!0}).catch(t=>{throw Z(t,e)});_r(c);try{let t=await B(n,l,r,i.logPath,S,a);return e.recoveredDiagnosticPhase&&b({level:`debug`,phase:e.recoveredDiagnosticPhase,data:{command:r.command,commandId:r.commandId,recovery:`session_restarted`,sessionId:l.sessionId}}),t}catch(o){let s=t(o,`COMMAND_FAILED`);if(T(s)&&!Pt(s))try{return await Gn({device:n,session:l,command:r,transportError:s,options:i,signal:a,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?Or(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 Or(e,t,n){return!n||t===`unknown`?o(e,t):a(e,jt(e)?`no`:`unknown`)}async function kr(e,t,n,r,i,a,o){let s=Date.now(),c=jr(r.prepareDeadline,r.healthTimeoutMs,`runner_health`);return Pr(await B(e,t,n,r.logPath,c,i),t,a,Date.now()-s,o)}function Ar(e,t){if(!e.prepareDeadline)return{};let n=jr(e.prepareDeadline,e.buildTimeoutMs,t);return{buildTimeoutMs:n,startupTimeoutMs:n}}function jr(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 Mr(e,t){let n=t.xctestrunArtifact;return!n||n.cache===`miss`?!1:Ot(e)}function Nr(e,n,r){let a=t(e,`COMMAND_FAILED`);return new i(a.code,`artifact restored but runner did not connect`,{...a.details??{},restoredFailureReason:r,xctestrunPath:n.xctestrunArtifact?.xctestrunPath,artifact:n.xctestrunArtifact?.artifact,cache:n.xctestrunArtifact?.cache,reason:a.message},a)}function Pr(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 Fr(e,t){return Ir(e,t),t}function Ir(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 Lr={maxAttempts:8,baseDelayMs:200,maxDelayMs:1e3,jitter:0};function Rr(e){return Nt(e)?8:T(e)?3:1}async function Q(e,t,n={}){Bn(e),D(n.requestId);let r=w(t),i=$(e,n);if(!E(r))return i.runCommand(e,r,n);let a;try{return await Ne(()=>(D(n.requestId),i.runCommand(e,r,n)),{...Lr,shouldRetry:(e,t)=>(D(n.requestId),Nt(e)&&(a=e),t<Rr(e))},{signal:C(n)})}catch(e){throw a&&St(n)?a:e}}async function zr(e,t={}){if(d(e))try{await Q(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 Br(e,t={}){if(d(e)){if(Le()){b({level:`debug`,phase:`ios_runner_cache_prewarm_unavailable`,data:{deviceId:e.id}});return}return Hr({device:e,options:t,failurePhase:`ios_runner_cache_prewarm_failed`,task:async t=>{await $t(e,{...t,budget:Ge(t.buildTimeoutMs,t.signal)})}})}}function Vr(e,t={}){if(!d(e))return;let n=$(e,t).prewarm;if(!n){b({level:`debug`,phase:`ios_runner_session_prewarm_unavailable`,data:{deviceId:e.id}});return}return Hr({device:e,options:t,failurePhase:`ios_runner_session_prewarm_failed`,task:async t=>{await n(e,t)}})}function Hr(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 Ur(e,t){Bn(e),D(t.requestId);let n=w({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 Ae(e,Kr,{requestId:t.requestId})}function Wr(e,t={}){return d(e)?$(e,t).hasLiveSession(e):!1}async function Gr(e,t={}){if(!d(e))return!1;let n=$(e,t).releaseSpeculativeSession;return n?await n(e):!1}const Kr=ke(Tr,{prepare:br,hasLiveSession:e=>F(e.id)?.liveness===`ready`,releaseSpeculativeSession:async e=>await Mn(e.id),prewarm:async(e,t)=>{let{healthCheck:n,...r}=t;if(n===!1){await P(e,{...r,speculative:!0});return}await br(e,{...r,speculative:!0,healthTimeoutMs:st})}});var qr=e({cleanupRunnerLeasesForOwner:()=>Ht,readRunnerSessionLiveness:()=>F});Re(nn);export{Br as a,Q as c,Nn as d,Ln as f,Ur as i,Fn as l,Wr as n,Vr as o,z as p,zr as r,Gr as s,qr as t,F as u};
1
+ import{r as e}from"./rolldown-runtime.js";import{F as t,I as n,K as r,P as i,V as a,z as o}from"./sdk-contracts.js";import{v as s}from"./sdk-batch-runner.js";import{c,r as l}from"./diagnostics.js";import"./diagnostics2.js";import{d as u,p as d}from"./sdk-device.js";import{o as f}from"./sdk-remote-config.js";import{S as p,T as m,h,j as g,m as _,t as v,w as y,y as ee}from"./owner-identity.js";import{h as te,i as ne,m as re,n as ie,o as ae,p as oe,u as se}from"./exec.js";import{a as ce,t as le}from"./file.js";import"./command.js";import"./process.js";import{a as ue,r as de}from"./version.js";import{t as fe}from"./ttl-memo.js";import{i as pe,n as me,r as he}from"./retry.js";import{o as ge}from"./device-shell.js";import{t as _e}from"./keyed-lock.js";import{n as ve,t as ye}from"./boot-diagnostics.js";import{i as be,r as xe}from"./request-cancel.js";import{t as Se}from"./request.js";import{a as Ce,n 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{C as Ae,L as je,M as Me,P as Ne,W as Pe,a as Fe,d as Ie,h as Le,r as Re,t as ze,u as b,v as Be}from"./host.js";import{o as Ve,s as He}from"./apple-runner-platform.js";import{c as Ue,g as We,h as Ge,i as Ke,l as qe,m as Je,t as Ye}from"./runner-cache-metadata.js";import{t as Xe}from"./plist-xml.js";import{n as Ze,t as Qe}from"./runner-owner-state.js";import{l as $e,n as et}from"./simctl.js";import{C as tt,S as nt,T as rt,_ as it,a as at,b as ot,c as st,d as ct,f as lt,h as ut,i as dt,l as x,n as ft,o as pt,p as mt,r as ht,s as gt,t as _t,w as vt,x as yt,y as bt}from"./runner-session-types.js";import{A as xt,D as St,E as Ct,M as S,O as wt,P as C,S as Tt,_ as Et,a as w,b as T,f as Dt,g as Ot,h as kt,i as At,j as jt,l as Mt,n as Nt,o as Pt,u as Ft,v as It,w as E}from"./runner-error-classification.js";import{A as Lt,D as Rt,F as zt,I as Bt,L as Vt,M as Ht,P as Ut,R as Wt,S as Gt,T as Kt,V as qt,_ as Jt,a as Yt,b as D,c as Xt,d as Zt,f as Qt,h as $t,i as O,j as en,m as tn,n as nn,o as rn,p as an,r as on,t as k,u as sn,v as cn,w as ln,y as un}from"./runner-disposal.js";import A from"node:fs";import dn from"node:path";const fn={runCmdStreaming:oe,runCmdSync:re,runCmdBackground:se,requireExecSuccess:ae,isCommandTimeoutError:ne,commandDeveloperDir:ie,shellQuote:ge,emitDiagnostic:l,withDiagnosticTimer:c,retryWithPolicy:pe,isEnvTruthy:he,deadlineFromTimeoutMs:(e,t)=>me.fromTimeoutMs(e,t),isProcessAlive:_,isProcessGroupAlive:h,readProcessStartTime:y,readProcessCommand:p,signalPidsBestEffort:m,signalProcessGroupBestEffort:te,findProjectRoot:de,readVersion:ue,acquireProcessLock:le,withProcessLock:ce,withKeyedLock:_e,publishFileSync:g,classifyOwnerLiveness:v,readHostCpuArchSync:ee,createTtlMemo:fe,parseBooleanLiteral:f,isRecord:s,emitRequestProgress:Se,getRequestSignal:xe,isRequestCanceled:be,classifyBootFailure:ve,bootFailureHint:ye,runAppleToolCommand:Ce,runXcrun:Te,readApplePlistJson:Ee,hasScopedAppleToolProvider:we,buildSimctlArgsForDevice:et,simulatorAddressFor:$e,resolveIosPhysicalDeviceControl:De,visitXmlPlistEntries:Xe,leaseOwnerStateDir:Ze,hasDeviceClaimAuthority:e=>Qe()?.(e)??!1};function pn(e=process.env){return Ae(e.AGENT_DEVICE_IOS_RUNNER_DETACH??``)!==!1}async function mn(e,t){if(!pn())return 0;let n=0;for(let[r,i]of e){let e=hn(i);if(!e.detached){b({level:`debug`,phase:`ios_runner_session_detach_skipped`,data:{deviceId:r,sessionId:i.sessionId,lane:e.lane,reason:e.reason,outstandingCharges:i.commandCharges.outstandingChargeCount,hasAbandonedCharges:i.commandCharges.hasAbandonedCharges}});continue}n+=1,t(r,i),b({level:`info`,phase:`ios_runner_session_detached`,data:{deviceId:r,lane:e.lane,sessionId:i.sessionId,runnerPid:i.child.pid,port:i.port,runnerLogPath:i.runnerLogPath}})}return n}function hn(e){let t=He(e.device);if(!t.handoff)return{detached:!1,lane:void 0,reason:t.reason};let n=t.lane,r=gt(e);if(!r.detach)return{detached:!1,lane:n,reason:r.reason};let i=e.lease;if(!i)return{detached:!1,lane:n,reason:`lease_absent`};if(!Yt(e.child.pid))return{detached:!1,lane:n,reason:`runner_process_dead`};try{D(sn(i))}catch{return{detached:!1,lane:n,reason:`lease_write_failed`}}return e.endOutputObservation?.(),ft(e,`stopped`),{detached:!0,lane:n}}async function gn(e,t){if(!pn())return null;let n=He(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=$t(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!==ut(e))return r(`simulator_set_mismatch`,a);let o=_n(a,t.expectedRunnerSessionId);if(`refusal`in o)return r(o.refusal,a);let s=vn(e,a,t.budget);if(`refusal`in s)return r(s.refusal,a);let c=o.value,l=s.value,u=await yn(e,a.port,n.lane,t.budget);if(u!==`answered`)return r(u,a);if(!an(a,c))return r(`runner_pid_recycled`,a);let d=Sn(e,a,c,l);try{D(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 _n(e,t){if(t!==void 0&&e.sessionId!==t)return{refusal:`session_identity_mismatch`};let n=e.runnerPid;return n?Be(n)?cn(e,n)?{value:n}:{refusal:`runner_pid_recycled`}:{refusal:`runner_process_dead`}:{refusal:`runner_pid_missing`}}function vn(e,t,n){let r=xn(e,n);return r?t.cacheKey!==r.cacheKey||!t.xctestrunPath.startsWith(`${r.derived}${dn.sep}`)?{refusal:`artifact_fingerprint_mismatch`}:{value:r}:{refusal:`expected_derived_unresolved`}}async function yn(e,t,n,i){let a=n===`physical_coredevice`?5e3:500,o=bn(i,a);if(o<=0)return`probe_budget_exhausted`;let s=Date.now(),c=!1;try{let n=await lt(e,t,C({command:`uptime`}),o,i?.signal);return c=xt(wt(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 bn(e,t){return e?.deadline?Math.min(t,Math.floor(e.deadline.remainingMs())):t}function xn(e,t){try{let n=qe(e,void 0,t);return{derived:Ge(e,n),cacheKey:Je(n)}}catch(e){if(r(e))throw e;return null}}function Sn(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}=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 _t,lease:Zt({device:e,sessionId:i,runnerPid:n,port:t.port,xctestrunPath:t.xctestrunPath,cacheKey:r.cacheKey,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(()=>{Be(e)||(clearInterval(r),t.exitCode=-1,n({stdout:``,stderr:``,exitCode:-1}))},1e3);r.unref?.()})}}function wn(){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 Tn(e){let t=e.logPath;A.mkdirSync(dn.dirname(t),{recursive:!0});let n=A.openSync(t,`a`),r=bt(t,n),i=En(()=>{try{A.closeSync(n)}catch{}}),a=wn();try{let t=Ne(`xcodebuild`,[`test-without-building`,`-only-testing`,`AgentDeviceRunnerUITests/RunnerTests/testCommand`,`-parallel-testing-enabled`,`NO`,`-test-timeouts-enabled`,`NO`,`-collect-test-diagnostics`,`never`,We(e.device),`1`,`-destination-timeout`,`20`,`-xctestrun`,e.xctestrunPath,`-derivedDataPath`,e.derivedPath,...it(e.device,Ve(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=rt({file:r,onOutput:t=>{a.observe(t),(e.traceLogPath||e.verbose)&&nt(t,void 0,e.traceLogPath,e.verbose)}}),s=En(()=>{o.stop(),i()}),c=()=>{o.drain(),i(),a.finish()};return t.wait.then(c,c),{...t,startupRetryWake:a.wake,endOutputObservation:s,readLogTail:e=>tt(r,e)}}catch(e){throw i(),e}}function En(e){let t=!1;return()=>{t||(t=!0,e())}}const j=new Map,Dn=new Map,M=new Map,On=1e4;function N(e,t){return Pe(Dn,e,t)}async function P(e,t){R(e.id);let n=t.startAdmission,r=n??Lt(e.id),i=N(e.id,async()=>{let{openRunnerStartBudget:n,reserveRunnerStartOwnerInterest:i}=await import(`./runner-start-budget.js`);Ht(r),Gt(e.id,r);let a=n(t),o=i(r,t);try{let n=j.get(e.id);if(n){Mn(n,t.expectedRunnerSessionId);let r=await In(e,n,a.phase);if(r)return r}return await un(e.id,async()=>await An(e,t,a,r))}catch(e){throw a.exhausted.aborted?a.exhausted.reason:e}finally{a.close(),o()}}),{raceRunnerStartAgainstCaller:a}=await import(`./runner-start-budget.js`);return await a(n?i:i.finally(()=>Rt(r)),r,t.signal)}const kn=1e4;async function An(e,t,r,i){let a={},o=r.phase,s=o.signal,c=nr(t.runnerLeaseContext,e.id);b({level:`debug`,phase:`ios_runner_session_startup`,data:{deviceId:e.id,logicalLeaseContext:c}});let l=await V(a,`adopt_detached_runner`,async()=>await gn(e,{budget:o,expectedRunnerSessionId:t.expectedRunnerSessionId}));if(l)return l.startupTimings=a,l.logicalLeaseContext=c,Gt(e.id,i),j.set(e.id,l),l;Nn(t.expectedRunnerSessionId),await V(a,`cleanup_stale_xcodebuild`,async()=>{await tn(e,rn,c)}),await V(a,`ensure_booted`,async()=>{await Xn(e)});let u=await V(a,`verify_device_readiness`,async()=>await(await import(`./runner-device-readiness.js`)).preflightIosRunnerDeviceReadiness(e,{budgetMs:Math.min(kn,o.deadline?.remainingMs()??kn),signal:s}));await V(a,`verify_host_dev_tools_security`,async()=>{let{assertDevToolsSecurityForIosRunner:t}=await import(`./runner-dev-tools-security.js`);await t(e)}),t.cleanStaleBundles?await V(a,`cleanup_stale_bundles`,async()=>{await Ln(e)}):(a.cleanup_stale_bundles=0,b({level:`debug`,phase:`ios_runner_startup_cleanup_stale_bundles_skipped`}));let d,f,p,m,h=vt(t.logPath,e.id),g;try{d=await V(a,`ensure_xctestrun`,async()=>await ln(e,{...t,startAdmission:i,budget:Ke($n(t,r),s)})),a.build_xctestrun=d.buildMs,f=await V(a,`allocate_port`,async()=>await yt()),{xctestrunPath:p,jsonPath:m}=await V(a,`prepare_xctestrun_env`,async()=>await Wt(d.xctestrunPath,{AGENT_DEVICE_RUNNER_PORT:String(f)},Vt({deviceId:e.id,ownerToken:Jt(),port:f}),{iosXctestEnvDir:t.iosXctestEnvDir})),d.buildMs>0&&Ie({type:`command`,status:`progress`,message:`Starting XCTest runner...`}),g=await V(a,`launch_xcodebuild`,async()=>(await ot(h).catch(()=>{}),await Tn({device:e,port:f,xctestrunPath:p,derivedPath:d.derived,signal:s,logPath:h,traceLogPath:t.traceLogPath,verbose:t.verbose})))}catch(e){throw At(e,u)}let _=ht(e.id,f),v=Zt({device:e,sessionId:_,runnerPid:g.child.pid,port:f,xctestrunPath:p,cacheKey:d.cacheKey,jsonPath:m,runnerLogPath:h}),y={sessionId:_,device:e,deviceId:e.id,port:f,xctestrunPath:p,xctestrunArtifact:d,jsonPath:m,runnerLogPath:h,testPromise:g.wait,child:g.child,endOutputObservation:g.endOutputObservation,readLogTail:g.readLogTail,state:`starting`,commandCharges:new _t,startupRetryWake:g.startupRetryWake,launchDeadline:ze.fromTimeoutMs(er(r)),startupTimings:a,startupDeviceStates:u,logicalLeaseContext:c,lease:v,speculative:t.speculative===!0};if(s?.aborted)throw await O(y,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),n();await jn(e,y,i);try{D(v)}catch(t){throw await L(e.id,y,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),t}return j.set(e.id,y),y}async function jn(e,t,n){if(!zt(e.id,n))throw await O(t,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),Bt(n.retired??`device_teardown`)}function Mn(e,t){if(t!==void 0&&e.sessionId!==t)throw Pn()}function Nn(e){if(e!==void 0)throw Pn()}function Pn(){return new i(`COMMAND_FAILED`,`Apple runner session ownership changed before command dispatch`,{reason:`runner_session_ownership_changed`})}async function Fn(e,t){let n=Bn(t);return n===`gone`?(await V({},`stop_stale_session`,async()=>{await L(e.id,t,{graceful:!1,waitTimeoutMs:k})}),!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:k})}),!1):mt(t.device,e)?!0:(await V({},`stop_other_simulator_set_session`,async()=>{await L(e.id,t)}),!1)}async function In(e,t,n){if(!await Fn(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=qe(e,void 0,n),a=Ge(e,i),o=Je(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 Ln(e){e.kind===`simulator`&&await Promise.allSettled(Ye.map(async t=>{let n=await Rn(e,t);!n||zn(n)}))}async function Rn(e,t){try{return await je(Fe(e,[`uninstall`,e.id,t]),{allowFailure:!0,timeoutMs:On})}catch(n){b({level:`warn`,phase:`ios_runner_startup_cleanup_stale_bundle_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:On,error:n instanceof Error?n.message:String(n)}});return}}function zn(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:Bn(t)}:null}function Bn(e){return st({state:e.state,processRunning:Yt(e.child.pid)})}async function I(e,t){await N(e.deviceId,async()=>{j.get(e.deviceId)===e&&dt(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:k}))})}async function L(e,t,n={}){let r=t??j.get(e);r&&dt(r)&&(await O(r,n),j.get(e)===r&&j.delete(e))}function Vn(e){R(e);let t=Hn();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 Hn(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 Un(e,t){e.speculative&&!Tt(t)&&(e.speculative=!1)}async function Wn(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){await Gn(e)}async function Gn(e,t){R(e);try{await N(e,async()=>{await un(e,async()=>{await L(e,void 0,{leaseLockHeld:!0}),await on(e)}),t?.()})}finally{t?.()}}async function Kn(e,t){let n=j.get(e);if(t.retain&&!at(n)){Vn(e);return}t.retain&&b({level:`info`,phase:`ios_runner_retain_skipped_busy`,data:{deviceId:e}});let r=Kt(e);try{await Xt(e),await Gn(e,r)}finally{r()}}async function qn(){let e=Array.from(j.values()),t=Ut(e.map(e=>e.deviceId));try{await nn(e);for(let t of e)j.get(t.deviceId)===t&&j.delete(t.deviceId)}finally{t()}}async function Jn(){return await mn(j,e=>{j.delete(e),R(e)})}async function Yn(){let e=Ut(j.keys());try{await qn();let e=Array.from(j.keys());await Promise.allSettled(e.map(async e=>{await z(e)})),await Xt()}finally{e()}}function Xn(e){return e.kind===`simulator`?e.booted?(b({level:`debug`,phase:`ios_runner_startup_ensure_booted_skipped`,data:{deviceId:e.id}}),Promise.resolve()):Zn(e):Promise.resolve()}async function Zn(e){await je(Fe(e,[`bootstatus`,e.id,`-b`]),{timeoutMs:x})}function Qn(e){if(!u(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){tr(t,n.command);let{executeRunnerExchange:o}=await import(`./runner-exchange.js`);return o(e,t,n,r,i,e=>I(t,e),a)}function $n(e,t){let n=Ue(t.phase,`runner_xctestrun_build`)??t.timeoutMs,r=pt(e.buildTimeoutMs);return r===void 0?n:Math.min(r,n)}function er(e){let t=Math.floor(e.phase.deadline?.remainingMs()??e.timeoutMs);return e.explicit?t:Math.min(x,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 tr(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 nr(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 rr(e){let{device:t,session:n,command:r,transportError:i,options:a,signal:o,invalidationReason:s}=e;return await ir(await ur(t,n,r,i,a,o),{command:r,session:n,transportError:i,options:a,invalidationReason:s,invalidateSession:e.invalidateSession})}async function ir(e,t){if(e.type===`recovered`)return sr(e,t);let n=ar(e,t);if(e.type===`skipInvalidation`)throw cr(e,t,n);return await lr(e,t,n)}function ar(e,t){return`runnerAnswer`in e?o(e.runnerAnswer,e.dispatched):T(t.command)?o(t.transportError,`unknown`):o(or(t,e.lostReply),`unknown`)}function or(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?wr(n.command,t.cause):t.message,{command:n.command,commandId:n.commandId,...t.lifecycleState===void 0?{}:{lifecycleState:t.lifecycleState},reason:Nt,...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 sr(e,t){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.data}function cr(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 lr(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 ur(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=pr(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}}}),mr(s,c,n,r,i)}const dr=new Set([`completed`,`failed`]),fr=new Set([`accepted`,`started`]);function pr(e,t,n){if(dr.has(n))return e.commandCharges.settleTerminalEvidence(t.commandId)}function mr(e,t,n,r,i){if(t===`completed`)return hr(e,n,r);if(t===`failed`){let a=St(typeof e.lifecycleErrorCode==`string`?e.lifecycleErrorCode:void 0);return{type:`skipInvalidation`,reason:`runner_reported_failure`,lifecycleState:t,dispatched:a.details.dispatched,runnerAnswer:gr(e,a,n,r,i)}}return fr.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:br(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 hr(e,t,n){let r=_r(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:vr(t.command,W(n))}}}function gr(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??yr(n.command,c),logPath:a.logPath,transportError:r.message},r)}function _r(e){if(typeof e!=`string`||e.trim().length===0)return;let t;try{t=wt(e)}catch{return}return xt(t)?jt(t):void 0}function vr(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 yr(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 br(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 xr(e,t){let n=e.details?.[t];return typeof n==`boolean`?n:void 0}function Sr(e,t){let n=e.details?.[t];return typeof n==`string`?n:void 0}function Cr(e,t){let n=e.details?.[t];return typeof n==`number`?n:void 0}function W(e){let t={},n=xr(e,`runnerReadinessPreflightSkipped`);n!==void 0&&(t.readinessPreflightSkipped=n);let r=Sr(e,`runnerReadinessPreflightSkipReason`);r!==void 0&&(t.readinessPreflightSkipReason=r);let i=Cr(e,`runnerReadinessPreflightSkippedAgeMs`);return i!==void 0&&(t.readinessPreflightSkippedAgeMs=i),t}function wr(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 Tr(e,t){let n=e.requestId?.trim();if(n)return`request:${n}`;let r=t.commandId?.trim();if(r)return`command:${r}`}function Er(e){if(!e)return;let t=Y(e);t.touchedSession=!0,X(e,t)}function Dr(e){return e?q.get(e)?.touchedSession===!0:!1}function Or(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 kr(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 Ar(),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 Ar(){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 jr(e,t){E(t.requestId);let n=S(t),r=C({command:`uptime`}),a=en(e.id),o;try{for(let i=1;i<=2;i+=1){let s=await Mr({device:e,command:r,options:{...t,startAdmission:a},signal:n,attempt:i,recoveryReason:o});if(s.kind===`prepared`)return s.result;o=s.recoveryReason}}finally{Rt(a)}throw new i(`COMMAND_FAILED`,`iOS runner prepare failed`)}async function Mr(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,...Vr(r,`runner_session`)}),l=Date.now()-s;try{return{kind:`prepared`,result:Kr(t,await Br(t,c,n,r,i,l,{recoveryReason:o}))}}catch(e){return await Nr({device:t,session:c,command:n,options:r,signal:i,attempt:a,error:e})}}async function Nr(e){let{device:n,session:i,command:a,options:o,signal:s,attempt:c,error:l}=e,u=t(l,`COMMAND_FAILED`);if(r(u))throw await Z(i,`prepare_runner_request_canceled`),l;if(c===1&&Ur(u,i))return{kind:`prepared`,result:await Pr({device:n,session:i,command:a,options:o,signal:s,error:u})};if(!Fr(u))throw l;let d=u.message||`runner_health_failed`;if(c>=2)throw await Z(i,`prepare_runner_health_failed`),l;return E(o.requestId),await I(i,`prepare_runner_health_retry`),b({level:`warn`,phase:`ios_runner_prepare_health_retry`,data:{command:a.command,commandId:a.commandId,sessionId:i.sessionId,attempt:c,maxAttempts:2,reason:d}}),{kind:`retry`,recoveryReason:d}}async function Pr(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 qt(n.xctestrunArtifact,s);let c=Date.now(),l=await P(t,{...i,cleanStaleBundles:!0,forceRunnerXctestrunRebuild:!0,...Vr(i,`runner_rebuild`)}),u=Date.now()-c;try{let e=await Br(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}}),Kr(t,e)}catch(e){await Z(l,`prepare_rebuilt_runner_health_failed`);let n=Wr(e,l,s);throw qr(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 Fr(e){return r(e)?!1:w(e)||It(e)}async function Ir(e,n,r){let i={entered:!1};try{return await Lr(e,n,r,i)}catch(e){let n=t(e);throw i.entered?Mt(n)?a(n,`no`):n:o(n,`no`)}}async function Lr(e,i,a,o){E(a.requestId);let s=S(a),c=Tr(a,i),l,u=!1,d=F(e.id)?.liveness??`gone`;try{if((d===`gone`||d===`stopped`)&&Dr(c)){if(!Or(c))throw kr(i,a);u=!0}l=await P(e,a),Mn(l,a.expectedRunnerSessionId),Un(l,i),u&&J(c),Er(c);let t=ct;if(l.state!==`ready`){let{readRunnerStartupTimeoutMs:e}=await import(`./runner-exchange.js`);t=e(l)}return o.entered=!0,await B(e,l,i,a.logPath,t,s)}catch(o){if(a.expectedRunnerSessionId!==void 0)throw o;let c=t(o,`COMMAND_FAILED`);if((l?l.state===`starting`:d!==`ready`)&&r(c))throw l&&!Ct(a)&&await Z(l,`runner_startup_request_canceled`),n({...c.details,readinessPhase:`runner-start`},c);if(Et(c,i)&&l)return E(a.requestId),await Rr({device:e,session:l,command:i,options:a,signal:s,restartReason:`runner_connect_failed_before_command_send`,firstAttemptDispatched:Dt(c)});if(l&&Ot(c))return E(a.requestId),await Rr({device:e,session:l,command:i,options:a,signal:s,restartReason:`runner_readiness_preflight_failed_before_command_send`,recoveredDiagnosticPhase:`ios_runner_readiness_preflight_recovered`,firstAttemptDispatched:`no`});if(l&&w(c)&&!Ft(c))return await rr({device:e,session:l,command:i,transportError:c,options:a,signal:s,invalidationReason:`transport_error_after_command_send`,invalidateSession:I});throw o}}async function Rr(e){let{device:n,command:r,options:i,signal:a,restartReason:s}=e,c=Tr(i,r);if(!Or(c))throw o(kr(r,i),e.firstAttemptDispatched);await I(e.session,s);let l=await P(n,{...i,cleanStaleBundles:!0}).catch(t=>{throw Q(t,e)});J(c);try{let t=await B(n,l,r,i.logPath,x,a);return e.recoveredDiagnosticPhase&&b({level:`debug`,phase:e.recoveredDiagnosticPhase,data:{command:r.command,commandId:r.commandId,recovery:`session_restarted`,sessionId:l.sessionId}}),t}catch(o){let s=t(o,`COMMAND_FAILED`);if(w(s)&&!Ft(s))try{return await rr({device:n,session:l,command:r,transportError:s,options:i,signal:a,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?zr(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 zr(e,t,n){return!n||t===`unknown`?o(e,t):a(e,Mt(e)?`no`:`unknown`)}async function Br(e,t,n,r,i,a,o){let s=Date.now(),c=Hr(r.prepareDeadline,r.healthTimeoutMs,`runner_health`);return Gr(await B(e,t,n,r.logPath,c,i),t,a,Date.now()-s,o)}function Vr(e,t){if(!e.prepareDeadline)return{};let n=Hr(e.prepareDeadline,e.buildTimeoutMs,t);return{buildTimeoutMs:n,startupTimeoutMs:n}}function Hr(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 Ur(e,t){let n=t.xctestrunArtifact;return!n||n.cache===`miss`?!1:kt(e)}function Wr(e,n,r){let a=t(e,`COMMAND_FAILED`);return new i(a.code,`artifact restored but runner did not connect`,{...a.details??{},restoredFailureReason:r,xctestrunPath:n.xctestrunArtifact?.xctestrunPath,artifact:n.xctestrunArtifact?.artifact,cache:n.xctestrunArtifact?.cache,reason:a.message},a)}function Gr(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 Kr(e,t){return qr(e,t),t}function qr(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 Jr={maxAttempts:8,baseDelayMs:200,maxDelayMs:1e3,jitter:0};function Yr(e){return Pt(e)?8:w(e)?3:1}async function Xr(e,t,n={}){Qn(e),E(n.requestId);let r=C(t),i=$(e,n);if(!T(r))return i.runCommand(e,r,n);let a;try{return await Me(()=>(E(n.requestId),i.runCommand(e,r,n)),{...Jr,shouldRetry:(e,t)=>(E(n.requestId),Pt(e)&&(a=e),t<Yr(e))},{signal:S(n)})}catch(e){throw a&&Ct(n)?a:e}}async function Zr(e,t={}){if(d(e))try{await Xr(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 Qr(e,t={}){if(d(e)){if(Le()){b({level:`debug`,phase:`ios_runner_cache_prewarm_unavailable`,data:{deviceId:e.id}});return}return ei({device:e,options:t,failurePhase:`ios_runner_cache_prewarm_failed`,task:async t=>{await ln(e,{...t,budget:Ke(t.buildTimeoutMs,t.signal)})}})}}function $r(e,t={}){if(!d(e))return;let n=$(e,t).prewarm;if(!n){b({level:`debug`,phase:`ios_runner_session_prewarm_unavailable`,data:{deviceId:e.id}});return}return ei({device:e,options:t,failurePhase:`ios_runner_session_prewarm_failed`,task:async t=>{await n(e,t)}})}function ei(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 ti(e,t){Qn(e),E(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,ii,{requestId:t.requestId})}function ni(e,t={}){return d(e)?$(e,t).hasLiveSession(e):!1}async function ri(e,t={}){if(!d(e))return!1;let n=$(e,t).releaseSpeculativeSession;return n?await n(e):!1}const ii=Oe(Ir,{prepare:jr,hasLiveSession:e=>F(e.id)?.liveness===`ready`,releaseSpeculativeSession:async e=>await Wn(e.id),prewarm:async(e,t)=>{let{healthCheck:n,...r}=t;if(n===!1){await P(e,{...r,speculative:!0});return}await jr(e,{...r,speculative:!0,healthTimeoutMs:ct})}});var ai=e({cleanupRunnerLeasesForOwner:()=>Qt,readRunnerSessionLiveness:()=>F});Re(fn);export{Qr as a,Xr as c,Kn as d,Yn as f,ti as i,Jn as l,ni as n,$r as o,z as p,Zr as r,ri as s,ai as t,F as u};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{F as t,K as n,P as r}from"./sdk-contracts.js";import{m as i}from"./sdk-device.js";import{t as a}from"./parser.js";import{A as o,B as s,D as c,F as l,G as u,H as d,L as f,N as p,O as m,R as ee,S as te,T as h,W as ne,_ as re,a as ie,b as g,d as ae,f as _,g as oe,m as se,n as ce,p as le,s as ue,u as v,v as y,w as de,y as fe,z as pe}from"./host.js";import{d as me,r as he}from"./apple-runner-platform.js";import{_ as ge,a as _e,b as ve,c as ye,d as be,f as xe,g as Se,h as Ce,l as we,m as Te,n as Ee,p as De,r as Oe,t as ke,v as Ae,x as je,y as Me}from"./runner-cache-metadata.js";import{S as Ne,_ as Pe,g as Fe,h as Ie,m as Le,n as b,u as Re,v as x}from"./runner-session-types.js";import{P as ze,r as Be}from"./runner-error-classification.js";import Ve from"node:crypto";import S from"node:fs";import He from"node:os";import C from"node:path";const w=new Set;function Ue(e){return C.join(e,Ee)}function We(e,t){S.mkdirSync(e,{recursive:!0}),S.writeFileSync(Ue(e),`${JSON.stringify(t,null,2)}\n`)}async function Ge(e,t){if(e.cache===`external`){k(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}w.add(e.derived),await u({acquire:()=>Ke(e.derived),task:async()=>{k(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),O(e.derived),D(e.derived)}})}async function Ke(e){return await ce({lockDirPath:qe(e),owner:{pid:process.pid,startTime:m(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,description:`iOS runner cache lock`})}function qe(e){return C.join(C.dirname(e),`${C.basename(e)}.lock`)}function Je(e,t){!$e()&&!t&&!w.has(e)||(k(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),O(e),D(e),w.delete(e))}async function T(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return We(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(k(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function E(e,t){if(e)throw new r(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:e.reason,refusingPath:e.path??t,...e.reason===`root_unusable`?{}:{resolvesTo:e.target},derived:t,hint:`Inspect ${e.path??t} under ${t}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function D(e){try{if(!S.existsSync(e))return;if(C.basename(e)!==`derived`){S.rmSync(e,{recursive:!0,force:!0});return}for(let t of S.readdirSync(e,{withFileTypes:!0}))Xe(t.name)&&S.rmSync(C.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Ye=new Set([Ee,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Xe(e){return Ye.has(e)}function Ze(e){try{let t=JSON.parse(S.readFileSync(Ue(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function Qe(e,t){let n=Ze(e);return n?ve(Oe(n))===ve(Oe(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:_e(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function $e(){return re(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function O(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!et(e))throw new r(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:e,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${C.join(_(),`.tmp`)}.`})}function et(e){let t=C.resolve(_(),`.tmp`),n=C.relative(t,C.resolve(e));return n!==``&&!n.startsWith(`..`)&&!C.isAbsolute(n)}async function tt(e){let t=Qe(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function nt(e,t){k(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function k(e,t,n){v({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const rt=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),it=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function at(e,t,n){if(!i(e))return;if(t.length===0)throw new r(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:n});let a=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of a)if(!S.existsSync(e))throw new r(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:n});for(let e of a)await lt(e)||await ot(e,n)}async function ot(e,n){try{let t=C.join(e,`Contents`,`Frameworks`),n=S.existsSync(t)?S.readdirSync(t).sort().map(e=>C.join(t,e)):[];for(let e of n)await p(`codesign`,[...it,e]);await p(`codesign`,[...it,e])}catch(r){let i=t(r,`COMMAND_FAILED`);throw st(e,n,i.message,i.details)}if(!await lt(e))throw st(e,n,`Product still fails code signature verification after re-signing`)}function st(e,t,n,i){return new r(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:n,details:i})}function ct(e){if(!(e instanceof r))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&rt.has(t)}async function lt(e){return(await p(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const ut=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function dt(e){let t=await mt(e);if(!t||t.length===0)return null;let n=C.dirname(e),r=new Set,i=ft(t,n);for(let e of i.testRootPaths){if(!S.existsSync(e))return null;r.add(e)}for(let e of pt(i)){if(!e)return null;r.add(e)}return Array.from(r)}function ft(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(C.join(t,e));let o=xt(e);o&&r.add(C.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function pt(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>S.existsSync(C.join(e,t)));return n?C.join(n,t):null})}async function mt(e){let t=await h(e);if(t)return ht(t);if(process.platform===`darwin`)return null;try{return yt(S.readFileSync(e,`utf8`))}catch{return null}}function ht(e){let t=new Set;for(let n of[e,...gt(e),..._t(e)])for(let e of vt(n))t.add(e);return Array.from(t)}function gt(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!g(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(g))}return n}function _t(e){return Object.values(e).filter(e=>g(e)&&`TestBundlePath`in e)}function vt(e){let t=new Set;for(let[n,r]of Object.entries(e))if(ut.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function yt(e){return bt(a(e))}function bt(e){let t=new Set;return d(e,(e,n)=>{if(ut.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function xt(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const St=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function Ct(e){await wt(Lt(e))}async function wt(e){let t=e.filter(Ft);if(t.length===0)return;let n=e.filter(e=>A(e)&&!It(e));for(let e of t){let t=Pt(e,n);t&&await Tt(t,e)}}async function Tt(e,t){let n=Et(e,t),r=await Dt(e,t);(n||r)&&(await At(t),Nt(t))}function Et(e,t){let n=!1;for(let r of S.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!Mt(r.name)||jt(C.join(e,r.name),C.join(t,r.name))&&(n=!0);return n}async function Dt(e,t){let n=C.join(e,`Info.plist`),r=C.join(t,`Info.plist`),i=await h(n),a=await h(r);if(!i||!a)return!1;let o=Ot(i,a);if(o.length===0)return!1;for(let e of o)await kt(r,e.key,e.value,e.shouldInsert);return!0}function Ot(e,t){return St.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function kt(e,t,n,r){o(await p(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function At(e){o(await p(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function jt(e,t){if(S.existsSync(t)){let n=S.readFileSync(e),r=S.readFileSync(t);return!n.equals(r)&&(S.copyFileSync(e,t),!0)}return S.copyFileSync(e,t),!0}function Mt(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function Nt(e){let t=new Date;S.utimesSync(e,t,t)}function Pt(e,t){let n=C.dirname(e);return t.find(e=>C.dirname(e)===n&&C.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>C.dirname(t)===n&&t!==e)??null}function Ft(e){return A(e)&&It(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function It(e){return C.basename(e).endsWith(`-Runner.app`)}function A(e){return C.basename(e).endsWith(`.app`)}function Lt(e){if(!S.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of S.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=C.join(e,r.name);if(A(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const j=`AgentDeviceRunner.env`,Rt=`session`,zt=`${N(`${j}.${Rt}`)}-`;function Bt(e){return M(`${Rt}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function Vt(e){return`${zt}${N(M(e))}-[0-9]`}function Ht(e){let t=e?C.basename(e):``;if(t.startsWith(`${j}.`))return N(t)}function M(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function N(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Ut={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function Wt(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?C.resolve(i):C.dirname(e);S.mkdirSync(a,{recursive:!0});let o=M(n),s=C.join(a,`${j}.${o}.json`),c=C.join(a,`${j}.${o}.xctestrun`),l=await Gt(e);return Yt(l,e=>qt(e,t)),Jt(l),await Kt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function Gt(e){let t=await p(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0||!t.stdout.trim())throw new r(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(t){throw new r(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(t)})}}async function Kt(e,t,n){S.writeFileSync(t,JSON.stringify(e,null,2)),o(await p(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function qt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function Jt(e){Yt(e,e=>Object.assign(e,Ut),{requireTestBundlePath:!0})}function Yt(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||Xt(e.TestTargets,t,n);for(let n of Object.values(e)){let e=Zt(n,{requireTestBundlePath:!0});e&&t(e)}}function Xt(e,t,n){if(Array.isArray(e))for(let r of e){let e=Zt(r,n);e&&t(e)}}function Zt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const Qt=new Map,P=new Set;function $t(e,t,n){let r={deviceId:e,requestId:n,child:t};P.add(r),t.on(`close`,()=>{P.delete(r)})}function en(e){return nn(e).map(e=>e.child)}function tn(e){return nn(e).filter(e=>!rn(e.requestId)).map(e=>e.child)}function nn(e){return[...P].filter(t=>e===void 0||t.deviceId===e)}function rn(e){if(!e)return!1;let t=le(e);return t!==void 0&&!t.aborted}function an(e){for(let t of P)t.child===e&&P.delete(t)}async function on(e,t){let n=sn(t);if(n)return n;let r=_(),i=we(e,r,t.budget),a=Ce(e,i);return await ne(Qt,a,async()=>await u({acquire:()=>Ke(a),task:()=>ln({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function sn(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let n=C.resolve(t);if(!S.existsSync(n))throw new r(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:n});let i=e.iosXctestDerivedDataPath?.trim(),a=i?C.resolve(i):cn(n);return k(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:n}),{xctestrunPath:n,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function cn(e){let t=Ve.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return C.join(He.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function ln(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;Je(a,e.forceRebuild);let o=await tt({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await un({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&nt(o,a),o.reason!==`cache_metadata_missing`&&(O(a),D(a)),await dn({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function un(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await fn(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:Te(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function dn(e){let{device:t,options:n,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=je(i);if(!S.existsSync(l))throw new r(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=ye(n.budget,`runner_xctestrun_build`),d=Date.now();ae({type:`command`,status:`progress`,message:`Building Apple runner...`}),await vn(t,l,o,n,u);let f=Math.max(0,Date.now()-d),p=mn(o,t);if(!p)throw new r(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await dt(p);if(!m)throw new r(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await at(t,m,p),await wt(m),E(await T(o,a,p,m),o),k(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,cacheKey:Te(a),artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function fn(e,t,n,r){try{return await at(e,r.productPaths,r.xctestrunPath),E(await T(t,n,r.xctestrunPath,r.productPaths),t),k(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!ct(e))throw e;return k(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function pn(e){try{let t=_(),n=we(e,t);return(await tt({derived:Ce(e,n),expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function mn(e,t){let n=hn(e);return n.length===0?null:(n.sort((e,n)=>gn(e,n,t)),n[0]?.path??null)}function hn(e){if(!S.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=S.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=C.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=S.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function gn(e,t,n){if(n){let r=_n(t.path,n)-_n(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function _n(e,t){let n=0,r=e.toLowerCase();C.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${C.sep}macos${C.sep}`)&&(n-=5e3);let i=me(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}async function vn(e,t,i,a,o){let s=De(process.env),c=Me(process.env,e.kind===`device`,e),u=e.kind===`device`?[`-allowProvisioningUpdates`]:[],d=ge(),f=be(process.env),p=Ae();try{await l(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,Se(e),`1`,...Pe(e,he(e)),`-derivedDataPath`,i,...xe(i),...d,...f,...p,...s,...u,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:t=>{$t(e.id,t,a.requestId)},onStdoutChunk:e=>{Ne(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{Ne(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(t){if(n(t))throw t;let i=t instanceof r?t:new r(`COMMAND_FAILED`,String(t)),o=Le(e),{reason:s,hint:c,matched:l}=Be(new r(i.code,i.message,{...i.details,...o})),u=oe(i),d=`xcodebuild build-for-testing failed`;throw new r(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?Fe(d,e,o):d,{reason:s,error:i.message,details:i.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}const F=process.pid;let yn;function I(){return yn??={value:m(process.pid)},yn.value}function L(){return Zn(F,I())}function bn(e){let t=H(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:L(),ownerPid:F,ownerStartTime:I(),ownerStateDir:Dn(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?m(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...Kn(Ie(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function xn(e,t){return await u({acquire:()=>ce({lockDirPath:`${B(e)}.lock`,owner:{pid:F,startTime:I(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function R(e){try{return Wn(JSON.parse(S.readFileSync(B(e),`utf8`)),e)}catch{return null}}function z(e){if(!e)return{type:`empty`};if(e.ownerToken===L())return{type:`owned`,lease:e};let t=ue({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function Sn(e,t,n){let i=e.id,a=z(R(i));if(a.type===`empty`){await t.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(Cn(a.lease)){await G(a.lease,`same-state-dir`,t);return}if(wn(a.lease,e)){await G(a.lease,`device-claim-takeover`,t);return}if(Tn(a.lease,n)){await G(a.lease,`logical-lease-takeover`,t);return}throw new r(`COMMAND_FAILED`,n?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:n,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:On(a.lease,n)})}await G(a.lease,a.type,t)}function Cn(e){let t=Dn();return!t||!e.ownerStateDir?!1:C.resolve(t)===C.resolve(e.ownerStateDir)}function wn(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&se(t)}function Tn(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:En(t.deviceKey,e.deviceId)}function En(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function Dn(){return te()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function On(e,t){let n=kn(e),r=An(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function kn(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function An(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${jn(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function jn(e,t){return`${e}=${ee(t)}`}function Mn(e){let t=z(R(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Nn(e){let t=Mn(e);return t.type===`adoptable`?t.lease:null}function Pn(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Fn(e,t){let n=z(R(e));n.type===`owned`&&await G(n.lease,`owned`,t)}async function In(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Hn(e);await Promise.all(n.map(async e=>{await G(e,`owned`,t)}))}function Ln(e){return R(e)?.ownerToken??null}function Rn(e){e&&Bn({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function zn(e){let t=B(e.deviceId);S.mkdirSync(C.dirname(t),{recursive:!0}),de({destination:t,contents:JSON.stringify(e,null,2)})}function Bn(e){let t=R(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{S.unlinkSync(B(e.deviceId))}catch{}}function B(e){return C.join(Vn(),`${Qn(e)}.json`)}function Vn(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?C.resolve(e):C.join(He.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Hn(e){let t,n=Vn();try{t=S.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=Un(C.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function Un(e){try{let t=JSON.parse(S.readFileSync(e,`utf8`)),n=V(t.deviceId);return n?Wn(t,n):null}catch{return null}}function Wn(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=Gn(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:U(n.ownerStartTime),ownerStateDir:U(n.ownerStateDir)??void 0,runnerPid:W(n.runnerPid),runnerStartTime:U(n.runnerStartTime),runnerLogPath:H(n.runnerLogPath),cacheKey:H(n.cacheKey),...Kn(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Gn(e){let t={ownerToken:V(e.ownerToken),ownerPid:W(e.ownerPid),sessionId:V(e.sessionId),port:W(e.port),xctestrunPath:V(e.xctestrunPath),jsonPath:V(e.jsonPath),createdAtMs:qn(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function V(e){return typeof e==`string`&&e.length>0?e:null}function H(e){return V(e)??void 0}function Kn(e){let t=V(e);return t?{simulatorSetPath:t}:{}}function U(e){return typeof e==`string`?e:null}function W(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function qn(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function G(e,t,n){v({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(Yn(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(Yn(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),Rn(e)}function Jn(e,t){return y(t)&&K(e,t)}function Yn(e){let t=e.runnerPid??void 0;if(!(!t||!y(t))){if(K(e,t))return t;v({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function K(e,t){return e.runnerStartTime?m(t)===e.runnerStartTime:Xn(c(t))}function Xn(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function Zn(e,t){let n=Ve.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function Qn(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var $n=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>er,abortRunnerSessionsAndPrepProcesses:()=>ir,cleanupOwnedIosRunnerLease:()=>rr,disposeRunnerSession:()=>nr,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>q,stopRunnerPrepProcesses:()=>ar,stopRunnerPrepProcessesWithoutActiveOwner:()=>or});const er=1e3,tr=2e3,q={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:hr,cleanupTempFile:x};async function nr(e,t={}){b(e,`draining`);let n=!1;if(t.graceful!==!1)n=await cr(e);else if(i(e.device)){await J([e]),await Y(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await lr(e,t.waitTimeoutMs??1e4),mr(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Y(e,t)}async function rr(e){await Fn(e,q)}async function ir(e){let t=en(),n=e.filter(e=>i(e.device)),r=e.filter(e=>!i(e.device));for(let t of e)b(t,`draining`);await Z(r,`SIGINT`),await Q(t,`SIGINT`),await Z(r,`SIGTERM`),await Q(t,`SIGTERM`),await Z(r,`SIGKILL`),await Q(t,`SIGKILL`),await J(n),await Promise.allSettled(e.map(async e=>{await Y(e)}))}async function ar(e){await sr(en(e))}async function or(e){await sr(tn(e))}async function sr(e){await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{an(e)}}))}async function cr(e){try{return await Re(e.device,e.port,ze({command:`shutdown`}),void 0,15e3),!1}catch{return i(e.device)?(await J([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function lr(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!mr(e.child.pid)}finally{n&&clearTimeout(n)}}async function J(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await ur(e,5e3);await Z(t,`SIGTERM`),await Z(await ur(t,2e3),`SIGKILL`)}async function ur(e,t){let n=await Promise.all(e.map(async e=>await lr(e,t)));return e.filter((e,t)=>!n[t])}async function Y(e,t={}){await dr(e,t),x(e.xctestrunPath),x(e.jsonPath),b(e,`stopped`)}async function dr(e,t){let n=async()=>{if(!fr(e))try{await pr(e.device)}finally{Rn(e.lease)}};if(t.leaseLockHeld){await n();return}try{await xn(e.deviceId,n)}catch(t){v({level:`warn`,phase:`ios_runner_disposal_lease_lock_unavailable`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:t instanceof Error?t.message:String(t)}})}}function fr(e){let t=Ln(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function pr(e){e.kind===`simulator`&&await Promise.allSettled(ke.map(async t=>{try{await f(ie(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:tr})}catch(n){v({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:tr,error:n instanceof Error?n.message:String(n)}})}}))}function mr(e){return e?X(e)||fe(e):!1}function X(e){return e?y(e):!1}async function Z(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&an(e)}))}async function $(e,t){if(!e||e<=0)return;s(e,t),pe([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await p(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function hr(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${Ht(e.xctestrunPath)??Vt(t)}`;for(let e of[`TERM`,`KILL`])try{await p(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){v({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{T as A,pn as C,dt as D,Ct as E,Ge as O,mn as S,Wt as T,L as _,X as a,zn as b,ar as c,bn as d,In as f,Nn as g,Mn as h,nr as i,E as k,or as l,Sn as m,ir as n,q as o,Jn as p,rr as r,$n as s,er as t,Pn as u,K as v,Bt as w,on as x,xn as y};
1
+ import{r as e}from"./rolldown-runtime.js";import{F as t,I as n,K as r,P as i}from"./sdk-contracts.js";import{m as a}from"./sdk-device.js";import{t as o}from"./parser.js";import{A as s,B as c,D as l,F as u,G as d,H as f,L as p,N as m,O as h,R as ee,S as te,T as g,W as ne,_ as re,a as ie,b as _,d as ae,f as v,g as oe,m as se,n as ce,s as le,u as y,v as b,w as ue,y as de,z as fe}from"./host.js";import{d as pe,r as me}from"./apple-runner-platform.js";import{_ as he,a as ge,b as _e,c as ve,d as ye,f as be,g as xe,h as Se,l as Ce,m as we,n as Te,p as Ee,r as De,t as Oe,v as ke,x as Ae,y as je}from"./runner-cache-metadata.js";import{S as Me,_ as Ne,g as Pe,h as Fe,m as Ie,n as x,u as Le,v as S}from"./runner-session-types.js";import{P as Re,r as ze}from"./runner-error-classification.js";import Be from"node:crypto";import C from"node:fs";import Ve from"node:os";import w from"node:path";const T=new Set;function He(e){return w.join(e,Te)}function Ue(e,t){C.mkdirSync(e,{recursive:!0}),C.writeFileSync(He(e),`${JSON.stringify(t,null,2)}\n`)}async function We(e,t){if(e.cache===`external`){A(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}T.add(e.derived),await d({acquire:()=>Ge(e.derived),task:async()=>{A(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),k(e.derived),O(e.derived)}})}async function Ge(e){return await ce({lockDirPath:Ke(e),owner:{pid:process.pid,startTime:h(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,description:`iOS runner cache lock`})}function Ke(e){return w.join(w.dirname(e),`${w.basename(e)}.lock`)}function qe(e,t){!Qe()&&!t&&!T.has(e)||(A(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),k(e),O(e),T.delete(e))}async function E(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return Ue(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(A(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function D(e,t){if(e)throw new i(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:e.reason,refusingPath:e.path??t,...e.reason===`root_unusable`?{}:{resolvesTo:e.target},derived:t,hint:`Inspect ${e.path??t} under ${t}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function O(e){try{if(!C.existsSync(e))return;if(w.basename(e)!==`derived`){C.rmSync(e,{recursive:!0,force:!0});return}for(let t of C.readdirSync(e,{withFileTypes:!0}))Ye(t.name)&&C.rmSync(w.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Je=new Set([Te,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Ye(e){return Je.has(e)}function Xe(e){try{let t=JSON.parse(C.readFileSync(He(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function Ze(e,t){let n=Xe(e);return n?_e(De(n))===_e(De(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:ge(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function Qe(){return re(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function k(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!$e(e))throw new i(`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(v(),`.tmp`)}.`})}function $e(e){let t=w.resolve(v(),`.tmp`),n=w.relative(t,w.resolve(e));return n!==``&&!n.startsWith(`..`)&&!w.isAbsolute(n)}async function et(e){let t=Ze(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 tt(e,t){A(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function A(e,t,n){y({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const nt=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),rt=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function it(e,t,n){if(!a(e))return;if(t.length===0)throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:n});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!C.existsSync(e))throw new i(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:n});for(let e of r)await ct(e)||await at(e,n)}async function at(e,n){try{let t=w.join(e,`Contents`,`Frameworks`),n=C.existsSync(t)?C.readdirSync(t).sort().map(e=>w.join(t,e)):[];for(let e of n)await m(`codesign`,[...rt,e]);await m(`codesign`,[...rt,e])}catch(r){let i=t(r,`COMMAND_FAILED`);throw ot(e,n,i.message,i.details)}if(!await ct(e))throw ot(e,n,`Product still fails code signature verification after re-signing`)}function ot(e,t,n,r){return new i(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:n,details:r})}function st(e){if(!(e instanceof i))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&nt.has(t)}async function ct(e){return(await m(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const lt=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function ut(e){let t=await pt(e);if(!t||t.length===0)return null;let n=w.dirname(e),r=new Set,i=dt(t,n);for(let e of i.testRootPaths){if(!C.existsSync(e))return null;r.add(e)}for(let e of ft(i)){if(!e)return null;r.add(e)}return Array.from(r)}function dt(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=bt(e);o&&r.add(w.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function ft(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>C.existsSync(w.join(e,t)));return n?w.join(n,t):null})}async function pt(e){let t=await g(e);if(t)return mt(t);if(process.platform===`darwin`)return null;try{return vt(C.readFileSync(e,`utf8`))}catch{return null}}function mt(e){let t=new Set;for(let n of[e,...ht(e),...gt(e)])for(let e of _t(n))t.add(e);return Array.from(t)}function ht(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 gt(e){return Object.values(e).filter(e=>_(e)&&`TestBundlePath`in e)}function _t(e){let t=new Set;for(let[n,r]of Object.entries(e))if(lt.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 vt(e){return yt(o(e))}function yt(e){let t=new Set;return f(e,(e,n)=>{if(lt.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 bt(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const xt=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function St(e){await Ct(It(e))}async function Ct(e){let t=e.filter(Pt);if(t.length===0)return;let n=e.filter(e=>j(e)&&!Ft(e));for(let e of t){let t=Nt(e,n);t&&await wt(t,e)}}async function wt(e,t){let n=Tt(e,t),r=await Et(e,t);(n||r)&&(await kt(t),Mt(t))}function Tt(e,t){let n=!1;for(let r of C.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!jt(r.name)||At(w.join(e,r.name),w.join(t,r.name))&&(n=!0);return n}async function Et(e,t){let n=w.join(e,`Info.plist`),r=w.join(t,`Info.plist`),i=await g(n),a=await g(r);if(!i||!a)return!1;let o=Dt(i,a);if(o.length===0)return!1;for(let e of o)await Ot(r,e.key,e.value,e.shouldInsert);return!0}function Dt(e,t){return xt.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 Ot(e,t,n,r){s(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 kt(e){s(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 At(e,t){if(C.existsSync(t)){let n=C.readFileSync(e),r=C.readFileSync(t);return!n.equals(r)&&(C.copyFileSync(e,t),!0)}return C.copyFileSync(e,t),!0}function jt(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function Mt(e){let t=new Date;C.utimesSync(e,t,t)}function Nt(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 Pt(e){return j(e)&&Ft(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function Ft(e){return w.basename(e).endsWith(`-Runner.app`)}function j(e){return w.basename(e).endsWith(`.app`)}function It(e){if(!C.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of C.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=w.join(e,r.name);if(j(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const M=`AgentDeviceRunner.env`,Lt=`session`,Rt=`${P(`${M}.${Lt}`)}-`;function zt(e){return N(`${Lt}-${e.deviceId}-${e.ownerToken}-${e.port}`)}function Bt(e){return`${Rt}${P(N(e))}-[0-9]`}function Vt(e){let t=e?w.basename(e):``;if(t.startsWith(`${M}.`))return P(t)}function N(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}function P(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Ht={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function Ut(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?w.resolve(i):w.dirname(e);C.mkdirSync(a,{recursive:!0});let o=N(n),s=w.join(a,`${M}.${o}.json`),c=w.join(a,`${M}.${o}.xctestrun`),l=await Wt(e);return Jt(l,e=>Kt(e,t)),qt(l),await Gt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function Wt(e){let t=await m(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0||!t.stdout.trim())throw new i(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(t){throw new i(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(t)})}}async function Gt(e,t,n){C.writeFileSync(t,JSON.stringify(e,null,2)),s(await m(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function Kt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function qt(e){Jt(e,e=>Object.assign(e,Ht),{requireTestBundlePath:!0})}function Jt(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||Yt(e.TestTargets,t,n);for(let n of Object.values(e)){let e=Xt(n,{requireTestBundlePath:!0});e&&t(e)}}function Yt(e,t,n){if(Array.isArray(e))for(let r of e){let e=Xt(r,n);e&&t(e)}}function Xt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const Zt=new Map,F=new Map;function Qt(e){return mn(hn(e,!0))}function $t(e){return mn(hn(e,!1))}function en(e){e.retryPending=!1;let t=F.get(e.deviceId);t&&(t.inFlight.delete(e),pn(e.deviceId,t))}function tn(e){let t=fn(e);t.pendingTeardowns+=1;for(let e of t.inFlight)e.close(`device_teardown`);let n=!1;return()=>{n||(n=!0,--t.pendingTeardowns,pn(e,t))}}function nn(e){let t=[...new Set([...F.keys(),...e??[]])].map(e=>tn(e));return()=>{for(let e of t.splice(0))e()}}function rn(e){return(F.get(e)?.pendingTeardowns??0)>0}function an(e){let t=e;return!t.mintedByStart||t.admitted||t.retired!==`device_teardown`||rn(t.deviceId)?!1:(t.readmit(),!0)}function on(e,t){return t&&!t.admitted?!1:!rn(e)}function sn(e){return n({runnerStartRetired:!0,runnerStartRetirementReason:e})}function cn(e,t){if(!on(e,t))throw sn(t?.retired??`device_teardown`)}function ln(e,t){return t.aborted?`already-spent`:(e.interestedWaiters.add(t),`interested`)}function un(e,t){let n=e;return n.interestedWaiters.delete(t),!n.admitted||n.interestedWaiters.size>0?!1:n.close(`last_waiter_canceled`)}function dn(e,t){e.interestedWaiters.delete(t)}function fn(e){let t=F.get(e);if(t)return t;let n={pendingTeardowns:0,inFlight:new Set};return F.set(e,n),n}function pn(e,t){t.pendingTeardowns<=0&&t.inFlight.size===0&&F.delete(e)}function mn(e){return fn(e.deviceId).inFlight.add(e),e}function hn(e,t){let n=new Set,r;return{deviceId:e,interestedWaiters:n,mintedByStart:t,retryPending:!1,get admitted(){return r===void 0},get retired(){return r},close(t){return!r&&(r=t,y({level:`debug`,phase:`ios_runner_start_admission_retired`,data:{deviceId:e,reason:t}}),!0)},readmit(){r=void 0,y({level:`debug`,phase:`ios_runner_start_admission_readmitted`,data:{deviceId:e}})}}}const I=new Set;function gn(e,t,n){let r={deviceId:e,startAdmission:n,child:t};I.add(r),t.on(`close`,()=>{I.delete(r)})}function _n(e){return xn(e).map(e=>e.child)}function vn(e){return xn(e).filter(e=>e.startAdmission===void 0||!yn(e.startAdmission)).map(e=>e.child)}function yn(e){let t=e;return t.interestedWaiters.size>0||t.retryPending}function bn(e){e.retryPending=!0}function xn(e){return[...I].filter(t=>e===void 0||t.deviceId===e)}function Sn(e){for(let t of I)t.child===e&&I.delete(t)}async function Cn(e,t){let n=wn(t);if(n)return n;let r=v(),i=Ce(e,r,t.budget),a=Se(e,i);return await ne(Zt,a,async()=>await d({acquire:()=>Ge(a),task:()=>En({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function wn(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let n=w.resolve(t);if(!C.existsSync(n))throw new i(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:n});let r=e.iosXctestDerivedDataPath?.trim(),a=r?w.resolve(r):Tn(n);return A(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:n}),{xctestrunPath:n,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function Tn(e){let t=Be.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 En(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;qe(a,e.forceRebuild);let o=await et({derived:a,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:`miss`;return await Dn({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.reason!==`reuse_ready`&&tt(o,a),o.reason!==`cache_metadata_missing`&&(k(a),O(a)),await On({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function Dn(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await kn(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,cacheKey:we(r),artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`}:null}async function On(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=Ae(r);if(!C.existsSync(l))throw new i(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=ve(n.budget,`runner_xctestrun_build`),d=Date.now();ae({type:`command`,status:`progress`,message:`Building Apple runner...`}),await Fn(t,l,o,n,u);let f=Math.max(0,Date.now()-d),p=jn(o,t);if(!p)throw new i(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await ut(p);if(!m)throw new i(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await it(t,m,p),await Ct(m),D(await E(o,a,p,m),o),A(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,cacheKey:we(a),artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function kn(e,t,n,r){try{return await it(e,r.productPaths,r.xctestrunPath),D(await E(t,n,r.xctestrunPath,r.productPaths),t),A(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!st(e))throw e;return A(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function An(e){try{let t=v(),n=Ce(e,t);return(await et({derived:Se(e,n),expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function jn(e,t){let n=Mn(e);return n.length===0?null:(n.sort((e,n)=>Nn(e,n,t)),n[0]?.path??null)}function Mn(e){if(!C.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=C.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=C.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function Nn(e,t,n){if(n){let r=Pn(t.path,n)-Pn(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function Pn(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=pe(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 Fn(e,t,n,a,o){cn(e.id,a.startAdmission);let s=Ee(process.env),c=je(process.env,e.kind===`device`,e),l=e.kind===`device`?[`-allowProvisioningUpdates`]:[],d=he(),f=ye(process.env),p=ke();try{await u(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,xe(e),`1`,...Ne(e,me(e)),`-derivedDataPath`,n,...be(n),...d,...f,...p,...s,...l,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:t=>{gn(e.id,t,a.startAdmission)},onStdoutChunk:e=>{Me(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{Me(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(t){if(r(t))throw t;let n=t instanceof i?t:new i(`COMMAND_FAILED`,String(t)),o=Ie(e),{reason:s,hint:c,matched:l}=ze(new i(n.code,n.message,{...n.details,...o})),u=oe(n),d=`xcodebuild build-for-testing failed`;throw new i(`COMMAND_FAILED`,s===`simulator_set_destination_not_found`?Pe(d,e,o):d,{reason:s,error:n.message,details:n.details,logPath:a.logPath,hint:c,startupRuleMatched:l,startupHostDeadlineHit:u,...o})}}const L=process.pid;let In;function R(){return In??={value:h(process.pid)},In.value}function z(){return mr(L,R())}function Ln(e){let t=W(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:z(),ownerPid:L,ownerStartTime:R(),ownerStateDir:Wn(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?h(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...lr(Fe(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function Rn(e,t){return await d({acquire:()=>ce({lockDirPath:`${H(e)}.lock`,owner:{pid:L,startTime:R(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function B(e){try{return sr(JSON.parse(C.readFileSync(H(e),`utf8`)),e)}catch{return null}}function V(e){if(!e)return{type:`empty`};if(e.ownerToken===z())return{type:`owned`,lease:e};let t=le({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 zn(e,t,n){let r=e.id,a=V(B(r));if(a.type===`empty`){await t.cleanupRunnerXcodebuildProcesses({deviceId:r});return}if(a.type===`busy`){if(Bn(a.lease)){await q(a.lease,`same-state-dir`,t);return}if(Vn(a.lease,e)){await q(a.lease,`device-claim-takeover`,t);return}if(Hn(a.lease,n)){await q(a.lease,`logical-lease-takeover`,t);return}throw new i(`COMMAND_FAILED`,n?`iOS runner for ${r} is busy after device lease admission`:`iOS runner for ${r} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:r,logicalLeaseContext:n,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:Gn(a.lease,n)})}await q(a.lease,a.type,t)}function Bn(e){let t=Wn();return!t||!e.ownerStateDir?!1:w.resolve(t)===w.resolve(e.ownerStateDir)}function Vn(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&se(t)}function Hn(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:Un(t.deviceKey,e.deviceId)}function Un(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function Wn(){return te()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function Gn(e,t){let n=Kn(e),r=qn(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function Kn(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function qn(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${Jn(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function Jn(e,t){return`${e}=${ee(t)}`}function Yn(e){let t=V(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 Xn(e){let t=Yn(e);return t.type===`adoptable`?t.lease:null}function Zn(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Qn(e,t){let n=V(B(e));n.type===`owned`&&await q(n.lease,`owned`,t)}async function $n(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=ar(e);await Promise.all(n.map(async e=>{await q(e,`owned`,t)}))}function er(e){return B(e)?.ownerToken??null}function tr(e){e&&rr({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function nr(e){let t=H(e.deviceId);C.mkdirSync(w.dirname(t),{recursive:!0}),ue({destination:t,contents:JSON.stringify(e,null,2)})}function rr(e){let t=B(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{C.unlinkSync(H(e.deviceId))}catch{}}function H(e){return w.join(ir(),`${hr(e)}.json`)}function ir(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?w.resolve(e):w.join(Ve.homedir(),`.agent-device`,`apple-runner`,`leases`)}function ar(e){let t,n=ir();try{t=C.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=or(w.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function or(e){try{let t=JSON.parse(C.readFileSync(e,`utf8`)),n=U(t.deviceId);return n?sr(t,n):null}catch{return null}}function sr(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=cr(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:G(n.ownerStartTime),ownerStateDir:G(n.ownerStateDir)??void 0,runnerPid:K(n.runnerPid),runnerStartTime:G(n.runnerStartTime),runnerLogPath:W(n.runnerLogPath),cacheKey:W(n.cacheKey),...lr(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function cr(e){let t={ownerToken:U(e.ownerToken),ownerPid:K(e.ownerPid),sessionId:U(e.sessionId),port:K(e.port),xctestrunPath:U(e.xctestrunPath),jsonPath:U(e.jsonPath),createdAtMs:ur(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function U(e){return typeof e==`string`&&e.length>0?e:null}function W(e){return U(e)??void 0}function lr(e){let t=U(e);return t?{simulatorSetPath:t}:{}}function G(e){return typeof e==`string`?e:null}function K(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function ur(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function q(e,t,n){y({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(fr(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(fr(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),tr(e)}function dr(e,t){return b(t)&&J(e,t)}function fr(e){let t=e.runnerPid??void 0;if(!(!t||!b(t))){if(J(e,t))return t;y({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function J(e,t){return e.runnerStartTime?h(t)===e.runnerStartTime:pr(l(t))}function pr(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function mr(e,t){let n=Be.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function hr(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var gr=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>_r,abortRunnerSessionsAndPrepProcesses:()=>xr,cleanupOwnedIosRunnerLease:()=>br,disposeRunnerSession:()=>yr,isRunnerProcessAlive:()=>Mr,runnerLeaseCleanupAdapter:()=>Y,stopRunnerPrepProcesses:()=>Sr,stopRunnerPrepProcessesWithoutLiveOwner:()=>Cr});const _r=1e3,vr=2e3,Y={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Pr,cleanupTempFile:S};async function yr(e,t={}){x(e,`draining`);let n=!1;if(t.graceful!==!1)n=await Tr(e);else if(a(e.device)){await X([e]),await Z(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await Er(e,t.waitTimeoutMs??1e4),jr(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Z(e,t)}async function br(e){await Qn(e,Y)}async function xr(e){let t=_n(),n=e.filter(e=>a(e.device)),r=e.filter(e=>!a(e.device));for(let t of e)x(t,`draining`);await Q(r,`SIGINT`),await Nr(t,`SIGINT`),await Q(r,`SIGTERM`),await Nr(t,`SIGTERM`),await Q(r,`SIGKILL`),await Nr(t,`SIGKILL`),await X(n),await Promise.allSettled(e.map(async e=>{await Z(e)}))}async function Sr(e){await wr(_n(e))}async function Cr(e){await wr(vn(e))}async function wr(e){await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{Sn(e)}}))}async function Tr(e){try{return await Le(e.device,e.port,Re({command:`shutdown`}),void 0,15e3),!1}catch{return a(e.device)?(await X([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function Er(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!jr(e.child.pid)}finally{n&&clearTimeout(n)}}async function X(e){if(e.length===0)return;await Q(e,`SIGINT`);let t=await Dr(e,5e3);await Q(t,`SIGTERM`),await Q(await Dr(t,2e3),`SIGKILL`)}async function Dr(e,t){let n=await Promise.all(e.map(async e=>await Er(e,t)));return e.filter((e,t)=>!n[t])}async function Z(e,t={}){await Or(e,t),S(e.xctestrunPath),S(e.jsonPath),x(e,`stopped`)}async function Or(e,t){let n=async()=>{if(!kr(e))try{await Ar(e.device)}finally{tr(e.lease)}};if(t.leaseLockHeld){await n();return}try{await Rn(e.deviceId,n)}catch(t){y({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 kr(e){let t=er(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Ar(e){e.kind===`simulator`&&await Promise.allSettled(Oe.map(async t=>{try{await p(ie(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:vr})}catch(n){y({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:vr,error:n instanceof Error?n.message:String(n)}})}}))}function jr(e){return e?Mr(e)||de(e):!1}function Mr(e){return e?b(e):!1}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Nr(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&Sn(e)}))}async function $(e,t){if(!e||e<=0)return;c(e,t),fe([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await m(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Pr(e){let{deviceId:t}=e,n=`xcodebuild.*test-without-building.*${Vt(e.xctestrunPath)??Bt(t)}`;for(let e of[`TERM`,`KILL`])try{await m(`pkill`,[`-${e}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){y({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:t,signal:e,error:n instanceof Error?n.message:String(n)}})}}export{Qt as A,ut as B,un as C,en as D,jn as E,on as F,D as H,sn as I,zt as L,an as M,dn as N,An as O,nn as P,Ut as R,cn as S,tn as T,E as U,We as V,z as _,Mr as a,nr as b,Sr as c,Ln as d,$n as f,Xn as g,Yn as h,yr as i,$t as j,bn as k,Cr as l,zn as m,xr as n,Y as o,dr as p,br as r,gr as s,_r as t,Zn as u,J as v,Cn as w,ln as x,Rn as y,St as z};
@@ -1 +1 @@
1
- import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,d as r,l as i,p as a,s as o,u as s,v as c,y as l}from"./runner-cache-metadata.js";import{a as u,c as d,d as f,f as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./runner-client.js";import{A as S,D as C,E as w,S as T,g as E,k as D,v as O}from"./runner-disposal.js";async function k(e,t,n,r){return await d(e,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:n},r)}async function A(e){let{cleanupRunnerLeasesForOwner:t}=await import(`./runner-client.js`).then(e=>e.t),{runnerLeaseCleanupAdapter:n}=await import(`./runner-disposal.js`).then(e=>e.s);await t(e,n)}export{w as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,T as findRunnerXctestrun,g as hasLiveIosRunnerSession,t as isRunnerXcuitestScriptPlatform,y as notifyIosRunnerAppRelaunched,m as prepareIosRunner,u as prewarmAppleRunnerCache,_ as prewarmIosRunnerSession,k as queryAppleRunnerSelector,x as readRunnerSessionLiveness,E as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,D as requireCertifiedRunnerCacheArtifacts,o as requireRunnerBuildSettingsMatchBuildLog,C as resolveExistingRunnerProductPaths,i as resolveExpectedRunnerCacheMetadata,s as resolveRunnerAppBundleId,r as resolveRunnerArchBuildSettings,a as resolveRunnerBundleBuildSettings,n as resolveRunnerPerformanceBuildSettings,c as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,l as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,O as verifyLeaseRunnerPidIdentity,S as writeRunnerCacheMetadataForArtifacts};
1
+ import{l as e,n as t}from"./apple-runner-platform.js";import{_ as n,d as r,l as i,p as a,s as o,u as s,v as c,y as l}from"./runner-cache-metadata.js";import{a as u,c as d,d as f,f as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./runner-client.js";import{B as S,E as C,H as w,U as T,g as E,v as D,z 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{O as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,h as detachIosRunnerSessionsForShutdown,C as findRunnerXctestrun,g as hasLiveIosRunnerSession,t as isRunnerXcuitestScriptPlatform,y as notifyIosRunnerAppRelaunched,m as prepareIosRunner,u as prewarmAppleRunnerCache,_ as prewarmIosRunnerSession,k as queryAppleRunnerSelector,x as readRunnerSessionLiveness,E as readStaleRunnerLease,f as releaseIosRunnerOnClose,b as releaseSpeculativeIosRunnerSessionFor,w as requireCertifiedRunnerCacheArtifacts,o as requireRunnerBuildSettingsMatchBuildLog,S as resolveExistingRunnerProductPaths,i as resolveExpectedRunnerCacheMetadata,s as resolveRunnerAppBundleId,r as resolveRunnerArchBuildSettings,a as resolveRunnerBundleBuildSettings,n as resolveRunnerPerformanceBuildSettings,c as resolveRunnerSandboxBuildArgs,e as resolveRunnerScriptDevice,l as resolveRunnerSigningBuildSettings,d as runAppleRunnerCommand,p as stopAllIosRunnerSessions,v as stopIosRunnerSession,D as verifyLeaseRunnerPidIdentity,T as writeRunnerCacheMetadataForArtifacts};
@@ -1 +1 @@
1
- import{I as e,K as t,P as n}from"./sdk-contracts.js";import{u as r}from"./host.js";import{i}from"./runner-cache-metadata.js";import{o as a}from"./runner-session-types.js";import{N as o,k as s}from"./runner-error-classification.js";import{l as c}from"./runner-disposal.js";function l(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(u(n,t!==void 0))},n);s.unref?.();let c=o(e),l=c?AbortSignal.any([c,r.signal]):r.signal;return{phase:i(n,l),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function u(e,t){return new n(`COMMAND_FAILED`,`Apple runner start exceeded its ${t?`startup timeout`:`default start budget`} of ${e}ms`,{reason:`runner_start_budget_exhausted`,timeoutMs:e,retriable:!0,hint:t?"Raise the startup timeout, or run `prepare ios-runner` first so the runner is built before it is needed.":"Run `prepare ios-runner --timeout <ms>` so the cold build has a budget of your choosing; the session runner.log names the step that stalled."})}async function d(t,n,r){return n?await new Promise((i,a)=>{let o=()=>{a(e(void 0,n.reason)),s(n.reason)||c(r),t.catch(f)};n.aborted?o():n.addEventListener(`abort`,o,{once:!0}),t.then(i,a).finally(()=>n.removeEventListener(`abort`,o))}):await t}function f(e){if(t(e))return;let i=e instanceof n?e:void 0;r({level:`warn`,phase:`ios_runner_detached_start_failed`,data:{code:i?.code,reason:i?.details?.reason,error:e instanceof Error?e.message:String(e)}})}export{l as openRunnerStartBudget,d as raceRunnerStartAgainstCaller};
1
+ import{I as e,K as t,P as n}from"./sdk-contracts.js";import{u as r}from"./host.js";import{i}from"./runner-cache-metadata.js";import{o as a}from"./runner-session-types.js";import{N as o,k as s}from"./runner-error-classification.js";import{C as c,N as l,k as u,l as d,x as f}from"./runner-disposal.js";function p(e){let t=a(e.startupTimeoutMs),n=t??6e5,r=new AbortController,s=setTimeout(()=>{r.abort(m(n,t!==void 0))},n);s.unref?.();let c=o(e),l=c?AbortSignal.any([c,r.signal]):r.signal;return{phase:i(n,l),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(s)}}function m(e,t){return new n(`COMMAND_FAILED`,`Apple runner start exceeded its ${t?`startup timeout`:`default start budget`} of ${e}ms`,{reason:`runner_start_budget_exhausted`,timeoutMs:e,retriable:!0,hint:t?"Raise the startup timeout, or run `prepare ios-runner` first so the runner is built before it is needed.":"Run `prepare ios-runner --timeout <ms>` so the cold build has a budget of your choosing; the session runner.log names the step that stalled."})}async function h(t,n,r){return r?await new Promise((i,a)=>{let o=r.aborted?`already-spent`:f(n,r),p=()=>{if(a(e(void 0,r.reason)),t.catch(_),s(r.reason)){o===`interested`&&l(n,r),u(n);return}c(n,r)&&d(n.deviceId)};r.aborted?p():r.addEventListener(`abort`,p,{once:!0}),t.then(i,a).finally(()=>{r.removeEventListener(`abort`,p),o===`interested`&&l(n,r)})}):await t}function g(e,t){let n=t.signal?void 0:o(t);if(!n||f(e,n)!==`interested`)return()=>{};let r=()=>{c(e,n)&&d(e.deviceId)};return n.addEventListener(`abort`,r,{once:!0}),()=>{n.removeEventListener(`abort`,r),l(e,n)}}function _(e){if(t(e))return;let i=e instanceof n?e:void 0;r({level:`warn`,phase:`ios_runner_detached_start_failed`,data:{code:i?.code,reason:i?.details?.reason,error:e instanceof Error?e.message:String(e)}})}export{p as openRunnerStartBudget,h as raceRunnerStartAgainstCaller,g as reserveRunnerStartOwnerInterest};
@@ -1,2 +1,2 @@
1
- import{H as e,I as t,K as n,P as r}from"./sdk-contracts.js";import{i}from"./recording-export-quality.js";import{C as a,E as o,O as s,T as c,a as l,b as u,i as d,o as f,r as p,t as ee,w as te,x as m,y as h}from"./runtime.js";import{r as g}from"./success-text.js";import{n as ne,t as re}from"./app-inventory.js";import"./app-inventory-contract.js";import{A as ie}from"./owner-identity.js";import{l as ae}from"./exec.js";import"./file.js";import{r as oe}from"./tv-remote.js";import"./command.js";import{r as se}from"./version.js";import{t as ce}from"./keyboard-actions.js";import{i as le}from"./quality-warnings.js";import{r as _}from"./png.js";import{i as ue}from"./png-worker-client.js";import{t as de}from"./png-size.js";import{i as v,n as fe,r as pe}from"./screenshot-overlay-draw.js";import{t as me}from"./png-encode.js";import{r as y}from"./artifact-paths.js";import{t as he}from"./mp4-duration.js";import{c as b,o as ge,r as _e,s as ve}from"./video.js";import x from"node:fs";import ye from"node:os";import S from"node:path";function C(e,t){if(e!==void 0)return w(e,t)}function w(e,t){let n=e?.trim();if(!n)throw new r(`INVALID_ARGS`,`${t} must be a non-empty string`);return n}const be=async(e,t={})=>{if(!e.backend.listDevices)throw new r(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(m(e,t),t.filter)}},xe=async(e,t={})=>{if(!e.backend.bootDevice)throw new r(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let n=ke(t.target),i=await e.backend.bootDevice(m(e,t),n),a=u(i);return{kind:`deviceBooted`,...n?{target:n}:{},...a?{backendResult:a}:{},...g(`Booted device`)}},Se=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new r(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let n=ke(t.target),i=await e.backend.shutdownDevice(m(e,t),n),a=u(i);return{kind:`deviceShutdown`,...n?{target:n}:{},...a?{backendResult:a}:{},...g(`Shutdown device`)}},Ce=async(e,t)=>await T(e,t,`install`),we=async(e,t)=>await T(e,t,`reinstall`),Te=async(e,t)=>await T(e,t,`installFromSource`);async function T(e,t,n){let i=n===`reinstall`?`reinstallApp`:`installApp`,a=e.backend[i];if(!a)throw new r(`UNSUPPORTED_OPERATION`,`admin.${n} is not supported by this backend`);let o=`app`in t&&t.app!==void 0?w(t.app,`app`):void 0;if(n!==`installFromSource`&&!o)throw new r(`INVALID_ARGS`,`admin.${n} requires app`);let s=m(e,t),c=await Ee(e,s,t.source);try{let t=await a.call(e.backend,s,{...o?{app:o}:{},source:c.source});return Ae(n,o,c.source,t)}finally{await c.cleanup?.()}}async function Ee(e,t,n){let r=await De(e,E(n));try{return{source:E(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function De(e,t){if(t.kind===`url`)return{source:t};let n=await d(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function E(e){if(!e||typeof e!=`object`)throw new r(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:w(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:w(e.id,`source.id`)};if(e.kind===`url`){let t=w(e.url,`source.url`);return Oe(t),{kind:`url`,url:t}}throw new r(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function Oe(e){let t;try{t=new URL(e)}catch{throw new r(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new r(`INVALID_ARGS`,`Install source URL must use http or https`)}function ke(e){if(!e)return;let t=C(e.id,`target.id`),n=C(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function Ae(e,t,n,r){let i=u(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=D(r,`appName`),s=D(r,`appId`),c=D(r,`bundleId`),l=D(r,`packageName`),d=D(r,`launchTarget`),f=D(r,`installablePath`),p=D(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...c?{bundleId:c}:{},...l?{packageName:l}:{},...d?{launchTarget:d}:{},...f?{installablePath:f}:{},...p?{archivePath:p}:{},...i?{backendResult:i}:{},...g(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??d??t??je(n)}`)}}function D(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function je(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const Me=/^[A-Za-z0-9_.:-]{1,64}$/,Ne=async(e,t)=>{if(!e.backend.openApp)throw new r(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let n=ze(t),i=await e.backend.openApp(k(e,t),n,{launchArgs:t.launchArgs,relaunch:t.relaunch}),a=u(i);return{kind:`appOpened`,target:n,relaunch:t.relaunch===!0,...a?{backendResult:a}:{},...g(`Opened: ${Ve(n)}`)}},Pe=async(e,t={})=>{if(!e.backend.closeApp)throw new r(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let n=C(t.app,`app`),i=await e.backend.closeApp(k(e,t),n),a=u(i);return{kind:`appClosed`,...n?{app:n}:{},...a?{backendResult:a}:{},...g(n?`Closed: ${n}`:`Closed app`)}},Fe=async(e,t={})=>{if(!e.backend.listApps)throw new r(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(k(e,t),re(t.filter))}},Ie=async(e,t)=>{if(!e.backend.getAppState)throw new r(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let n=w(t.app,`app`);return{kind:`appState`,app:n,state:await e.backend.getAppState(k(e,t),n)}},Le=async(e,t)=>{if(!e.backend.pushFile)throw new r(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let n=w(t.app,`app`),i=await He(e,t.input);try{let r=await e.backend.pushFile(k(e,t),i.backendInput,n),a=u(r);return{kind:`appPushed`,app:n,inputKind:i.inputKind,...a?{backendResult:a}:{},...g(`Pushed to ${n}`)}}finally{await i.cleanup?.()}},Re=async(e,t)=>{if(!e.backend.triggerAppEvent)throw new r(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let n=Ue(t.name);We(t.payload,`apps.triggerEvent payload for "${n}"`);let i=await e.backend.triggerAppEvent(k(e,t),{name:n,...t.payload?{payload:t.payload}:{}}),a=u(i);return{kind:`appEventTriggered`,name:n,...t.payload?{payload:t.payload}:{},...a?{backendResult:a}:{},...g(`Triggered app event: ${n}`)}};function ze(e){let t=C(e.app,`app`),n=C(e.appId,`appId`),i=C(e.bundleId,`bundleId`),a=C(e.packageName,`packageName`),o=C(e.url,`url`),s=C(e.activity,`activity`),c={...t?{app:t}:{},...n?{appId:n}:{},...i?{bundleId:i}:{},...a?{packageName:a}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!Be(c))throw new r(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function Be(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function Ve(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function He(e,t){if(!t||typeof t!=`object`)throw new r(`INVALID_ARGS`,`apps.push requires an input`);if(t.kind===`json`)return O(t.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:t.payload},inputKind:`json`};let n=await d(e,t,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:n.path},inputKind:`file`,...n.cleanup?{cleanup:n.cleanup}:{}}}function Ue(e){let t=w(e,`name`);if(!Me.test(t))throw new r(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${t}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return t}function We(e,t){e!==void 0&&O(e,t,8192)}function O(e,t,n){if(Ge(e,t),Buffer.byteLength(Ke(e,t),`utf8`)>n)throw new r(`INVALID_ARGS`,`${t} exceeds ${n} bytes`)}function Ge(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be a JSON object`)}function Ke(e,t){try{let n=JSON.stringify(e);if(typeof n!=`string`)throw new r(`INVALID_ARGS`,`${t} must be JSON-serializable`);return n}catch{throw new r(`INVALID_ARGS`,`${t} must be JSON-serializable`)}}function k(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const A={open:Ne,close:Pe,list:Fe,state:Ie,push:Le,triggerEvent:Re},qe={devices:be,boot:xe,shutdown:Se,install:Ce,reinstall:we,installFromSource:Te};function Je(e){return{...h(A,e),list:(t={})=>A.list(e,{...t,filter:ne(t.filter)})}}const Ye=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,Xe=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function j(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(Xe,()=>(t=!0,`[REDACTED]`)),n=Qe(n,()=>{t=!0}),{value:n,redacted:t}}function Ze(e){try{let t=new URL(e),n=$e(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Qe(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=Ze(e);return n?(n.redacted&&t(),n.value):e}):e}function $e(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Ye.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const M=2048,N=4096,P=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function et(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function tt(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?rt(e.url):void 0,i=t===`headers`||t===`all`?F(e.requestHeaders):void 0,a=t===`headers`||t===`all`?F(e.responseHeaders):void 0,o=t===`body`||t===`all`?I(e.requestBody):void 0,s=t===`body`||t===`all`?I(e.responseBody):void 0,c=L(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function nt(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function F(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(P.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=z(i,M);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function rt(e){return Ze(e)??z(e,M)}function I(e){return e===void 0?{redacted:!1}:it(e)??z(e,M)}function it(e){try{let t=R(JSON.parse(e),j);return B(JSON.stringify(t.value),M,t.redacted)}catch{return}}function L(e){return R(e,e=>z(e,M))}function R(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=R(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(P.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=R(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function z(e,t){if(e===void 0)return{redacted:!1};let n=j(e);return B(n.value,t,n.redacted)}function B(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const at=async(e,t={})=>{if(!e.backend.readLogs)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return et(await e.backend.readLogs(await V(e,t),ct(t)))},ot=async(e,t={})=>{if(!e.backend.dumpNetwork)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let n=lt(t);return tt(await e.backend.dumpNetwork(await V(e,t),n),n.include??`summary`)},st=async(e,t={})=>{if(!e.backend.measurePerf)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return nt(await e.backend.measurePerf(await V(e,t),ut(t)))};async function V(e,t){let n=m(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function ct(e){return{...H(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:W(e.levels,`levels`)},...e.search===void 0?{}:{search:w(e.search,`search`)},...e.source===void 0?{}:{source:w(e.source,`source`)}}}function lt(e){return{...H(e,25,200,`network limit`),include:dt(e.include)}}function ut(e){return{...U(e),...e.sampleMs===void 0?{}:{sampleMs:s(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:W(e.metrics,`metrics`,20)}}}function H(e,t,n,r){return{...U(e),...e.cursor===void 0?{}:{cursor:w(e.cursor,`cursor`)},limit:e.limit===void 0?t:s(e.limit,r,1,n)}}function U(e){return{...e.since===void 0?{}:{since:w(e.since,`since`)},...e.until===void 0?{}:{until:w(e.until,`until`)}}}function dt(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new r(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function W(e,t,n=50){if(!Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be an array of strings`);if(e.length>n)throw new r(`INVALID_ARGS`,`${t} must contain at most ${n} entries`);return e.map((e,n)=>w(e,`${t}[${n}]`))}const ft={logs:at,network:ot,perf:st},G=`contact_sheet_frame_extraction_failed`,K=`contact_sheet_no_frames`;function q(e=process.platform){if(e!==`darwin`)throw new r(`UNSUPPORTED_OPERATION`,`Contact sheets can only be built on macOS hosts, which is where the frame decoder runs`,{reason:`contact_sheet_unsupported_host`,hostPlatform:e,hint:`Run this command on the macOS host that recorded the clip, or read the video artifact itself.`})}async function pt(e){if(q(e.hostPlatform??process.platform),e.timesMs.length===0)throw new r(`COMMAND_FAILED`,`Contact sheet sampling requested no frames`,{reason:K,videoPath:e.videoPath});Q(e.signal);let t=await vt(e);Q(e.signal);let n;try{n=await ae(t,[`--input`,e.videoPath,`--output-dir`,e.scratchDir,`--times`,e.timesMs.join(`,`),`--max-width`,String(e.maxWidth)],{timeoutMs:9e4,env:ge(),allowFailure:!0,...e.signal===void 0?{}:{signal:e.signal}})}catch(t){X(t,e.videoPath,`Failed to run the frame decoder`)}if(n.exitCode!==0)throw new r(`COMMAND_FAILED`,`Failed to extract frames from the recording: ${_t(n.stderr)||`exit ${n.exitCode}`}`,{reason:G,videoPath:e.videoPath,exitCode:n.exitCode});let i=mt(n.stdout,e.videoPath,e.scratchDir,e.timesMs.length);if(i.frames.length===0)throw new r(`COMMAND_FAILED`,`The recording returned no decodable frames for a contact sheet`,{reason:K,videoPath:e.videoPath,skippedSampleCount:i.skippedSampleCount});return i}function mt(e,t,n,r){let i;try{i=JSON.parse(e)}catch(e){throw Y(t,`invalid manifest: ${String(e)}`)}let a=Z(i).frames;if(!Array.isArray(a))throw Y(t,`manifest has no frames array`);let o=Z(i).skipped;if(a.length>r)throw Y(t,`returned ${a.length} frames for ${r} requested samples`);let s=a.flatMap(e=>{let r=Z(e),i=ht(r.path),a=gt(r.actualTimeMs);if(i===void 0||a===void 0||a<0)throw Y(t,`frame entry is missing a path or presentation time`);let o=S.resolve(n,S.basename(i));return x.existsSync(o)?[{requestedTimeMs:gt(r.requestedTimeMs)??a,actualTimeMs:a,path:o}]:[]});return{frames:s.sort((e,t)=>e.actualTimeMs-t.actualTimeMs),skippedSampleCount:Math.max(Array.isArray(o)?o.length:0,r-s.length)}}function J(e,t,n){return new r(`COMMAND_FAILED`,e,{reason:G,videoPath:t},n)}function Y(e,t){return J(`Frame extraction returned an unreadable manifest: ${t}`,e)}function X(t,i,a){throw n(t)||t instanceof r&&t.code===`COMMAND_FAILED`&&t.details?.reason?t:J(`${a} for ${i}: ${e(t)}`,i,t)}function Z(e){return typeof e==`object`&&e?e:{}}function ht(e){return typeof e==`string`&&e!==``?e:void 0}function gt(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function _t(e){return(e.trim().split(`
1
+ import{H as e,I as t,K as n,P as r}from"./sdk-contracts.js";import{i}from"./recording-export-quality.js";import{C as a,E as o,O as s,T as c,a as l,b as u,i as d,o as f,r as p,t as ee,w as te,x as m,y as h}from"./runtime.js";import{r as g}from"./success-text.js";import{n as ne,t as re}from"./app-inventory.js";import"./app-inventory-contract.js";import{j as ie}from"./owner-identity.js";import{l as ae}from"./exec.js";import"./file.js";import{r as oe}from"./tv-remote.js";import"./command.js";import{r as se}from"./version.js";import{t as ce}from"./keyboard-actions.js";import{i as le}from"./quality-warnings.js";import{r as _}from"./png.js";import{i as ue}from"./png-worker-client.js";import{t as de}from"./png-size.js";import{i as v,n as fe,r as pe}from"./screenshot-overlay-draw.js";import{t as me}from"./png-encode.js";import{r as y}from"./artifact-paths.js";import{t as he}from"./mp4-duration.js";import{c as b,o as ge,r as _e,s as ve}from"./video.js";import x from"node:fs";import ye from"node:os";import S from"node:path";function C(e,t){if(e!==void 0)return w(e,t)}function w(e,t){let n=e?.trim();if(!n)throw new r(`INVALID_ARGS`,`${t} must be a non-empty string`);return n}const be=async(e,t={})=>{if(!e.backend.listDevices)throw new r(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(m(e,t),t.filter)}},xe=async(e,t={})=>{if(!e.backend.bootDevice)throw new r(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let n=ke(t.target),i=await e.backend.bootDevice(m(e,t),n),a=u(i);return{kind:`deviceBooted`,...n?{target:n}:{},...a?{backendResult:a}:{},...g(`Booted device`)}},Se=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new r(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let n=ke(t.target),i=await e.backend.shutdownDevice(m(e,t),n),a=u(i);return{kind:`deviceShutdown`,...n?{target:n}:{},...a?{backendResult:a}:{},...g(`Shutdown device`)}},Ce=async(e,t)=>await T(e,t,`install`),we=async(e,t)=>await T(e,t,`reinstall`),Te=async(e,t)=>await T(e,t,`installFromSource`);async function T(e,t,n){let i=n===`reinstall`?`reinstallApp`:`installApp`,a=e.backend[i];if(!a)throw new r(`UNSUPPORTED_OPERATION`,`admin.${n} is not supported by this backend`);let o=`app`in t&&t.app!==void 0?w(t.app,`app`):void 0;if(n!==`installFromSource`&&!o)throw new r(`INVALID_ARGS`,`admin.${n} requires app`);let s=m(e,t),c=await Ee(e,s,t.source);try{let t=await a.call(e.backend,s,{...o?{app:o}:{},source:c.source});return Ae(n,o,c.source,t)}finally{await c.cleanup?.()}}async function Ee(e,t,n){let r=await De(e,E(n));try{return{source:E(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function De(e,t){if(t.kind===`url`)return{source:t};let n=await d(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function E(e){if(!e||typeof e!=`object`)throw new r(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:w(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:w(e.id,`source.id`)};if(e.kind===`url`){let t=w(e.url,`source.url`);return Oe(t),{kind:`url`,url:t}}throw new r(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function Oe(e){let t;try{t=new URL(e)}catch{throw new r(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new r(`INVALID_ARGS`,`Install source URL must use http or https`)}function ke(e){if(!e)return;let t=C(e.id,`target.id`),n=C(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function Ae(e,t,n,r){let i=u(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=D(r,`appName`),s=D(r,`appId`),c=D(r,`bundleId`),l=D(r,`packageName`),d=D(r,`launchTarget`),f=D(r,`installablePath`),p=D(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...c?{bundleId:c}:{},...l?{packageName:l}:{},...d?{launchTarget:d}:{},...f?{installablePath:f}:{},...p?{archivePath:p}:{},...i?{backendResult:i}:{},...g(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??d??t??je(n)}`)}}function D(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function je(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const Me=/^[A-Za-z0-9_.:-]{1,64}$/,Ne=async(e,t)=>{if(!e.backend.openApp)throw new r(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let n=ze(t),i=await e.backend.openApp(k(e,t),n,{launchArgs:t.launchArgs,relaunch:t.relaunch}),a=u(i);return{kind:`appOpened`,target:n,relaunch:t.relaunch===!0,...a?{backendResult:a}:{},...g(`Opened: ${Ve(n)}`)}},Pe=async(e,t={})=>{if(!e.backend.closeApp)throw new r(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let n=C(t.app,`app`),i=await e.backend.closeApp(k(e,t),n),a=u(i);return{kind:`appClosed`,...n?{app:n}:{},...a?{backendResult:a}:{},...g(n?`Closed: ${n}`:`Closed app`)}},Fe=async(e,t={})=>{if(!e.backend.listApps)throw new r(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(k(e,t),re(t.filter))}},Ie=async(e,t)=>{if(!e.backend.getAppState)throw new r(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let n=w(t.app,`app`);return{kind:`appState`,app:n,state:await e.backend.getAppState(k(e,t),n)}},Le=async(e,t)=>{if(!e.backend.pushFile)throw new r(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let n=w(t.app,`app`),i=await He(e,t.input);try{let r=await e.backend.pushFile(k(e,t),i.backendInput,n),a=u(r);return{kind:`appPushed`,app:n,inputKind:i.inputKind,...a?{backendResult:a}:{},...g(`Pushed to ${n}`)}}finally{await i.cleanup?.()}},Re=async(e,t)=>{if(!e.backend.triggerAppEvent)throw new r(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let n=Ue(t.name);We(t.payload,`apps.triggerEvent payload for "${n}"`);let i=await e.backend.triggerAppEvent(k(e,t),{name:n,...t.payload?{payload:t.payload}:{}}),a=u(i);return{kind:`appEventTriggered`,name:n,...t.payload?{payload:t.payload}:{},...a?{backendResult:a}:{},...g(`Triggered app event: ${n}`)}};function ze(e){let t=C(e.app,`app`),n=C(e.appId,`appId`),i=C(e.bundleId,`bundleId`),a=C(e.packageName,`packageName`),o=C(e.url,`url`),s=C(e.activity,`activity`),c={...t?{app:t}:{},...n?{appId:n}:{},...i?{bundleId:i}:{},...a?{packageName:a}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!Be(c))throw new r(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function Be(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function Ve(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function He(e,t){if(!t||typeof t!=`object`)throw new r(`INVALID_ARGS`,`apps.push requires an input`);if(t.kind===`json`)return O(t.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:t.payload},inputKind:`json`};let n=await d(e,t,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:n.path},inputKind:`file`,...n.cleanup?{cleanup:n.cleanup}:{}}}function Ue(e){let t=w(e,`name`);if(!Me.test(t))throw new r(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${t}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return t}function We(e,t){e!==void 0&&O(e,t,8192)}function O(e,t,n){if(Ge(e,t),Buffer.byteLength(Ke(e,t),`utf8`)>n)throw new r(`INVALID_ARGS`,`${t} exceeds ${n} bytes`)}function Ge(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be a JSON object`)}function Ke(e,t){try{let n=JSON.stringify(e);if(typeof n!=`string`)throw new r(`INVALID_ARGS`,`${t} must be JSON-serializable`);return n}catch{throw new r(`INVALID_ARGS`,`${t} must be JSON-serializable`)}}function k(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const A={open:Ne,close:Pe,list:Fe,state:Ie,push:Le,triggerEvent:Re},qe={devices:be,boot:xe,shutdown:Se,install:Ce,reinstall:we,installFromSource:Te};function Je(e){return{...h(A,e),list:(t={})=>A.list(e,{...t,filter:ne(t.filter)})}}const Ye=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,Xe=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function j(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(Xe,()=>(t=!0,`[REDACTED]`)),n=Qe(n,()=>{t=!0}),{value:n,redacted:t}}function Ze(e){try{let t=new URL(e),n=$e(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Qe(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=Ze(e);return n?(n.redacted&&t(),n.value):e}):e}function $e(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Ye.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const M=2048,N=4096,P=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function et(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function tt(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?rt(e.url):void 0,i=t===`headers`||t===`all`?F(e.requestHeaders):void 0,a=t===`headers`||t===`all`?F(e.responseHeaders):void 0,o=t===`body`||t===`all`?I(e.requestBody):void 0,s=t===`body`||t===`all`?I(e.responseBody):void 0,c=L(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function nt(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=z(e.message,N),r=L(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function F(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(P.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=z(i,M);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function rt(e){return Ze(e)??z(e,M)}function I(e){return e===void 0?{redacted:!1}:it(e)??z(e,M)}function it(e){try{let t=R(JSON.parse(e),j);return B(JSON.stringify(t.value),M,t.redacted)}catch{return}}function L(e){return R(e,e=>z(e,M))}function R(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=R(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(P.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=R(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function z(e,t){if(e===void 0)return{redacted:!1};let n=j(e);return B(n.value,t,n.redacted)}function B(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const at=async(e,t={})=>{if(!e.backend.readLogs)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return et(await e.backend.readLogs(await V(e,t),ct(t)))},ot=async(e,t={})=>{if(!e.backend.dumpNetwork)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let n=lt(t);return tt(await e.backend.dumpNetwork(await V(e,t),n),n.include??`summary`)},st=async(e,t={})=>{if(!e.backend.measurePerf)throw new r(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return nt(await e.backend.measurePerf(await V(e,t),ut(t)))};async function V(e,t){let n=m(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function ct(e){return{...H(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:W(e.levels,`levels`)},...e.search===void 0?{}:{search:w(e.search,`search`)},...e.source===void 0?{}:{source:w(e.source,`source`)}}}function lt(e){return{...H(e,25,200,`network limit`),include:dt(e.include)}}function ut(e){return{...U(e),...e.sampleMs===void 0?{}:{sampleMs:s(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:W(e.metrics,`metrics`,20)}}}function H(e,t,n,r){return{...U(e),...e.cursor===void 0?{}:{cursor:w(e.cursor,`cursor`)},limit:e.limit===void 0?t:s(e.limit,r,1,n)}}function U(e){return{...e.since===void 0?{}:{since:w(e.since,`since`)},...e.until===void 0?{}:{until:w(e.until,`until`)}}}function dt(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new r(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function W(e,t,n=50){if(!Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be an array of strings`);if(e.length>n)throw new r(`INVALID_ARGS`,`${t} must contain at most ${n} entries`);return e.map((e,n)=>w(e,`${t}[${n}]`))}const ft={logs:at,network:ot,perf:st},G=`contact_sheet_frame_extraction_failed`,K=`contact_sheet_no_frames`;function q(e=process.platform){if(e!==`darwin`)throw new r(`UNSUPPORTED_OPERATION`,`Contact sheets can only be built on macOS hosts, which is where the frame decoder runs`,{reason:`contact_sheet_unsupported_host`,hostPlatform:e,hint:`Run this command on the macOS host that recorded the clip, or read the video artifact itself.`})}async function pt(e){if(q(e.hostPlatform??process.platform),e.timesMs.length===0)throw new r(`COMMAND_FAILED`,`Contact sheet sampling requested no frames`,{reason:K,videoPath:e.videoPath});Q(e.signal);let t=await vt(e);Q(e.signal);let n;try{n=await ae(t,[`--input`,e.videoPath,`--output-dir`,e.scratchDir,`--times`,e.timesMs.join(`,`),`--max-width`,String(e.maxWidth)],{timeoutMs:9e4,env:ge(),allowFailure:!0,...e.signal===void 0?{}:{signal:e.signal}})}catch(t){X(t,e.videoPath,`Failed to run the frame decoder`)}if(n.exitCode!==0)throw new r(`COMMAND_FAILED`,`Failed to extract frames from the recording: ${_t(n.stderr)||`exit ${n.exitCode}`}`,{reason:G,videoPath:e.videoPath,exitCode:n.exitCode});let i=mt(n.stdout,e.videoPath,e.scratchDir,e.timesMs.length);if(i.frames.length===0)throw new r(`COMMAND_FAILED`,`The recording returned no decodable frames for a contact sheet`,{reason:K,videoPath:e.videoPath,skippedSampleCount:i.skippedSampleCount});return i}function mt(e,t,n,r){let i;try{i=JSON.parse(e)}catch(e){throw Y(t,`invalid manifest: ${String(e)}`)}let a=Z(i).frames;if(!Array.isArray(a))throw Y(t,`manifest has no frames array`);let o=Z(i).skipped;if(a.length>r)throw Y(t,`returned ${a.length} frames for ${r} requested samples`);let s=a.flatMap(e=>{let r=Z(e),i=ht(r.path),a=gt(r.actualTimeMs);if(i===void 0||a===void 0||a<0)throw Y(t,`frame entry is missing a path or presentation time`);let o=S.resolve(n,S.basename(i));return x.existsSync(o)?[{requestedTimeMs:gt(r.requestedTimeMs)??a,actualTimeMs:a,path:o}]:[]});return{frames:s.sort((e,t)=>e.actualTimeMs-t.actualTimeMs),skippedSampleCount:Math.max(Array.isArray(o)?o.length:0,r-s.length)}}function J(e,t,n){return new r(`COMMAND_FAILED`,e,{reason:G,videoPath:t},n)}function Y(e,t){return J(`Frame extraction returned an unreadable manifest: ${t}`,e)}function X(t,i,a){throw n(t)||t instanceof r&&t.code===`COMMAND_FAILED`&&t.details?.reason?t:J(`${a} for ${i}: ${e(t)}`,i,t)}function Z(e){return typeof e==`object`&&e?e:{}}function ht(e){return typeof e==`string`&&e!==``?e:void 0}function gt(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function _t(e){return(e.trim().split(`
2
2
  `).pop()??``).trim()}async function vt(e){try{return await ve({sourcePath:b(`recording-frames.swift`,se()),extraSourcePaths:[b(`RecordingExportSupport.swift`,se())],cacheName:`recording-frames`,timeoutMs:12e4})}catch(t){X(t,e.videoPath,`Could not build the frame decoder`)}}function Q(e){if(e?.aborted)throw t()}function yt(e,t){if(e===void 0||!Number.isFinite(e)||e<0)throw new r(`COMMAND_FAILED`,`Cannot plan a contact sheet: the video timeline of ${t} could not be read`,{reason:`contact_sheet_duration_unknown`,videoPath:t,hint:`Retry once the recording finished finalizing; a clip whose container is still being written has no readable duration.`});if(e<=250)return{durationMs:e,timesMs:e>0?[0,Math.round(e)]:[0]};let n=Math.min(48,Math.floor(e/250)+1),i=e/(n-1);return{durationMs:e,timesMs:Array.from({length:n},(e,t)=>Math.round(t*i))}}const bt=[360,320,280,240,200,160],xt=[255,255,255,255],St=[17,24,39,255],$=pe(2)+8;function Ct(e){let{cells:t}=e;if(t.length===0)throw new r(`COMMAND_FAILED`,`Contact sheet has no cells to render`);let n=Tt(t[0].image.height/Math.max(1,t[0].image.width),t.length,e),i=Ot(n.width,n.height,St);return t.forEach((e,t)=>{let r=t%n.columns,a=Math.floor(t/n.columns);wt(i,8+r*(n.cellWidth+8),8+a*($+n.cellHeight+8),e,n.cellWidth,n.cellHeight)}),{bytes:me(i.data,n.width,n.height,4),width:n.width,height:n.height,cellWidth:n.cellWidth}}function wt(e,t,n,r,i,a){fe(e,{x:t+4,y:n+4,text:jt(r.timeMs),color:xt,scale:2}),kt(e,le(At(r.image),i,a),t,n+$)}function Tt(e,t,n){let i=Et(e,t,n.maxPixels);if(i)return i;let a=Dt(e,t,160);throw new r(`COMMAND_FAILED`,`Contact sheet would be ${a.width*a.height} pixels, above the configured maxImagePixels limit of ${n.maxPixels}`,{reason:`contact_sheet_pixel_budget_exceeded`,cellCount:n.cells.length,maxPixels:n.maxPixels,hint:`Shorten the recording or raise the command policy maxImagePixels limit.`})}function Et(e,t,n){for(let r of bt){let i=Dt(e,t,r);if(i.width*i.height<=n)return i}}function Dt(e,t,n){let r=Math.min(4,t),i=Math.ceil(t/r),a=Math.max(1,Math.round(n*e));return{columns:r,cellWidth:n,cellHeight:a,width:16+r*n+(r-1)*8,height:16+i*($+a)+(i-1)*8}}function Ot(e,t,n){let r=new _.PNG({width:e,height:t});for(let i=0;i<t;i+=1)for(let t=0;t<e;t+=1)v(r,t,i,n);return r}function kt(e,t,n,r){for(let i=0;i<t.height;i+=1)for(let a=0;a<t.width;a+=1){let o=(i*t.width+a)*4;v(e,n+a,r+i,[t.data[o],t.data[o+1],t.data[o+2],t.data[o+3]])}}function At(e){let t=new _.PNG({width:e.width,height:e.height});return Buffer.from(e.data.buffer,e.data.byteOffset,e.data.byteLength).copy(t.data),t}function jt(e){let t=Math.floor(e/1e3),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=Math.floor(e%1e3);return`${[n,r,i].map(e=>String(e).padStart(2,`0`)).join(`:`)}.${String(a).padStart(3,`0`)}`}function Mt(e,t){if(e.width!==t.width||e.height!==t.height)return{status:`dimension_mismatch`};let n=e.width*e.height;if(n===0)return{status:`compared`,changedPixelRatio:0};if(e.data.length!==t.data.length)return{status:`dimension_mismatch`};let r=0;for(let n=0;n+3<e.data.length;n+=4)(e.data[n]!==t.data[n]||e.data[n+1]!==t.data[n+1]||e.data[n+2]!==t.data[n+2])&&(r+=1);return{status:`compared`,changedPixelRatio:r/n}}function Nt(e,t=.02,n=24){let r=[],i;for(let n of e){let e=i?Ft(i,n.image):1;e<t||(r.push({timeMs:n.timeMs,changedPixelRatio:e,image:n.image}),i=n.image)}Pt(r,e);let a=r.length>n?It(r,n):r;return{cells:a,keptCellCount:r.length,thinned:a.length<r.length}}function Pt(e,t){let n=t.at(-1);if(!n)return;let r=e.at(-1);!r||r.timeMs===n.timeMs||e.push({timeMs:n.timeMs,changedPixelRatio:Ft(r.image,n.image),image:n.image})}function Ft(e,t){let n=Mt(e,t);return n.status===`compared`?n.changedPixelRatio:1}function It(e,t){if(t<=1)return[e.at(-1)];let n=(e.length-1)/(t-1);return Array.from({length:t},(t,r)=>e[Math.round(r*n)])}async function Lt(e){q(e.hostPlatform??process.platform);let t=S.resolve(e.videoPath),n=S.resolve(e.outputPath??y(t));Bt(t,n);let i=await _e(t);if(i!==`mp4`)throw new r(`INVALID_ARGS`,i===`webm`?`Contact sheets need an MP4 recording; ${t} is WebM, whose frames this decoder does not read`:`Contact sheets need an MP4 recording; ${t} is not a readable MP4`,{reason:`contact_sheet_container_unsupported`,videoPath:t,container:i??`unknown`,hint:`Re-record on a backend that exports MP4, or pass the MP4 artifact the recording produced.`});let a=yt(he(t),t),o=x.mkdtempSync(S.join(ye.tmpdir(),`agent-device-contact-sheet-`));try{let r=await pt({videoPath:t,scratchDir:o,timesMs:a.timesMs,maxWidth:360,hostPlatform:e.hostPlatform??process.platform,...e.signal===void 0?{}:{signal:e.signal}}),i=await Rt(r.frames,e.maxPixels);zt(e.signal);let s=Nt(i,e.changedPixelThreshold??.02),c=Ct({cells:s.cells,maxPixels:e.maxPixels});return Gt(n,c.bytes),{path:n,videoPath:t,durationMs:a.durationMs,width:c.width,height:c.height,sampledFrameCount:a.timesMs.length,decodedFrameCount:r.frames.length,skippedSampleCount:r.skippedSampleCount,changedPixelThreshold:e.changedPixelThreshold??.02,cells:s.cells.map(Ut),...Wt(s,r)}}finally{x.rmSync(o,{recursive:!0,force:!0})}}async function Rt(e,t){let n=[];for(let i of e){let e=await de(i.path);if(e.width>360)throw new r(`COMMAND_FAILED`,`Frame extraction returned a ${e.width}px-wide frame when the sheet asked for 360px cells`,{reason:G,framePath:i.path,frameWidth:e.width,frameWidthLimit:360});if(e.width*e.height>t)throw new r(`COMMAND_FAILED`,`Frame extraction returned a ${e.width}x${e.height} frame, above the ${t}-pixel budget for the whole sheet`,{reason:G,framePath:i.path,framePixels:e.width*e.height,maxPixels:t});let a=await ue(x.readFileSync(i.path),`recording frame`);n.push({timeMs:i.actualTimeMs,image:a})}return n}function zt(e){if(e?.aborted)throw t()}function Bt(e,t){if(Vt(e,t)??t===e)throw new r(`INVALID_ARGS`,`A contact sheet cannot be written over the recording it describes: ${t}`,{reason:`contact_sheet_output_collides_with_input`,videoPath:e,outputPath:t,hint:`Choose a different --out path, or omit it to write beside the recording.`})}function Vt(e,t){let n=Ht(e),r=Ht(t);if(n!==void 0&&r!==void 0)return n.dev===r.dev&&n.ino===r.ino}function Ht(e){try{return x.statSync(e)}catch{return}}function Ut(e){return{timeMs:e.timeMs,changedPixelRatio:e.changedPixelRatio}}function Wt(e,t){let n=[];return t.skippedSampleCount>0&&n.push(`${t.skippedSampleCount} sample times returned no frame, so the sheet covers less of the recording than it asked for`),e.thinned&&n.push(`${e.keptCellCount} changes were found and 24 cells are printed, so the sheet thins evenly across the recording instead of showing every change`),n.length===0?{}:{warning:n.join(`; `)}}function Gt(e,t){try{x.mkdirSync(S.dirname(e),{recursive:!0}),ie({destination:e,contents:t})}catch(t){throw new r(`COMMAND_FAILED`,`Failed to write the contact sheet to ${e}: ${t instanceof Error?t.message:String(t)}`,{reason:`contact_sheet_output_write_failed`,outputPath:e})}}const Kt=async(e,t)=>{if(!t.video)throw new r(`INVALID_ARGS`,`record contact-sheet requires a recording to read`);Jt(t.changedPixelThreshold);let n=await d(e,t.video,{usage:`record contact-sheet`,field:`video`}),i;try{let r=qt(t,t.video,n.path);i=await p(e,r,{field:`path`,ext:`.png`,artifactType:`screen-recording-contact-sheet`});let a=await Lt({videoPath:n.path,outputPath:i.path,maxPixels:e.policy.maxImagePixels,...t.changedPixelThreshold===void 0?{}:{changedPixelThreshold:t.changedPixelThreshold},signal:t.signal??e.signal}),o=await i.publish();return{...a,path:Yt(a.path,o),...o?{artifact:o}:{}}}catch(e){throw await i?.cleanup?.(),e}finally{await n.cleanup?.()}};function qt(e,t,n){if(e.out)return e.out;if(t.kind===`path`)return{kind:`path`,path:S.resolve(y(t.path||n))};throw new r(`INVALID_ARGS`,`record contact-sheet needs an output path when the recording is an uploaded artifact`,{hint:"Pass --out <sheet.png> (CLI) or `out` (Node) to name where the sheet is written."})}function Jt(e){if(e!==void 0&&(!Number.isFinite(e)||e<0||e>1))throw new r(`INVALID_ARGS`,`record contact-sheet needs a changedPixelThreshold between 0 and 1, got ${e}`,{reason:`contact_sheet_threshold_invalid`,changedPixelThreshold:e,hint:`Omit it to use the calibrated default, or pass a share of the frame between 0 and 1.`})}function Yt(e,t){return t?t.kind===`localPath`?t.path:t.clientPath??e:e}const Xt=async(e,t)=>{let n=tn(t.action,`record`),i=n===`start`?e.backend.startRecording:e.backend.stopRecording;if(!i)throw new r(`UNSUPPORTED_OPERATION`,`record ${n} is not supported by this backend`);let a=t.out?await p(e,t.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let r=Qt(t,a?.path);return nn(n,await i.call(e.backend,m(e,t),r),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}},Zt=async(e,t)=>{let n=tn(t.action,`trace`),i=n===`start`?e.backend.startTrace:e.backend.stopTrace;if(!i)throw new r(`UNSUPPORTED_OPERATION`,`trace ${n} is not supported by this backend`);let a=t.out?await p(e,t.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let r=a?.path?{outPath:a.path}:{};return rn(n,await i.call(e.backend,m(e,t),r),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}};function Qt(e,t){let n={};t&&(n.outPath=t);let r=$t(e.fps);r!==void 0&&(n.fps=r);let i=en(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function $t(e){return e===void 0?void 0:s(e,`fps`,1,60)}function en(e){if(e===void 0)return;let t=i(e);if(t===void 0)throw new r(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return t}function tn(e,t){if(e===`start`||e===`stop`)return e;throw new r(`INVALID_ARGS`,`${t} action must be start or stop`)}function nn(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...an(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function rn(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...an(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function an(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...g(e===`start`?r.startMessage:r.stopMessage)}}const on={record:Xt,trace:Zt,contactSheet:Kt},sn=async(e,t={})=>{if(!e.backend.pressBack)throw new r(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let n=t.mode??`in-app`;if(n!==`in-app`&&n!==`system`)throw new r(`INVALID_ARGS`,`system.back mode must be in-app or system`);let i=await e.backend.pressBack(m(e,t),{mode:n}),a=u(i);return{kind:`systemBack`,mode:n,...a?{backendResult:a}:{},...g(`Back`)}},cn=async(e,t={})=>{if(!e.backend.pressHome)throw new r(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let n=await e.backend.pressHome(m(e,t)),i=u(n);return{kind:`systemHome`,...i?{backendResult:i}:{},...g(`Home`)}},ln=async(e,t)=>{if(!e.backend.pressTvRemote)throw new r(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let n=oe(t.button),i=t.durationMs===void 0?void 0:s(t.durationMs,`durationMs`,0,1e4),a=await e.backend.pressTvRemote(m(e,t),{button:n,...i===void 0?{}:{durationMs:i}}),o=u(a);return{kind:`tvRemotePressed`,button:n,...i===void 0?{}:{durationMs:i},...o?{backendResult:o}:{},...g(`Pressed TV remote ${n}`)}},un=async(e,t)=>{if(!e.backend.setOrientation)throw new r(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let n=gn(t.orientation),i=await e.backend.setOrientation(m(e,t),n),a=u(i);return{kind:`systemOrientationSet`,orientation:n,...a?{backendResult:a}:{},...g(`Rotated to ${n}`)}},dn=async(e,t={})=>{if(!e.backend.setKeyboard)throw new r(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let n=t.action??`status`;if(!ce(n))throw new r(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let i=await e.backend.setKeyboard(m(e,t),{action:n}),a=u(i),o=Tn(i)?i:{};return n===`enter`||n===`return`?vn(o,a):n===`dismiss`?yn(n,o,a):xn(n,o,a)},fn=async(e,t)=>{if(t.action===`read`){if(!e.backend.getClipboard)throw new r(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let n=await e.backend.getClipboard(m(e,t));return{kind:`clipboardText`,action:`read`,text:typeof n==`string`?n:n.text}}if(t.action!==`write`)throw new r(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new r(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof t.text!=`string`)throw new r(`INVALID_ARGS`,`system.clipboard write requires text`);let n=await e.backend.setClipboard(m(e,t),t.text),i=u(n);return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(t.text).length,...i?{backendResult:i}:{},...g(`Clipboard updated`)}},pn=async(e,t={})=>{if(!e.backend.openSettings)throw new r(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let n=C(t.target,`target`),i=await e.backend.openSettings(m(e,t),n),a=u(i);return{kind:`settingsOpened`,...n?{target:n}:{},...a?{backendResult:a}:{},...g(n?`Opened settings: ${n}`:`Opened settings`)}},mn=async(e,t={})=>{if(!e.backend.handleAlert)throw new r(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let n=t.action??`get`;if(n!==`get`&&n!==`accept`&&n!==`dismiss`&&n!==`wait`)throw new r(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let i=t.timeoutMs===void 0?void 0:s(t.timeoutMs,`timeoutMs`,0,12e4);return _n(n,await e.backend.handleAlert(m(e,t),n,{timeoutMs:i}))},hn=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new r(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let n=await e.backend.openAppSwitcher(m(e,t)),i=u(n);return{kind:`appSwitcherOpened`,...i?{backendResult:i}:{},...g(`Opened app switcher`)}};function gn(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new r(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function _n(e,t){return e===`get`?Sn(t):e===`wait`?Cn(t):wn(e,t)}function vn(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...g(`Keyboard enter pressed`)}}function yn(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...g(bn(t))}}function bn(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function xn(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function Sn(e){if(e.kind!==`alertStatus`)throw new r(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function Cn(e){if(e.kind!==`alertWait`)throw new r(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:e.alert,...e.waitedMs===void 0?{}:{waitedMs:e.waitedMs},...e.timedOut===void 0?{}:{timedOut:e.timedOut},...g(e.alert?`Alert visible`:`Alert wait timed out`)}}function wn(e,t){if(t.kind!==`alertHandled`)throw new r(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...g(t.handled?`Alert ${e}ed`:`No alert handled`)}}function Tn(e){return!!(e&&typeof e==`object`)}const En={back:sn,home:cn,orientation:un,keyboard:dn,clipboard:fn,settings:pn,alert:mn,appSwitcher:hn,tvRemote:ln};function Dn(e){return{capture:ee(e),selectors:f(e),interactions:l(e),system:h(En,e),apps:Je(e),admin:h(qe,e),recording:h(on,e),observability:h(ft,e)}}function On(e){let t=a(e);return{...t,...Dn(t)}}export{On as createAgentDevice,te as createMemorySessionStore,c as localCommandPolicy,o as restrictedCommandPolicy};
@@ -1 +1 @@
1
- import"./sdk-batch.js";function e(e){return!!(e&&e.width>0&&e.height>0)}function t(e,t,n){return Number.isFinite(e)?Math.max(t,Math.min(n,e)):t}function n(e){return e.width*e.height}function r(e){let t=e[0];if(t===void 0)throw Error(`unionRects requires at least one rect`);let n=t.x,r=t.y,i=t.x+t.width,a=t.y+t.height;for(let t of e.slice(1))n=Math.min(n,t.x),r=Math.min(r,t.y),i=Math.max(i,t.x+t.width),a=Math.max(a,t.y+t.height);return{x:n,y:r,width:i-n,height:a-r}}const i=[255,59,48,255],a=[255,214,10,255],o=[0,0,0,255],s={e:[`01110`,`10000`,`11110`,`10000`,`10000`,`10001`,`01110`],0:[`01110`,`10001`,`10011`,`10101`,`11001`,`10001`,`01110`],1:[`00100`,`01100`,`00100`,`00100`,`00100`,`00100`,`01110`],2:[`01110`,`10001`,`00001`,`00010`,`00100`,`01000`,`11111`],3:[`11110`,`00001`,`00001`,`01110`,`00001`,`00001`,`11110`],4:[`00010`,`00110`,`01010`,`10010`,`11111`,`00010`,`00010`],5:[`11111`,`10000`,`10000`,`11110`,`00001`,`00001`,`11110`],6:[`01110`,`10000`,`10000`,`11110`,`10001`,`10001`,`01110`],7:[`11111`,`00001`,`00010`,`00100`,`01000`,`01000`,`01000`],8:[`01110`,`10001`,`10001`,`01110`,`10001`,`10001`,`01110`],9:[`01110`,`10001`,`10001`,`01111`,`00001`,`00001`,`01110`],":":[`00000`,`00100`,`00100`,`00000`,`00100`,`00100`,`00000`],".":[`00000`,`00000`,`00000`,`00000`,`00000`,`00110`,`00110`]};function c(e,t){m(e,t.overlayRect,i,2),h(e,t.overlayRect,t.ref)}function l(e){return e===``?0:e.length*6-1}function u(e=1){return 7*e}function d(e,t){let n=t.scale??1,r=t.x;for(let i of t.text.toLowerCase()){let a=s[i];a&&f(e,a,r,t.y,n,t.color),r+=6*n}}function f(e,t,n,r,i,a){for(let o=0;o<t.length;o+=1)for(let s=0;s<t[o].length;s+=1)t[o][s]===`1`&&g(e,n+s*i,r+o*i,i,i,a)}function p(e,t,n,r){if(t<0||n<0||t>=e.width||n>=e.height)return;let i=(e.width*n+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function m(e,t,n,r){for(let i=0;i<r;i+=1)_(e,t.x,t.x+t.width-1,t.y+i,n),_(e,t.x,t.x+t.width-1,t.y+t.height-1-i,n),v(e,t.x+i,t.y,t.y+t.height-1,n),v(e,t.x+t.width-1-i,t.y,t.y+t.height-1,n)}function h(e,n,r){let i=6+l(r),s=t(n.x,0,Math.max(0,e.width-i)),c=n.y-11-2,u=c>=0?c:t(n.y+2,0,Math.max(0,e.height-11));g(e,s,u,i,11,a),d(e,{x:s+3,y:u+2,text:r,color:o})}function g(e,t,n,r,i,a){for(let o=0;o<i;o+=1)for(let i=0;i<r;i+=1)p(e,t+i,n+o,a)}function _(e,t,n,r,i){for(let a=t;a<=n;a+=1)p(e,a,r,i)}function v(e,t,n,r,i){for(let a=n;a<=r;a+=1)p(e,t,a,i)}export{t as a,r as c,p as i,d as n,e as o,u as r,n as s,c as t};
1
+ import"./sdk-batch.js";function e(e){return!!(e&&e.width>0&&e.height>0)}function t(e,t,n){return Number.isFinite(e)?Math.max(t,Math.min(n,e)):t}function n(e){return e.width*e.height}const r=[255,59,48,255],i=[255,214,10,255],a=[0,0,0,255],o={e:[`01110`,`10000`,`11110`,`10000`,`10000`,`10001`,`01110`],0:[`01110`,`10001`,`10011`,`10101`,`11001`,`10001`,`01110`],1:[`00100`,`01100`,`00100`,`00100`,`00100`,`00100`,`01110`],2:[`01110`,`10001`,`00001`,`00010`,`00100`,`01000`,`11111`],3:[`11110`,`00001`,`00001`,`01110`,`00001`,`00001`,`11110`],4:[`00010`,`00110`,`01010`,`10010`,`11111`,`00010`,`00010`],5:[`11111`,`10000`,`10000`,`11110`,`00001`,`00001`,`11110`],6:[`01110`,`10000`,`10000`,`11110`,`10001`,`10001`,`01110`],7:[`11111`,`00001`,`00010`,`00100`,`01000`,`01000`,`01000`],8:[`01110`,`10001`,`10001`,`01110`,`10001`,`10001`,`01110`],9:[`01110`,`10001`,`10001`,`01111`,`00001`,`00001`,`01110`],":":[`00000`,`00100`,`00100`,`00000`,`00100`,`00100`,`00000`],".":[`00000`,`00000`,`00000`,`00000`,`00000`,`00110`,`00110`]};function s(e,t){p(e,t.overlayRect,r,2),m(e,t.overlayRect,t.ref)}function c(e){return e===``?0:e.length*6-1}function l(e=1){return 7*e}function u(e,t){let n=t.scale??1,r=t.x;for(let i of t.text.toLowerCase()){let a=o[i];a&&d(e,a,r,t.y,n,t.color),r+=6*n}}function d(e,t,n,r,i,a){for(let o=0;o<t.length;o+=1)for(let s=0;s<t[o].length;s+=1)t[o][s]===`1`&&h(e,n+s*i,r+o*i,i,i,a)}function f(e,t,n,r){if(t<0||n<0||t>=e.width||n>=e.height)return;let i=(e.width*n+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function p(e,t,n,r){for(let i=0;i<r;i+=1)g(e,t.x,t.x+t.width-1,t.y+i,n),g(e,t.x,t.x+t.width-1,t.y+t.height-1-i,n),_(e,t.x+i,t.y,t.y+t.height-1,n),_(e,t.x+t.width-1-i,t.y,t.y+t.height-1,n)}function m(e,n,r){let o=6+c(r),s=t(n.x,0,Math.max(0,e.width-o)),l=n.y-11-2,d=l>=0?l:t(n.y+2,0,Math.max(0,e.height-11));h(e,s,d,o,11,i),u(e,{x:s+3,y:d+2,text:r,color:a})}function h(e,t,n,r,i,a){for(let o=0;o<i;o+=1)for(let i=0;i<r;i+=1)f(e,t+i,n+o,a)}function g(e,t,n,r,i){for(let a=t;a<=n;a+=1)f(e,a,r,i)}function _(e,t,n,r,i){for(let a=n;a<=r;a+=1)f(e,t,a,i)}export{t as a,f as i,u as n,e as o,l as r,n as s,s as t};
@@ -1 +1 @@
1
- import{P as e,b as t,s as n}from"./sdk-contracts.js";import{f as r,l as i,r as a,u as o}from"./capture.js";import{O as s,p as c,w as l}from"./sdk-device.js";import{$r as u,Ir as d,It as f,Lr as p,S as m,Yr as h,b as g,ei as _,f as ee,hn as te,jr as v,l as ne,zr as y}from"./sdk-batch.js";import{T as b,d as re}from"./runtime.js";import{t as ie}from"./overlay.js";import{t as ae}from"./session-paths.js";import{t as x}from"./snapshot-state.js";import{c as oe,f as se,m as S,o as ce,u as C}from"./session-snapshot.js";import{t as le}from"./selector-pipeline-policy.js";import{i as ue,o as w,r as T}from"./png-worker-client.js";import{t as de}from"./png-size.js";import{r as fe,t as pe}from"./screenshot-density.js";import{a as E,c as me,o as D,s as O,t as he}from"./screenshot-overlay-draw.js";import{a as ge,i as _e,n as ve,t as ye}from"./session-runtime-admission.js";import{promises as k}from"node:fs";import A from"node:os";import j from"node:path";const M=ne(ee),N=Ie(M);function P(e){return I(e)?.route??`generic`}function F(e){return I(e)?.sessionKind}function be(e){return I(e)?.leaseAdmissionExempt===!0}function xe(e){return I(e)?.appLease===`allowed`}function Se(e){return I(e)?.selectorValidationExempt!==!0}function Ce(e){return I(e)?.sessionExecutionLockExempt!==!0}function we(e){return I(e)?.replayScopedAction===!0}function Te(e){return I(e)?.allowInvalidRecording!==!0}function Ee(e){return I(e)?.saveScriptFlagOwner===!0}function De(){return M.filter(e=>e.saveScriptFlagOwner===!0).map(e=>e.command).sort()}function Oe(e){return I(e)?.lockPolicySelectorOverride===!0}function ke(e){return I(e)?.androidBlockingDialogGuard===!0}function Ae(e){if(e.command===`human_control`||e.command===`lease_heartbeat`)return!1;let t=m(e);return t===void 0?F(e.command)!==`observability`&&g(e.command)!==`observe`:t!==`observes-app`}function je(e){return I(e.command)?.preferExplicitDeviceOverExistingSession===!0}function Me(e){let t=I(e.command)?.allowSessionlessDefaultDevice;return typeof t==`function`&&t(e)}function Ne(e){return I(e.command)?.sessionlessLeaseAdmissionExemption?.(e)}function Pe(e){let t=I(e.command)?.refFrameEffect;return typeof t==`function`?t(e):t}function Fe(e,t){return t.hasExistingSession?je(e)&&t.hasExplicitDeviceIdentity?`explicit-device`:`existing-session`:Le(e)?`skip`:t.hasDeviceSelectionInput?`explicit-device`:Me(e)?`sessionless-default-device`:`skip`}function I(e){return N.descriptorsByCommand.get(e)}function Ie(e){let t=new Map;for(let n of e){if(t.has(n.command))throw Error(`Duplicate daemon command descriptor: ${n.command}`);t.set(n.command,n)}return{descriptorsByCommand:t}}function Le(e){let t=I(e.command);if(t?.route===`lease`)return!0;let n=t?.skipSessionlessProviderDevice;return typeof n==`function`&&n(e)}const L=a.pendingPixelIdentityEvidence,Re=[{target:`ios-simulator`,status:`accepted`},{target:`android-emulator`,status:`accepted`},{target:`android-device`,status:`rejected`,rejectionReason:L},{target:`macos-app-window`,status:`rejected`,rejectionReason:L},{target:`ios-physical`,status:`rejected`,rejectionReason:L},{target:`macos-helper`,status:`rejected`,rejectionReason:L},{target:`web`,status:`rejected`,rejectionReason:L},{target:`linux`,status:`rejected`,rejectionReason:L},{target:`tvos`,status:`rejected`,rejectionReason:L},{target:`harmonyos`,status:`rejected`,rejectionReason:L},{target:`vega`,status:`rejected`,rejectionReason:L}];function ze(e,t){switch(e.platform){case`apple`:return Be(e,t);case`android`:return e.kind===`device`?`android-device`:`android-emulator`;case`harmonyos`:return`harmonyos`;case`vega`:return`vega`;case`linux`:return`linux`;case`web`:return`web`}}function Be(e,t){let n=s(e);switch(n){case`ios`:case`ipados`:return e.kind===`device`?`ios-physical`:`ios-simulator`;case`tvos`:return`tvos`;case`macos`:return Ve(t);case`watchos`:case`visionos`:throw R(n)}}function Ve(e){return(e??`app`)===`app`?`macos-app-window`:`macos-helper`}function R(t,n){return new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on is not accepted on ${t} targets`,{reason:a.targetNotAccepted,...n?{rejectionReason:n}:{}})}function He(t){if(t.overlayRefs||t.fullscreen)throw new e(`INVALID_ARGS`,`--crop-on cannot be combined with --overlay-refs or --fullscreen: both move the captured frame away from the snapshot viewport the crop is measured against`,{reason:a.frameMismatch});try{te(t.cropOn)}catch{throw new e(`INVALID_ARGS`,`screenshot --crop-on requires a valid selector expression`,{reason:a.selectorInvalid})}let n=ze(t.device,t.surface),r=Re.find(e=>e.target===n);if(!r||r.status===`rejected`)throw R(n,r?.status===`rejected`?r.rejectionReason:void 0)}async function Ue(t,n){if(!We(n))throw new e(`INVALID_ARGS`,`Screenshot crop box must be positive integer pixel offsets`);let r=await T(await k.readFile(t),n,`screenshot`);r!==null&&await k.writeFile(t,r)}function We(e){return Number.isInteger(e.x)&&e.x>=0&&Number.isInteger(e.y)&&e.y>=0&&Number.isInteger(e.width)&&e.width>0&&Number.isInteger(e.height)&&e.height>0}function Ge(t){switch(t){case`android`:return`device-pixels`;case`xctest`:case`macos-helper`:return`viewport-points`;default:throw new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on does not accept snapshot backend "${t??`unknown`}"`,{reason:a.targetNotAccepted})}}function z(e,t,n,r,i){if(e===`device-pixels`||t===null)return Ye(n);let a=r/t.width,o=i/t.height;return{x:Math.round((n.x-t.x)*a),y:Math.round((n.y-t.y)*o),width:Math.round(n.width*a),height:Math.round(n.height*o)}}function Ke(e,t,n){let r=Math.max(e.x,0),i=Math.max(e.y,0),a=Math.min(e.x+e.width,t),o=Math.min(e.y+e.height,n);return a<=r||o<=i?null:{x:r,y:i,width:a-r,height:o-i}}function B(e){let t=null;for(let n of e)!v(n)||!h(n.rect)||(!t||u(n.rect)>u(t))&&(t=n.rect);return t||qe(e.filter(e=>h(e.rect)&&!Je(e)))}function qe(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)h(a.rect)&&(t=Math.min(t,a.rect.x),n=Math.min(n,a.rect.y),r=Math.max(r,a.rect.x+a.rect.width),i=Math.max(i,a.rect.y+a.rect.height));return!Number.isFinite(t)||!Number.isFinite(n)||r<=t||i<=n?null:{x:t,y:n,width:r-t,height:i-n}}function Je(e){return p(e.type??``)===`image`&&!d(e.label)}function Ye(e){return{x:Math.round(e.x),y:Math.round(e.y),width:Math.round(e.width),height:Math.round(e.height)}}const Xe=`${a.partialIntersection}: the selector frame extends past the captured image; the crop was clipped to the image frame`;function V(e){return e?.partialIntersection?[Xe]:[]}async function Ze(t){let{device:n,session:r,surface:i,cropOn:o,screenshotPath:s,logPath:c,dispatchContext:l}=t,u={snapshotInteractiveOnly:!1},d=await C({device:n,session:r,flags:u,logPath:c,snapshotScope:void 0,captureData:async()=>await t.captureSnapshot({options:{appBundleId:l.appBundleId,interactiveOnly:!1,includeRects:!0,surface:i},execution:S(l)})}),f=x(d,u);if(f.snapshotQuality?.state===`sparse`)throw new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was sparse and cannot be read as the screen`,{reason:a.captureUnreadable});let p=await Qe(f.nodes,o,f.truncated,n),m=await de(s),h=z(Ge(f.backend),B(f.nodes),p.rect,m.width,m.height),g=Ke(h,m.width,m.height);if(g===null)throw new e(`COMMAND_FAILED`,`the frame resolved by --crop-on occupies no pixel of the capture`,{reason:a.emptyIntersection});let _=g.x!==h.x||g.y!==h.y||g.width<h.width||g.height<h.height;return await Ue(s,g),{partialIntersection:_}}async function Qe(t,n,r,i){let o=await re(le.cropTarget,t,n,{platform:l(i)});if(o.kind===`ambiguous`)throw new e(`COMMAND_FAILED`,`--crop-on matched ${o.matchedNodes.length} nodes and must resolve to one`,{reason:a.targetAmbiguous,candidates:o.matchedNodes.map(e=>e.label??e.ref),matches:o.matchedNodes.length});if(o.kind===`none`)throw r?new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was truncated, so a missing match is not proven`,{reason:a.captureIncomplete}):new e(`COMMAND_FAILED`,`--crop-on matched no node: ${n}`,{reason:a.targetNotFound,hint:`find ${n} list`});return o.node}const $e=[`scroll`,`list`,`recyclerview`,`edittext`,`textfield`];function et(e,t,n){if(e.backend!==`android`||!n.hittable||!D(n.rect)||v(n))return!1;let r=p(n.type??``);return!($e.some(e=>r.includes(e))||t&&O(n.rect)>O(t)*.25)}function tt(e,t,n,r){return!e.rect||e.hittable!==!0||n(e)||r(e)?null:nt(e,t,r)}function nt(e,t,n){let r=e.rect,i=rt(e,t,n);if(!i)return null;let a=i.y-r.y,o=r.y+r.height-(i.y+i.height);if(a<0||o<0||Math.abs(o-a)<16)return null;let s=Math.min(a,o),c=Math.round(i.y-s),l=Math.round(i.height+s*2);return l<=0||l>=r.height?null:{x:r.x,y:c,width:r.width,height:l}}function rt(e,t,n){let r=e.rect,i=new Map(t.map(e=>[e.index,e])),a=t.filter(t=>t.ref!==e.ref&&at(t,e,i)&&it(t,n)&&D(t.rect)&&_(r,t.rect)).map(e=>e.rect);return a.length<2?null:me(a)}function it(e,t){let n=p(e.type??``);return n.includes(`text`)||n.includes(`image`)&&t(e)}function at(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n.get(r.parentIndex);if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}const ot=[`button`,`link`,`menu`,`tab`,`textfield`,`searchfield`,`securetextfield`,`checkbox`,`radio`,`switch`,`cell`];async function H(e){let t=await k.readFile(e.screenshotPath),n=await ue(t,`screenshot`),r=st(e.snapshot,n.width,n.height,{maxRefs:e.maxRefs});for(let e of r)he(n,e);return await k.writeFile(e.screenshotPath,await w(n)),r}function st(e,n,r,i={}){let a=B(e.nodes),o=new Map;for(let t of e.nodes){if(!ut(e,a,t))continue;let i=dt(e.nodes,t);if(!i?.rect||!D(i.rect))continue;let s=ft(t,i,e.nodes),c=pt(t,i,s),l=U(e,a,lt(e,i,e.nodes),n,r);if(!D(l))continue;let u=o.get(i.ref);(!u||c>u.score)&&o.set(i.ref,{ref:i.ref,label:s,rect:i.rect,overlayRect:l,score:c})}return ct(e,a,o,n,r),mt([...o.values()]).sort(wt).slice(0,i.maxRefs??24).sort(Y).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:t(e.overlayRect)}))}function ct(e,t,n,r,i){let a=ie(e.nodes).primaryAction;if(!a?.ref||!a.rect||!D(a.rect))return;let o=U(e,t,a.rect,r,i);if(!D(o))return;let s={ref:a.ref,label:a.label,rect:a.rect,overlayRect:o,score:100},c=n.get(a.ref);n.set(a.ref,c?{...c,score:Math.max(c.score,s.score)}:s)}function lt(e,t,n){return e.backend===`android`?tt(t,n,W,e=>!!J(e))??t.rect:t.rect}function ut(e,t,n){let r=[n.label,n.value].some(K)||q(n.identifier);return et(e,t,n)?!0:W(n)?r:r&&ht(n)}function dt(e,t){return[G(t)?t:null,y(e,t,G),t.hittable?t:null,y(e,t,e=>e.hittable===!0)].find(gt)??null}function ft(e,t,n){let r=J(e);return e.ref!==t.ref&&r?r:_t(t,n)||J(t)}function pt(e,t,n){let r=0;return e.ref===t.ref&&(r+=4),t.hittable&&(r+=3),W(t)&&(r+=3),W(e)&&(r+=2),n&&(r+=2),q(t.identifier)&&(r+=1),d(t.value)&&(r+=1),r}function mt(e){let t=[];for(let n of e.sort((e,t)=>O(e.overlayRect)-O(t.overlayRect))){let e=t.findIndex(e=>e.label!==void 0&&e.label===n.label&&(_(e.overlayRect,n.overlayRect)||_(n.overlayRect,e.overlayRect)));if(e===-1){t.push(n);continue}O(n.overlayRect)<O(t[e].overlayRect)&&(t[e]=n)}return t}function U(e,t,n,r,i){return Ct(z(e.backend===`android`?`device-pixels`:`viewport-points`,t,n,r,i),r,i)}function W(e){let t=[e.type,e.role,e.subrole].map(e=>p(e??``)).join(` `);return ot.some(e=>t.includes(e))}function G(e){return W(e)&&!v(e)}function ht(e){let t=p(e.type??``);return t.includes(`statictext`)||t.includes(`image`)||t.includes(`text`)||t.includes(`other`)}function gt(e){return!!(e?.rect&&D(e.rect)&&!v(e))}function K(e){return d(e)?!bt(e):!1}function q(e){return typeof e!=`string`||!K(e)?!1:!xt(e)}function J(e){let t=[e.label,e.value].find(K);if(t)return t.trim();if(q(e.identifier))return e.identifier.trim()}function _t(e,t){let n=null;for(let r of t){if(r.ref===e.ref||!vt(r,e,t))continue;let i=J(r);if(!i)continue;let a=yt(r);(!n||a>n.score)&&(n={label:i,score:a})}return n?.label}function vt(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n[r.parentIndex];if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}function yt(e){let t=0;return p(e.type??``).includes(`text`)&&(t+=2),K(e.label)&&(t+=2),K(e.value)&&(t+=1),t}function bt(e){let t=e?.trim().toLowerCase();return t===`toolbar`||t===`window`||t===`application`||t?.startsWith(`vertical scroll bar`)===!0}function xt(e){return/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(e.trim())}function St(e,t){return Number.parseInt(e.replace(/^\D+/,``),10)-Number.parseInt(t.replace(/^\D+/,``),10)}function Ct(e,t,n){let r=E(e.x,0,Math.max(0,t-1)),i=E(e.y,0,Math.max(0,n-1)),a=Math.max(1,t-r),o=Math.max(1,n-i);return{x:r,y:i,width:E(e.width,1,a),height:E(e.height,1,o)}}function Y(e,t){let n=e.overlayRect.y-t.overlayRect.y;if(n!==0)return n;let r=e.overlayRect.x-t.overlayRect.x;return r===0?St(e.ref,t.ref):r}function wt(e,t){return t.score===e.score?Y(e,t):t.score-e.score}async function X(e){let t=f({overlayRefs:e.overlayRefs,cropOn:e.cropOn!==void 0}),n=await ye({device:e.device,plan:t,inspectFacts:e.inspectFacts});return n.admitted?{ok:!0,runtime:await Tt(e.bindDevice,n)}:{ok:!1,response:Dt(t.kind,n.operation,n.fact)}}async function Tt(e,t){let n=ve(e),{device:r,plan:i}=ge(t);switch(i.kind){case`capture`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e)})}case`capture-with-overlay-refs`:case`capture-with-crop-on`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e),captureSnapshot:Et(e)})}}}function Z(e){return async t=>await e.operations.captureScreenshot(t)}function Et(e){return async t=>await e.operations.captureSnapshot(t)}function Dt(e,t,r){return t===`captureScreenshot`?_e(`screenshot`,r):e===`capture-with-crop-on`?n(`UNSUPPORTED_OPERATION`,`--crop-on crops the capture to a selector frame using a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --crop-on.`}):n(`UNSUPPORTED_OPERATION`,`--overlay-refs annotates a capture with the refs of a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --overlay-refs.`})}async function Ot(t){let{req:n,session:r}=t,a=i(`screenshot`,n.flags);if(a)throw new e(`INVALID_ARGS`,a);pe(r.device,n.flags?.screenshotPixelDensity);let o=Nt(n),s=typeof n.flags?.screenshotCropOn==`string`&&n.flags.screenshotCropOn.length>0?n.flags.screenshotCropOn:void 0;s!==void 0&&He({device:r.device,surface:r.surface,cropOn:s,overlayRefs:n.flags?.overlayRefs===!0,fullscreen:n.flags?.screenshotFullscreen===!0});let c=await X({device:r.device,overlayRefs:n.flags?.overlayRefs===!0,cropOn:s,inspectFacts:t.inspectFacts,bindDevice:t.bindDevice});if(!c.ok)return c;let l=c.runtime,u={warnings:[]};return{ok:!0,recorded:o.recorded,execute:async e=>await kt({session:e.session,sessionName:e.sessionName,logPath:e.logPath,dispatchContext:e.dispatchContext,flags:e.request.flags,outPath:o.outPath,runtime:l,cropOn:s,cropRun:u})}}async function Q(e){let{session:t,sessionName:n,outPath:i,dispatchContext:a}=e;return await se({backend:Pt(e),artifacts:Ft(),sessions:oe(n,t),policy:b()}).capture.screenshot({session:n,requestId:a.requestId,appBundleId:t.appBundleId,...r(a),surface:t.surface,...i?{out:{kind:`path`,path:i}}:{}})}function $(e){return S(e)}async function kt(e){let{session:t,runtime:n,flags:r}=e,i=At({cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,cropRun:e.cropRun,logPath:e.logPath}),a=await Q({session:t,sessionName:e.sessionName,outPath:e.outPath,dispatchContext:e.dispatchContext,captureScreenshot:n.captureScreenshot,...i?{crop:i}:{}}),o=[...a.warnings??[],...i?.run?.warnings??[]];return{...a,...o.length>0?{warnings:o}:{},...await jt({session:t,cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,screenshotPath:a.path,logPath:e.logPath,dispatchContext:e.dispatchContext}),...await fe({device:t.device,path:a.path,requestedPixelDensity:r?.screenshotPixelDensity,scale:r?.screenshotScale})}}function At(e){let{cropOn:t,captureSnapshot:n,cropRun:r}=e;if(t!==void 0&&n!==void 0&&r!==void 0)return{cropOn:t,captureSnapshot:n,run:r,logPath:e.logPath}}async function jt(e){let{session:t,cropOn:n,captureSnapshot:r}=e;return n!==void 0||r===void 0?{}:{overlayRefs:await Mt({session:t,logPath:e.logPath,screenshotPath:e.screenshotPath,dispatchContext:e.dispatchContext,captureSnapshot:r})}}async function Mt(e){let{session:t,dispatchContext:n}=e,r={snapshotInteractiveOnly:!0},i=await C({device:t.device,session:t,flags:r,logPath:e.logPath,snapshotScope:void 0,captureData:async()=>await e.captureSnapshot({options:{appBundleId:t.appBundleId,interactiveOnly:!0,surface:t.surface},execution:$(n)})}),a=x(i,r);return ce(t,a),await H({screenshotPath:e.screenshotPath,snapshot:a})}function Nt(e){let t=e.positionals??[],n=e.flags??{},r=t=>t===void 0?void 0:ae(t,e.meta?.cwd),i=r(t[0]),a=r(n.out);return{outPath:i??a,recorded:{positionals:i?[i,...t.slice(1)]:t,flags:a?{...n,out:a}:n}}}function Pt(e){let{session:t,dispatchContext:n,captureScreenshot:i,crop:a}=e;return{platform:l(t.device),captureScreenshot:async(e,s,l)=>{let u=r({...n,...o(l)}),d=await i({outPath:s,options:{appBundleId:n.appBundleId,pixelDensity:u.pixelDensity,fullscreen:u.fullscreen,normalizeStatusBar:u.normalizeStatusBar,stabilize:u.stabilize,surface:l?.surface,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck??(c(t.device)&&t.device.kind===`simulator`),captureBackend:n.screenshotCaptureBackend},execution:$(n)});if(a){let e=await Ze({device:t.device,session:t,surface:t.surface,cropOn:a.cropOn,screenshotPath:s,logPath:a.logPath,dispatchContext:n,captureSnapshot:a.captureSnapshot});a.run.warnings.push(...V(e))}return d.displayRotation?{displayRotation:d.displayRotation}:void 0}}}function Ft(){return{resolveInput:async()=>{throw new e(`UNSUPPORTED_OPERATION`,`screenshot does not resolve input artifacts`)},reserveOutput:async e=>{let t,n;return e?.kind===`path`?n=e.path:(t=await k.mkdtemp(j.join(A.tmpdir(),`agent-device-screenshot-`)),n=j.join(t,`screenshot.png`)),await k.mkdir(j.dirname(n),{recursive:!0}),{path:n,visibility:`client-visible`,publish:async()=>void 0,...t?{cleanup:async()=>{await k.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await k.mkdtemp(j.join(A.tmpdir(),`${e.prefix}-`));return{path:j.join(t,`file${e.ext}`),visibility:`internal`,cleanup:async()=>{await k.rm(t,{recursive:!0,force:!0})}}}}}export{Ne as _,H as a,Ce as b,P as c,Ae as d,be as f,Pe as g,Fe as h,X as i,F as l,Ee as m,Ot as n,Oe as o,De as p,$ as r,we as s,Q as t,xe as u,Te as v,Se as x,ke as y};
1
+ import{P as e,b as t,s as n}from"./sdk-contracts.js";import{f as r,l as i,r as a,u as o}from"./capture.js";import{O as s,p as c,w as l}from"./sdk-device.js";import{$r as u,Ir as d,It as f,Lr as p,S as m,Yr as h,b as g,ei as _,f as ee,hn as te,jr as v,l as ne,ni as re,zr as y}from"./sdk-batch.js";import{T as ie,d as ae}from"./runtime.js";import{t as oe}from"./overlay.js";import{t as se}from"./session-paths.js";import{t as b}from"./snapshot-state.js";import{c as ce,f as le,m as x,o as ue,u as S}from"./session-snapshot.js";import{t as C}from"./selector-pipeline-policy.js";import{i as w,o as T,r as de}from"./png-worker-client.js";import{t as fe}from"./png-size.js";import{r as pe,t as me}from"./screenshot-density.js";import{a as E,o as D,s as O,t as he}from"./screenshot-overlay-draw.js";import{a as ge,i as _e,n as ve,t as ye}from"./session-runtime-admission.js";import{promises as k}from"node:fs";import A from"node:os";import j from"node:path";const M=ne(ee),N=Ie(M);function P(e){return I(e)?.route??`generic`}function F(e){return I(e)?.sessionKind}function be(e){return I(e)?.leaseAdmissionExempt===!0}function xe(e){return I(e)?.appLease===`allowed`}function Se(e){return I(e)?.selectorValidationExempt!==!0}function Ce(e){return I(e)?.sessionExecutionLockExempt!==!0}function we(e){return I(e)?.replayScopedAction===!0}function Te(e){return I(e)?.allowInvalidRecording!==!0}function Ee(e){return I(e)?.saveScriptFlagOwner===!0}function De(){return M.filter(e=>e.saveScriptFlagOwner===!0).map(e=>e.command).sort()}function Oe(e){return I(e)?.lockPolicySelectorOverride===!0}function ke(e){return I(e)?.androidBlockingDialogGuard===!0}function Ae(e){if(e.command===`human_control`||e.command===`lease_heartbeat`)return!1;let t=m(e);return t===void 0?F(e.command)!==`observability`&&g(e.command)!==`observe`:t!==`observes-app`}function je(e){return I(e.command)?.preferExplicitDeviceOverExistingSession===!0}function Me(e){let t=I(e.command)?.allowSessionlessDefaultDevice;return typeof t==`function`&&t(e)}function Ne(e){return I(e.command)?.sessionlessLeaseAdmissionExemption?.(e)}function Pe(e){let t=I(e.command)?.refFrameEffect;return typeof t==`function`?t(e):t}function Fe(e,t){return t.hasExistingSession?je(e)&&t.hasExplicitDeviceIdentity?`explicit-device`:`existing-session`:Le(e)?`skip`:t.hasDeviceSelectionInput?`explicit-device`:Me(e)?`sessionless-default-device`:`skip`}function I(e){return N.descriptorsByCommand.get(e)}function Ie(e){let t=new Map;for(let n of e){if(t.has(n.command))throw Error(`Duplicate daemon command descriptor: ${n.command}`);t.set(n.command,n)}return{descriptorsByCommand:t}}function Le(e){let t=I(e.command);if(t?.route===`lease`)return!0;let n=t?.skipSessionlessProviderDevice;return typeof n==`function`&&n(e)}const L=a.pendingPixelIdentityEvidence,Re=[{target:`ios-simulator`,status:`accepted`},{target:`android-emulator`,status:`accepted`},{target:`android-device`,status:`rejected`,rejectionReason:L},{target:`macos-app-window`,status:`rejected`,rejectionReason:L},{target:`ios-physical`,status:`rejected`,rejectionReason:L},{target:`macos-helper`,status:`rejected`,rejectionReason:L},{target:`web`,status:`rejected`,rejectionReason:L},{target:`linux`,status:`rejected`,rejectionReason:L},{target:`tvos`,status:`rejected`,rejectionReason:L},{target:`harmonyos`,status:`rejected`,rejectionReason:L},{target:`vega`,status:`rejected`,rejectionReason:L}];function ze(e,t){switch(e.platform){case`apple`:return Be(e,t);case`android`:return e.kind===`device`?`android-device`:`android-emulator`;case`harmonyos`:return`harmonyos`;case`vega`:return`vega`;case`linux`:return`linux`;case`web`:return`web`}}function Be(e,t){let n=s(e);switch(n){case`ios`:case`ipados`:return e.kind===`device`?`ios-physical`:`ios-simulator`;case`tvos`:return`tvos`;case`macos`:return Ve(t);case`watchos`:case`visionos`:throw R(n)}}function Ve(e){return(e??`app`)===`app`?`macos-app-window`:`macos-helper`}function R(t,n){return new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on is not accepted on ${t} targets`,{reason:a.targetNotAccepted,...n?{rejectionReason:n}:{}})}function He(t){if(t.overlayRefs||t.fullscreen)throw new e(`INVALID_ARGS`,`--crop-on cannot be combined with --overlay-refs or --fullscreen: both move the captured frame away from the snapshot viewport the crop is measured against`,{reason:a.frameMismatch});try{te(t.cropOn)}catch{throw new e(`INVALID_ARGS`,`screenshot --crop-on requires a valid selector expression`,{reason:a.selectorInvalid})}let n=ze(t.device,t.surface),r=Re.find(e=>e.target===n);if(!r||r.status===`rejected`)throw R(n,r?.status===`rejected`?r.rejectionReason:void 0)}async function Ue(t,n){if(!We(n))throw new e(`INVALID_ARGS`,`Screenshot crop box must be positive integer pixel offsets`);let r=await de(await k.readFile(t),n,`screenshot`);r!==null&&await k.writeFile(t,r)}function We(e){return Number.isInteger(e.x)&&e.x>=0&&Number.isInteger(e.y)&&e.y>=0&&Number.isInteger(e.width)&&e.width>0&&Number.isInteger(e.height)&&e.height>0}function Ge(t){switch(t){case`android`:return`device-pixels`;case`xctest`:case`macos-helper`:return`viewport-points`;default:throw new e(`UNSUPPORTED_OPERATION`,`screenshot --crop-on does not accept snapshot backend "${t??`unknown`}"`,{reason:a.targetNotAccepted})}}function z(e,t,n,r,i){if(e===`device-pixels`||t===null)return Ye(n);let a=r/t.width,o=i/t.height;return{x:Math.round((n.x-t.x)*a),y:Math.round((n.y-t.y)*o),width:Math.round(n.width*a),height:Math.round(n.height*o)}}function Ke(e,t,n){let r=Math.max(e.x,0),i=Math.max(e.y,0),a=Math.min(e.x+e.width,t),o=Math.min(e.y+e.height,n);return a<=r||o<=i?null:{x:r,y:i,width:a-r,height:o-i}}function B(e){let t=null;for(let n of e)!v(n)||!h(n.rect)||(!t||u(n.rect)>u(t))&&(t=n.rect);return t||qe(e.filter(e=>h(e.rect)&&!Je(e)))}function qe(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)h(a.rect)&&(t=Math.min(t,a.rect.x),n=Math.min(n,a.rect.y),r=Math.max(r,a.rect.x+a.rect.width),i=Math.max(i,a.rect.y+a.rect.height));return!Number.isFinite(t)||!Number.isFinite(n)||r<=t||i<=n?null:{x:t,y:n,width:r-t,height:i-n}}function Je(e){return p(e.type??``)===`image`&&!d(e.label)}function Ye(e){return{x:Math.round(e.x),y:Math.round(e.y),width:Math.round(e.width),height:Math.round(e.height)}}const Xe=`${a.partialIntersection}: the selector frame extends past the captured image; the crop was clipped to the image frame`;function V(e){return e?.partialIntersection?[Xe]:[]}async function Ze(t){let{device:n,session:r,surface:i,cropOn:o,screenshotPath:s,logPath:c,dispatchContext:l}=t,u={snapshotInteractiveOnly:!1},d=await S({device:n,session:r,flags:u,logPath:c,snapshotScope:void 0,captureData:async()=>await t.captureSnapshot({options:{appBundleId:l.appBundleId,interactiveOnly:!1,includeRects:!0,surface:i},execution:x(l)})}),f=b(d,u);if(f.snapshotQuality?.state===`sparse`)throw new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was sparse and cannot be read as the screen`,{reason:a.captureUnreadable});let p=await Qe(f.nodes,o,f.truncated,n),m=await fe(s),h=z(Ge(f.backend),B(f.nodes),p.rect,m.width,m.height),g=Ke(h,m.width,m.height);if(g===null)throw new e(`COMMAND_FAILED`,`the frame resolved by --crop-on occupies no pixel of the capture`,{reason:a.emptyIntersection});let _=g.x!==h.x||g.y!==h.y||g.width<h.width||g.height<h.height;return await Ue(s,g),{partialIntersection:_}}async function Qe(t,n,r,i){let o=await ae(C.cropTarget,t,n,{platform:l(i)});if(o.kind===`ambiguous`)throw new e(`COMMAND_FAILED`,`--crop-on matched ${o.matchedNodes.length} nodes and must resolve to one`,{reason:a.targetAmbiguous,candidates:o.matchedNodes.map(e=>e.label??e.ref),matches:o.matchedNodes.length});if(o.kind===`none`)throw r?new e(`COMMAND_FAILED`,`the snapshot taken for --crop-on was truncated, so a missing match is not proven`,{reason:a.captureIncomplete}):new e(`COMMAND_FAILED`,`--crop-on matched no node: ${n}`,{reason:a.targetNotFound,hint:`find ${n} list`});return o.node}const $e=[`scroll`,`list`,`recyclerview`,`edittext`,`textfield`];function et(e,t,n){if(e.backend!==`android`||!n.hittable||!D(n.rect)||v(n))return!1;let r=p(n.type??``);return!($e.some(e=>r.includes(e))||t&&O(n.rect)>O(t)*.25)}function tt(e,t,n,r){return!e.rect||e.hittable!==!0||n(e)||r(e)?null:nt(e,t,r)}function nt(e,t,n){let r=e.rect,i=rt(e,t,n);if(!i)return null;let a=i.y-r.y,o=r.y+r.height-(i.y+i.height);if(a<0||o<0||Math.abs(o-a)<16)return null;let s=Math.min(a,o),c=Math.round(i.y-s),l=Math.round(i.height+s*2);return l<=0||l>=r.height?null:{x:r.x,y:c,width:r.width,height:l}}function rt(e,t,n){let r=e.rect,i=new Map(t.map(e=>[e.index,e])),a=t.filter(t=>t.ref!==e.ref&&at(t,e,i)&&it(t,n)&&D(t.rect)&&_(r,t.rect)).map(e=>e.rect);return a.length<2?null:re(a)}function it(e,t){let n=p(e.type??``);return n.includes(`text`)||n.includes(`image`)&&t(e)}function at(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n.get(r.parentIndex);if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}const ot=[`button`,`link`,`menu`,`tab`,`textfield`,`searchfield`,`securetextfield`,`checkbox`,`radio`,`switch`,`cell`];async function H(e){let t=await k.readFile(e.screenshotPath),n=await w(t,`screenshot`),r=st(e.snapshot,n.width,n.height,{maxRefs:e.maxRefs});for(let e of r)he(n,e);return await k.writeFile(e.screenshotPath,await T(n)),r}function st(e,n,r,i={}){let a=B(e.nodes),o=new Map;for(let t of e.nodes){if(!ut(e,a,t))continue;let i=dt(e.nodes,t);if(!i?.rect||!D(i.rect))continue;let s=ft(t,i,e.nodes),c=pt(t,i,s),l=U(e,a,lt(e,i,e.nodes),n,r);if(!D(l))continue;let u=o.get(i.ref);(!u||c>u.score)&&o.set(i.ref,{ref:i.ref,label:s,rect:i.rect,overlayRect:l,score:c})}return ct(e,a,o,n,r),mt([...o.values()]).sort(wt).slice(0,i.maxRefs??24).sort(Y).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:t(e.overlayRect)}))}function ct(e,t,n,r,i){let a=oe(e.nodes).primaryAction;if(!a?.ref||!a.rect||!D(a.rect))return;let o=U(e,t,a.rect,r,i);if(!D(o))return;let s={ref:a.ref,label:a.label,rect:a.rect,overlayRect:o,score:100},c=n.get(a.ref);n.set(a.ref,c?{...c,score:Math.max(c.score,s.score)}:s)}function lt(e,t,n){return e.backend===`android`?tt(t,n,W,e=>!!J(e))??t.rect:t.rect}function ut(e,t,n){let r=[n.label,n.value].some(K)||q(n.identifier);return et(e,t,n)?!0:W(n)?r:r&&ht(n)}function dt(e,t){return[G(t)?t:null,y(e,t,G),t.hittable?t:null,y(e,t,e=>e.hittable===!0)].find(gt)??null}function ft(e,t,n){let r=J(e);return e.ref!==t.ref&&r?r:_t(t,n)||J(t)}function pt(e,t,n){let r=0;return e.ref===t.ref&&(r+=4),t.hittable&&(r+=3),W(t)&&(r+=3),W(e)&&(r+=2),n&&(r+=2),q(t.identifier)&&(r+=1),d(t.value)&&(r+=1),r}function mt(e){let t=[];for(let n of e.sort((e,t)=>O(e.overlayRect)-O(t.overlayRect))){let e=t.findIndex(e=>e.label!==void 0&&e.label===n.label&&(_(e.overlayRect,n.overlayRect)||_(n.overlayRect,e.overlayRect)));if(e===-1){t.push(n);continue}O(n.overlayRect)<O(t[e].overlayRect)&&(t[e]=n)}return t}function U(e,t,n,r,i){return Ct(z(e.backend===`android`?`device-pixels`:`viewport-points`,t,n,r,i),r,i)}function W(e){let t=[e.type,e.role,e.subrole].map(e=>p(e??``)).join(` `);return ot.some(e=>t.includes(e))}function G(e){return W(e)&&!v(e)}function ht(e){let t=p(e.type??``);return t.includes(`statictext`)||t.includes(`image`)||t.includes(`text`)||t.includes(`other`)}function gt(e){return!!(e?.rect&&D(e.rect)&&!v(e))}function K(e){return d(e)?!bt(e):!1}function q(e){return typeof e!=`string`||!K(e)?!1:!xt(e)}function J(e){let t=[e.label,e.value].find(K);if(t)return t.trim();if(q(e.identifier))return e.identifier.trim()}function _t(e,t){let n=null;for(let r of t){if(r.ref===e.ref||!vt(r,e,t))continue;let i=J(r);if(!i)continue;let a=yt(r);(!n||a>n.score)&&(n={label:i,score:a})}return n?.label}function vt(e,t,n){let r=e;for(;r.parentIndex!==void 0;){let e=n[r.parentIndex];if(!e)return!1;if(e.ref===t.ref)return!0;r=e}return!1}function yt(e){let t=0;return p(e.type??``).includes(`text`)&&(t+=2),K(e.label)&&(t+=2),K(e.value)&&(t+=1),t}function bt(e){let t=e?.trim().toLowerCase();return t===`toolbar`||t===`window`||t===`application`||t?.startsWith(`vertical scroll bar`)===!0}function xt(e){return/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(e.trim())}function St(e,t){return Number.parseInt(e.replace(/^\D+/,``),10)-Number.parseInt(t.replace(/^\D+/,``),10)}function Ct(e,t,n){let r=E(e.x,0,Math.max(0,t-1)),i=E(e.y,0,Math.max(0,n-1)),a=Math.max(1,t-r),o=Math.max(1,n-i);return{x:r,y:i,width:E(e.width,1,a),height:E(e.height,1,o)}}function Y(e,t){let n=e.overlayRect.y-t.overlayRect.y;if(n!==0)return n;let r=e.overlayRect.x-t.overlayRect.x;return r===0?St(e.ref,t.ref):r}function wt(e,t){return t.score===e.score?Y(e,t):t.score-e.score}async function X(e){let t=f({overlayRefs:e.overlayRefs,cropOn:e.cropOn!==void 0}),n=await ye({device:e.device,plan:t,inspectFacts:e.inspectFacts});return n.admitted?{ok:!0,runtime:await Tt(e.bindDevice,n)}:{ok:!1,response:Dt(t.kind,n.operation,n.fact)}}async function Tt(e,t){let n=ve(e),{device:r,plan:i}=ge(t);switch(i.kind){case`capture`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e)})}case`capture-with-overlay-refs`:case`capture-with-crop-on`:{let e=await n(r,i.use);return Object.freeze({captureScreenshot:Z(e),captureSnapshot:Et(e)})}}}function Z(e){return async t=>await e.operations.captureScreenshot(t)}function Et(e){return async t=>await e.operations.captureSnapshot(t)}function Dt(e,t,r){return t===`captureScreenshot`?_e(`screenshot`,r):e===`capture-with-crop-on`?n(`UNSUPPORTED_OPERATION`,`--crop-on crops the capture to a selector frame using a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --crop-on.`}):n(`UNSUPPORTED_OPERATION`,`--overlay-refs annotates a capture with the refs of a snapshot taken on the same screen, which this target cannot capture.`,{reason:r.available?void 0:r.reason},{hint:(r.available?void 0:r.hint)??`Re-run screenshot without --overlay-refs.`})}async function Ot(t){let{req:n,session:r}=t,a=i(`screenshot`,n.flags);if(a)throw new e(`INVALID_ARGS`,a);me(r.device,n.flags?.screenshotPixelDensity);let o=Nt(n),s=typeof n.flags?.screenshotCropOn==`string`&&n.flags.screenshotCropOn.length>0?n.flags.screenshotCropOn:void 0;s!==void 0&&He({device:r.device,surface:r.surface,cropOn:s,overlayRefs:n.flags?.overlayRefs===!0,fullscreen:n.flags?.screenshotFullscreen===!0});let c=await X({device:r.device,overlayRefs:n.flags?.overlayRefs===!0,cropOn:s,inspectFacts:t.inspectFacts,bindDevice:t.bindDevice});if(!c.ok)return c;let l=c.runtime,u={warnings:[]};return{ok:!0,recorded:o.recorded,execute:async e=>await kt({session:e.session,sessionName:e.sessionName,logPath:e.logPath,dispatchContext:e.dispatchContext,flags:e.request.flags,outPath:o.outPath,runtime:l,cropOn:s,cropRun:u})}}async function Q(e){let{session:t,sessionName:n,outPath:i,dispatchContext:a}=e;return await le({backend:Pt(e),artifacts:Ft(),sessions:ce(n,t),policy:ie()}).capture.screenshot({session:n,requestId:a.requestId,appBundleId:t.appBundleId,...r(a),surface:t.surface,...i?{out:{kind:`path`,path:i}}:{}})}function $(e){return x(e)}async function kt(e){let{session:t,runtime:n,flags:r}=e,i=At({cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,cropRun:e.cropRun,logPath:e.logPath}),a=await Q({session:t,sessionName:e.sessionName,outPath:e.outPath,dispatchContext:e.dispatchContext,captureScreenshot:n.captureScreenshot,...i?{crop:i}:{}}),o=[...a.warnings??[],...i?.run?.warnings??[]];return{...a,...o.length>0?{warnings:o}:{},...await jt({session:t,cropOn:e.cropOn,captureSnapshot:n.captureSnapshot,screenshotPath:a.path,logPath:e.logPath,dispatchContext:e.dispatchContext}),...await pe({device:t.device,path:a.path,requestedPixelDensity:r?.screenshotPixelDensity,scale:r?.screenshotScale})}}function At(e){let{cropOn:t,captureSnapshot:n,cropRun:r}=e;if(t!==void 0&&n!==void 0&&r!==void 0)return{cropOn:t,captureSnapshot:n,run:r,logPath:e.logPath}}async function jt(e){let{session:t,cropOn:n,captureSnapshot:r}=e;return n!==void 0||r===void 0?{}:{overlayRefs:await Mt({session:t,logPath:e.logPath,screenshotPath:e.screenshotPath,dispatchContext:e.dispatchContext,captureSnapshot:r})}}async function Mt(e){let{session:t,dispatchContext:n}=e,r={snapshotInteractiveOnly:!0},i=await S({device:t.device,session:t,flags:r,logPath:e.logPath,snapshotScope:void 0,captureData:async()=>await e.captureSnapshot({options:{appBundleId:t.appBundleId,interactiveOnly:!0,surface:t.surface},execution:$(n)})}),a=b(i,r);return ue(t,a),await H({screenshotPath:e.screenshotPath,snapshot:a})}function Nt(e){let t=e.positionals??[],n=e.flags??{},r=t=>t===void 0?void 0:se(t,e.meta?.cwd),i=r(t[0]),a=r(n.out);return{outPath:i??a,recorded:{positionals:i?[i,...t.slice(1)]:t,flags:a?{...n,out:a}:n}}}function Pt(e){let{session:t,dispatchContext:n,captureScreenshot:i,crop:a}=e;return{platform:l(t.device),captureScreenshot:async(e,s,l)=>{let u=r({...n,...o(l)}),d=await i({outPath:s,options:{appBundleId:n.appBundleId,pixelDensity:u.pixelDensity,fullscreen:u.fullscreen,normalizeStatusBar:u.normalizeStatusBar,stabilize:u.stabilize,surface:l?.surface,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck??(c(t.device)&&t.device.kind===`simulator`),captureBackend:n.screenshotCaptureBackend},execution:$(n)});if(a){let e=await Ze({device:t.device,session:t,surface:t.surface,cropOn:a.cropOn,screenshotPath:s,logPath:a.logPath,dispatchContext:n,captureSnapshot:a.captureSnapshot});a.run.warnings.push(...V(e))}return d.displayRotation?{displayRotation:d.displayRotation}:void 0}}}function Ft(){return{resolveInput:async()=>{throw new e(`UNSUPPORTED_OPERATION`,`screenshot does not resolve input artifacts`)},reserveOutput:async e=>{let t,n;return e?.kind===`path`?n=e.path:(t=await k.mkdtemp(j.join(A.tmpdir(),`agent-device-screenshot-`)),n=j.join(t,`screenshot.png`)),await k.mkdir(j.dirname(n),{recursive:!0}),{path:n,visibility:`client-visible`,publish:async()=>void 0,...t?{cleanup:async()=>{await k.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await k.mkdtemp(j.join(A.tmpdir(),`${e.prefix}-`));return{path:j.join(t,`file${e.ext}`),visibility:`internal`,cleanup:async()=>{await k.rm(t,{recursive:!0,force:!0})}}}}}export{Ne as _,H as a,Ce as b,P as c,Ae as d,be as f,Pe as g,Fe as h,X as i,F as l,Ee as m,Ot as n,Oe as o,De as p,$ as r,we as s,Q as t,xe as u,Te as v,Se as x,ke as y};