agent-device 0.21.5 → 0.21.6
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.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.5.apk → agent-device-android-ime-helper-0.21.6.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.6.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.5.manifest.json → agent-device-android-ime-helper-0.21.6.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.5.apk → agent-device-android-snapshot-helper-0.21.6.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.6.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.5.manifest.json → agent-device-android-snapshot-helper-0.21.6.manifest.json} +6 -6
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +8 -1
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-transport.js +1 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-lifecycle.js +3 -3
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/device-input-state.d.ts +3 -4
- package/dist/src/device-session.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/run-script-http-child.d.ts +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/mechanics.js +16 -16
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/platform-runtime-android-adb-host.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/semantic-index.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/tree.js +1 -1
- package/dist/src/video.js +2 -2
- package/package.json +2 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.5.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.5.apk.sha256 +0 -1
- package/dist/src/adb-host.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,N as t}from"./sdk-contracts.js";import{S as n,c as r,w as i}from"./sdk-device.js";import{At as a,Dt as o,Et as s,Tt as c,kt as l}from"./sdk-batch.js";import{m as u}from"./observability.js";import{r as d}from"./diagnostics.js";import{D as ee,a as f,i as p}from"./owner-identity.js";import{t as m}from"./file.js";import"./diagnostics2.js";import"./process.js";import{c as h,i as g,l as _,r as v,s as y,t as b,u as x}from"./device-claim-inspection.js";import{l as S,u as C}from"./screen-recording-resource-recovery.js";import w from"node:path";import T from"node:fs";import E from"node:crypto";async function te(e){let t=await e.observeDeviceBoot?.observeBootTimeMs(e.device);if(t?.observed!==!0||t.bootedAtMs<=e.claim.updatedAtMs)return;let{session:n,workspace:r,stateDir:i}=e.claim;return{session:n,workspace:r,stateDir:i,bootedAtMs:t.bootedAtMs}}function ne(e){d({level:`info`,phase:`device_claim_reboot_released`,data:{deviceKey:e.deviceKey,ownerSession:e.claim.session,ownerStateDir:e.claim.stateDir,ownerWorkspace:e.claim.workspace,claimUpdatedAtMs:e.claim.updatedAtMs,deviceBootedAtMs:e.bootedAtMs}})}function D(e){let t=_(e.deviceKey);T.mkdirSync(w.dirname(t),{recursive:!0,mode:448}),ee({destination:t,contents:`${JSON.stringify(e)}\n`,mode:384})}async function O(e,t){let n=f(),r=await m({lockDirPath:`${_(e)}.lock`,owner:{pid:n.pid,startTime:n.startTime,acquiredAtMs:Date.now()},timeoutMs:3e4,description:`device claim for ${e}`});try{return await t()}finally{await r()}}async function re(e){let t=v(_(e.deviceKey));return t?t.claim&&se(t.claim,e.stateDir,e.owner)?(F(e.deviceKey,t.claim),{status:`available`}):t.claim&&M(t.claim,e,e.owner)?{status:`held`,ownership:ie(t.claim)}:await ae(t,e):{status:`available`}}function ie(e){if(e.updatedAtMs>=Date.now())return y(e);let t={...e,updatedAtMs:Date.now()};return D(t),y(t)}async function ae(e,t){let n=e.claim;if(!n)return N(t.deviceKey,e),{status:`conflict`,conflict:e};let r=await oe({classification:e.classification,claim:n,device:t.device,observeDeviceBoot:t.observeDeviceBoot});if(!r.settles)return N(t.deviceKey,e),{status:`conflict`,conflict:e};let i=await k(n,t.reconcileOrphanedDeviceClaim);return i.status===`retained`?(N(t.deviceKey,e,i.reason),{status:`conflict`,conflict:e}):r.tookOver?(ne({deviceKey:t.deviceKey,claim:n,bootedAtMs:r.tookOver.bootedAtMs}),{status:`available`,tookOver:r.tookOver}):{status:`available`}}async function oe(e){if(b(e.classification))return{settles:!0};let t=await te(e);return t?{settles:!0,tookOver:t}:{settles:!1}}async function k(e,t){let n=await t(e);if(n.status===`retained`)return n;try{T.unlinkSync(_(e.deviceKey))}catch(e){if(e.code!==`ENOENT`)throw e}return{status:`reconciled`}}function A(e,t,n){return e.stateDir===t&&p({pid:e.ownerPid,startTime:e.ownerStartTime},n)}function j(e){return e.abandonedAtMs!==void 0}function se(e,t,n){return j(e)&&A(e,t,n)}function M(e,t,n){return e.session===t.session&&e.workspace===t.workspace&&A(e,t.stateDir,n)}function N(e,t,n){d({level:`warn`,phase:`device_claim_conflict`,data:{deviceKey:e,classification:t.classification,...P(t),...n?{reconciliationReason:n}:{}}})}function P(e){return e.allocatorClaim?{ownerStateDir:e.allocatorClaim.stateDir,allocatorInstanceId:e.allocatorClaim.allocator.instanceId,identityIncarnationId:e.allocatorClaim.allocator.identityIncarnationId}:{ownerSession:e.claim?.session,ownerStateDir:e.claim?.stateDir}}function F(e,t){d({level:`info`,phase:`device_claim_abandoned_superseded`,data:{deviceKey:e,abandonedSession:t.session,abandonedAtMs:t.abandonedAtMs}})}function I(e){return`transient:${e}`}async function L(e){let t=V(e.device),n=h(t);return await O(n,async()=>await z({...e,deviceKey:n,identity:t}))}async function R(e){let t=V(e.device),n=h(t);return await O(n,async()=>{let r=v(_(n));return r?.claim&&!j(r.claim)&&A(r.claim,e.stateDir,f())?{status:`covered-by-owned-claim`}:await z({device:e.device,deviceKey:n,identity:t,session:I(e.command),workspace:e.workspace,stateDir:e.stateDir,reconcileOrphanedDeviceClaim:e.reconcileOrphanedDeviceClaim})})}async function z(e){let{deviceKey:t,identity:n}=e,r=f(),i=await re({...e,owner:r});if(i.status===`conflict`)return i;if(i.status===`held`)return{status:`acquired`,ownership:i.ownership};let a=Date.now(),o={schemaVersion:2,deviceKey:t,device:{...n,name:e.device.name},session:e.session,workspace:e.workspace,stateDir:e.stateDir,ownerPid:r.pid,ownerStartTime:r.startTime,ownerToken:E.randomUUID(),createdAtMs:a,updatedAtMs:a};return D(o),{status:`acquired`,ownership:y(o),...i.tookOver?{tookOver:i.tookOver}:{}}}function B(e){let t=h(V(e)),n=v(_(t))?.claim;return n!==void 0&&n.deviceKey===t&&!j(n)&&p({pid:n.ownerPid,startTime:n.ownerStartTime},f())}function V(e){return i({...e,...r(e.platform)?{appleOs:n(e)}:{}})}async function H(e){let t=[];for(let n of g(e.selectors))t.push(await U(n,e.reconcile));return t}async function U(e,t){let n=e.claim,r={fileName:e.fileName,classification:e.classification,...e.deviceKey?{deviceKey:e.deviceKey}:{},...n?{device:n.device,session:n.session,workspace:n.workspace,stateDir:n.stateDir}:{},...e.allocatorClaim?{device:e.allocatorClaim.device,stateDir:e.allocatorClaim.stateDir,allocator:e.allocatorClaim.allocator}:{}};if(!n||!b(e.classification))return{...r,status:`refused`,reason:G(e.classification)};if(_(n.deviceKey)!==w.join(x(),e.fileName))return{...r,status:`refused`,reason:`claim-file-name-mismatch`};let{deviceKey:i,ownerToken:a}=n;return await O(i,async()=>{let e=v(_(i));if(!e?.claim||e.claim.ownerToken!==a||!b(e.classification))return{...r,status:`changed`,reason:`claim-changed-during-release`};let o=await k(e.claim,t);return o.status===`retained`?{...r,status:`retained`,reason:o.reason}:(d({level:`info`,phase:`device_claim_stale_released`,data:{deviceKey:i,ownerSession:n.session,ownerStateDir:n.stateDir}}),{...r,status:`released`})})}const W=Object.freeze({live:`live-owner`,"owner-process-reused":`owner-pid-reused`,"owner-state-dir-gone":`owner-process-still-running`,unknown:`owner-liveness-unknown`,inconsistent:`claim-record-inconsistent`,"allocator-inconsistent":`allocator-claim-record-inconsistent`,"allocator-held":`allocator-held-owner`,"owner-process-dead":`claim-record-unreadable`,"owner-daemon-superseded":`claim-record-unreadable`});function G(e){return W[e]}async function K(e){return e?await q(e,(e,t)=>{try{T.unlinkSync(t)}catch(e){if(e.code!==`ENOENT`)throw e;return`absent`}return`deleted`},e=>e?`ownership-changed`:`absent`):`absent`}async function ce(e){return e?await q(e,e=>{let t=Date.now();return D({...e,abandonedAtMs:t,updatedAtMs:t}),`abandoned`},e=>e?`ownership-changed`:`absent`):`absent`}async function le(e){return e?await q(e,e=>(D({...e,updatedAtMs:Date.now()}),{status:`renewed`}),e=>({status:`lost`,conflict:e})):{status:`lost`,conflict:void 0}}async function q(e,t,n){return await O(e.deviceKey,async()=>{let r=_(e.deviceKey),i=v(r);if(!i)return n(void 0);let a=i.claim;return!a||!ue(a,e)?n(i):t(a,r)})}function ue(e,t){return e.ownerToken===t.ownerToken&&p({pid:e.ownerPid,startTime:e.ownerStartTime},{pid:t.ownerPid,startTime:t.ownerStartTime})}async function de(e,t){let n=x(),r;try{r=T.readdirSync(n,{withFileTypes:!0})}catch{return{examined:0,reconciled:0,retained:0,changed:0}}let i=0,a=0,o=0,s=0;for(let c of r){if(!c.isFile()||!c.name.endsWith(`.json`))continue;let r=w.join(n,c.name),l=v(r);if(!l?.claim||!J(l.classification,l.claim.stateDir,t))continue;i+=1;let{deviceKey:u,ownerToken:d}=l.claim;if(_(u)!==r){o+=1;continue}await O(u,async()=>{let n=v(r);if(!n?.claim||!J(n.classification,n.claim.stateDir,t)||n.claim.ownerToken!==d){s+=1;return}if((await k(n.claim,e)).status===`retained`){o+=1;return}a+=1})}return{examined:i,reconciled:a,retained:o,changed:s}}function J(e,t,n){return b(e)?e!==`owner-daemon-superseded`||w.resolve(t)===w.resolve(n):!1}const Y=C({resourceKind:`app-log`,fileName:`app-log.resource.json`,displayName:`App-log`}),X=S({resourceKind:`app-log`,displayName:`app-log`,store:Y,sessionSlot:{read:e=>e.appLog,replace:(e,t)=>({...e,appLog:t,appLogFailure:void 0})},completionMetadata:e=>({backend:e.backend,outputPath:e.outputPath,completedAt:e.completedAt}),failedFinishPolicy:`dispose-on-failed-finish`,messages:{noActive:`no app log stream active`,cleanupPendingHint:`Keep app-log.resource.json and retry cleanup through its exact runtime owner.`}});function fe(e){if(e.appLog){let t=e.appLog.handle.inspect();return{active:t.state===`active`||t.state===`recovering`,...t}}return e.appLogFailure?{active:!1,state:`failed`,backend:e.appLogFailure.backend,failureCode:e.appLogFailure.code,failureMessage:e.appLogFailure.message,hint:e.appLogFailure.hint}:{active:!1,state:`inactive`}}function pe(e){return X.adoptStarted(e)}function me(e){return X.finishLive(e)}function he(e){return X.forceCleanupLive(e)}function ge(e){let n=t(e.error);return e.sessionStore.set(e.sessionName,{...e.session,appLog:void 0,appLogFailure:{backend:e.backend,code:n.code,message:n.message,hint:n.hint}}),n}function _e(e){e.sessionStore.set(e.sessionName,{...e.session,appLogFailure:void 0})}const ve=C({resourceKind:`audio-probe`,fileName:`audio-probe.resource.json`,displayName:`Audio probe`}),Z=S({resourceKind:`audio-probe`,displayName:`audio probe`,store:ve,sessionSlot:{read:e=>e.audioProbe,replace:(e,t)=>({...e,audioProbe:t})},completionMetadata:e=>({backend:e.backend??`unknown`,source:e.source,durationMs:e.durationMs,elapsedMs:e.elapsedMs,bucketMs:e.bucketMs,sampleCount:e.sampleCount,heard:e.heard}),failedFinishPolicy:`dispose-on-failed-finish`,messages:{noActive:`no active audio probe`,cleanupPendingHint:`Keep audio-probe.resource.json and retry stop through its exact runtime owner.`}});function ye(e){return Z.adoptStarted(e)}function be(e){return Z.finishLive(e)}const xe=C({resourceKind:`perf-capture`,fileName:`perf-capture.resource.json`,displayName:`Perf capture`}),Q=S({resourceKind:`perf-capture`,displayName:`perf capture`,store:xe,sessionSlot:{read:e=>e.perfCapture,replace:(e,t)=>({...e,perfCapture:t})},completionMetadata:e=>({kind:typeof e.kind==`string`?e.kind:`unknown`,mode:typeof e.mode==`string`?e.mode:`unknown`,...typeof e.outPath==`string`?{outPath:e.outPath}:{}}),failedFinishPolicy:`preserve-retry-material`,messages:{noActive:`no active native perf capture`,cleanupPendingHint:`Keep perf-capture.resource.json and retry stop through its exact runtime owner.`}});function Se(e){return Q.adoptStarted(e)}function $(e){return Q.finishLive(e)}function Ce(e){if(e.area===`frames`)return Object.freeze({kind:`frames`,request:e,use:c});if(e.area===`memory`)return e.action===`snapshot`?Object.freeze({kind:`memory-snapshot`,request:e,use:o}):Object.freeze({kind:`memory-sample`,request:e,use:s});if(e.area===`trace`)return e.action===`start`?Object.freeze({kind:`capture-start`,request:e,use:l}):Object.freeze({kind:`capture-stop`,request:e});switch(e.action){case`start`:return Object.freeze({kind:`capture-start`,request:e,use:l});case`stop`:return Object.freeze({kind:`capture-stop`,request:e});case`report`:return Object.freeze({kind:`profile-report`,request:e,use:a})}}function we(t){let n=t.positionals??[],r=n[0]?.toLowerCase();if(r===`frames`){let i=n[1]?.toLowerCase();if(i!==void 0&&i!==`sample`||n.length>2||t.kind!==void 0)throw new e(`INVALID_ARGS`,`perf action must be frames, memory sample|snapshot, cpu profile start|stop|report, or trace start|stop`);return Object.freeze({area:r,action:`sample`})}if(r===`memory`)return Te(n,t);if(r===`cpu`)return Ee(n,t.outPath);if(r===`trace`)return De(n,t.outPath);throw new e(`INVALID_ARGS`,`perf requires frames, memory, cpu, or trace`)}function Te(t,n){let r=(t[1]??`sample`).toLowerCase();if(r!==`sample`&&r!==`snapshot`)throw new e(`INVALID_ARGS`,`perf memory requires sample or snapshot`);if(n.kind!==void 0&&r!==`snapshot`)throw new e(`INVALID_ARGS`,`--kind is only supported with perf memory snapshot`);if(r===`sample`&&t.length>2)throw new e(`INVALID_ARGS`,`perf memory sample does not accept additional positionals`);if(r===`snapshot`&&t.length>3)throw new e(`INVALID_ARGS`,`perf memory snapshot accepts at most one positional kind`);let i=n.kind??t[2];if(i!==void 0&&!u(i))throw new e(`INVALID_ARGS`,`perf memory snapshot --kind must be android-hprof or memgraph`);return Object.freeze({area:`memory`,action:r,...i===void 0?{}:{kind:i},...n.outPath===void 0?{}:{outPath:n.outPath}})}function Ee(t,n){if(t[1]?.toLowerCase()!==`profile`)throw new e(`INVALID_ARGS`,`perf cpu requires profile`);let r=t[2]?.toLowerCase();if(r!==`start`&&r!==`stop`&&r!==`report`)throw new e(`INVALID_ARGS`,`perf cpu profile action must be start, stop, or report`);let i=t[3]?.toLowerCase();if(i!==`xctrace`&&i!==`simpleperf`)throw new e(`INVALID_ARGS`,`perf cpu profile requires --kind xctrace or simpleperf`);let a=n??t[5];return Object.freeze({area:`cpu`,subject:`profile`,action:r,kind:i,...t[4]?{template:t[4]}:{},...a?{outPath:a}:{},...t[6]?{tracePath:t[6]}:{}})}function De(t,n){let r=t[1]?.toLowerCase();if(r!==`start`&&r!==`stop`)throw new e(`INVALID_ARGS`,`perf trace action must be start or stop`);let i=t[2]?.toLowerCase();if(i!==`xctrace`&&i!==`perfetto`)throw new e(`INVALID_ARGS`,`perf trace requires --kind xctrace or perfetto`);let a=n??t[4];return Object.freeze({area:`trace`,action:r,kind:i,...t[3]?{template:t[3]}:{},...a?{outPath:a}:{}})}export{de as C,B as S,le as T,ce as _,Q as a,K as b,be as c,_e as d,me as f,Y as g,ge as h,$ as i,pe as l,fe as m,Ce as n,ye as o,he as p,Se as r,Z as s,we as t,X as u,L as v,H as w,V as x,R as y};
|
|
1
|
+
import{C as e,N as t}from"./sdk-contracts.js";import{S as n,c as r,w as i}from"./sdk-device.js";import{At as a,Dt as o,Et as s,Tt as c,kt as l}from"./sdk-batch.js";import{m as u}from"./observability.js";import{r as d}from"./diagnostics.js";import{D as ee,a as f,i as p}from"./owner-identity.js";import{n as te,t as m}from"./file.js";import"./diagnostics2.js";import"./process.js";import{c as h,i as ne,l as g,r as _,s as v,t as y,u as b}from"./device-claim-inspection.js";import{l as x,u as S}from"./screen-recording-resource-recovery.js";import C from"node:path";import w from"node:fs";import re from"node:crypto";async function T(e){let t=await e.observeDeviceBoot?.observeBootTimeMs(e.device);if(t?.observed!==!0||t.bootedAtMs<=e.claim.updatedAtMs)return;let{session:n,workspace:r,stateDir:i}=e.claim;return{session:n,workspace:r,stateDir:i,bootedAtMs:t.bootedAtMs}}function E(e){d({level:`info`,phase:`device_claim_reboot_released`,data:{deviceKey:e.deviceKey,ownerSession:e.claim.session,ownerStateDir:e.claim.stateDir,ownerWorkspace:e.claim.workspace,claimUpdatedAtMs:e.claim.updatedAtMs,deviceBootedAtMs:e.bootedAtMs}})}function D(e){let t=g(e.deviceKey);w.mkdirSync(C.dirname(t),{recursive:!0,mode:448}),ee({destination:t,contents:`${JSON.stringify(e)}\n`,mode:384})}async function O(e,t){let n=f();return await te({acquire:()=>m({lockDirPath:`${g(e)}.lock`,owner:{pid:n.pid,startTime:n.startTime,acquiredAtMs:Date.now()},timeoutMs:3e4,description:`device claim for ${e}`}),task:t})}async function ie(e){let t=_(g(e.deviceKey));return t?t.claim&&M(t.claim,e.stateDir,e.owner)?(I(e.deviceKey,t.claim),{status:`available`}):t.claim&&N(t.claim,e,e.owner)?{status:`held`,ownership:ae(t.claim)}:await oe(t,e):{status:`available`}}function ae(e){if(e.updatedAtMs>=Date.now())return v(e);let t={...e,updatedAtMs:Date.now()};return D(t),v(t)}async function oe(e,t){let n=e.claim;if(!n)return P(t.deviceKey,e),{status:`conflict`,conflict:e};let r=await se({classification:e.classification,claim:n,device:t.device,observeDeviceBoot:t.observeDeviceBoot});if(!r.settles)return P(t.deviceKey,e),{status:`conflict`,conflict:e};let i=await k(n,t.reconcileOrphanedDeviceClaim);return i.status===`retained`?(P(t.deviceKey,e,i.reason),{status:`conflict`,conflict:e}):r.tookOver?(E({deviceKey:t.deviceKey,claim:n,bootedAtMs:r.tookOver.bootedAtMs}),{status:`available`,tookOver:r.tookOver}):{status:`available`}}async function se(e){if(y(e.classification))return{settles:!0};let t=await T(e);return t?{settles:!0,tookOver:t}:{settles:!1}}async function k(e,t){let n=await t(e);if(n.status===`retained`)return n;try{w.unlinkSync(g(e.deviceKey))}catch(e){if(e.code!==`ENOENT`)throw e}return{status:`reconciled`}}function A(e,t,n){return e.stateDir===t&&p({pid:e.ownerPid,startTime:e.ownerStartTime},n)}function j(e){return e.abandonedAtMs!==void 0}function M(e,t,n){return j(e)&&A(e,t,n)}function N(e,t,n){return e.session===t.session&&e.workspace===t.workspace&&A(e,t.stateDir,n)}function P(e,t,n){d({level:`warn`,phase:`device_claim_conflict`,data:{deviceKey:e,classification:t.classification,...F(t),...n?{reconciliationReason:n}:{}}})}function F(e){return e.allocatorClaim?{ownerStateDir:e.allocatorClaim.stateDir,allocatorInstanceId:e.allocatorClaim.allocator.instanceId,identityIncarnationId:e.allocatorClaim.allocator.identityIncarnationId}:{ownerSession:e.claim?.session,ownerStateDir:e.claim?.stateDir}}function I(e,t){d({level:`info`,phase:`device_claim_abandoned_superseded`,data:{deviceKey:e,abandonedSession:t.session,abandonedAtMs:t.abandonedAtMs}})}function L(e){return`transient:${e}`}async function R(e){let t=H(e.device),n=h(t);return await O(n,async()=>await B({...e,deviceKey:n,identity:t}))}async function z(e){let t=H(e.device),n=h(t);return await O(n,async()=>{let r=_(g(n));return r?.claim&&!j(r.claim)&&A(r.claim,e.stateDir,f())?{status:`covered-by-owned-claim`}:await B({device:e.device,deviceKey:n,identity:t,session:L(e.command),workspace:e.workspace,stateDir:e.stateDir,reconcileOrphanedDeviceClaim:e.reconcileOrphanedDeviceClaim})})}async function B(e){let{deviceKey:t,identity:n}=e,r=f(),i=await ie({...e,owner:r});if(i.status===`conflict`)return i;if(i.status===`held`)return{status:`acquired`,ownership:i.ownership};let a=Date.now(),o={schemaVersion:2,deviceKey:t,device:{...n,name:e.device.name},session:e.session,workspace:e.workspace,stateDir:e.stateDir,ownerPid:r.pid,ownerStartTime:r.startTime,ownerToken:re.randomUUID(),createdAtMs:a,updatedAtMs:a};return D(o),{status:`acquired`,ownership:v(o),...i.tookOver?{tookOver:i.tookOver}:{}}}function V(e){let t=h(H(e)),n=_(g(t))?.claim;return n!==void 0&&n.deviceKey===t&&!j(n)&&p({pid:n.ownerPid,startTime:n.ownerStartTime},f())}function H(e){return i({...e,...r(e.platform)?{appleOs:n(e)}:{}})}async function U(e){let t=[];for(let n of ne(e.selectors))t.push(await W(n,e.reconcile));return t}async function W(e,t){let n=e.claim,r={fileName:e.fileName,classification:e.classification,...e.deviceKey?{deviceKey:e.deviceKey}:{},...n?{device:n.device,session:n.session,workspace:n.workspace,stateDir:n.stateDir}:{},...e.allocatorClaim?{device:e.allocatorClaim.device,stateDir:e.allocatorClaim.stateDir,allocator:e.allocatorClaim.allocator}:{}};if(!n||!y(e.classification))return{...r,status:`refused`,reason:K(e.classification)};if(g(n.deviceKey)!==C.join(b(),e.fileName))return{...r,status:`refused`,reason:`claim-file-name-mismatch`};let{deviceKey:i,ownerToken:a}=n;return await O(i,async()=>{let e=_(g(i));if(!e?.claim||e.claim.ownerToken!==a||!y(e.classification))return{...r,status:`changed`,reason:`claim-changed-during-release`};let o=await k(e.claim,t);return o.status===`retained`?{...r,status:`retained`,reason:o.reason}:(d({level:`info`,phase:`device_claim_stale_released`,data:{deviceKey:i,ownerSession:n.session,ownerStateDir:n.stateDir}}),{...r,status:`released`})})}const G=Object.freeze({live:`live-owner`,"owner-process-reused":`owner-pid-reused`,"owner-state-dir-gone":`owner-process-still-running`,unknown:`owner-liveness-unknown`,inconsistent:`claim-record-inconsistent`,"allocator-inconsistent":`allocator-claim-record-inconsistent`,"allocator-held":`allocator-held-owner`,"owner-process-dead":`claim-record-unreadable`,"owner-daemon-superseded":`claim-record-unreadable`});function K(e){return G[e]}async function ce(e){return e?await q(e,(e,t)=>{try{w.unlinkSync(t)}catch(e){if(e.code!==`ENOENT`)throw e;return`absent`}return`deleted`},e=>e?`ownership-changed`:`absent`):`absent`}async function le(e){return e?await q(e,e=>{let t=Date.now();return D({...e,abandonedAtMs:t,updatedAtMs:t}),`abandoned`},e=>e?`ownership-changed`:`absent`):`absent`}async function ue(e){return e?await q(e,e=>(D({...e,updatedAtMs:Date.now()}),{status:`renewed`}),e=>({status:`lost`,conflict:e})):{status:`lost`,conflict:void 0}}async function q(e,t,n){return await O(e.deviceKey,async()=>{let r=g(e.deviceKey),i=_(r);if(!i)return n(void 0);let a=i.claim;return!a||!de(a,e)?n(i):t(a,r)})}function de(e,t){return e.ownerToken===t.ownerToken&&p({pid:e.ownerPid,startTime:e.ownerStartTime},{pid:t.ownerPid,startTime:t.ownerStartTime})}async function fe(e,t){let n=b(),r;try{r=w.readdirSync(n,{withFileTypes:!0})}catch{return{examined:0,reconciled:0,retained:0,changed:0}}let i=0,a=0,o=0,s=0;for(let c of r){if(!c.isFile()||!c.name.endsWith(`.json`))continue;let r=C.join(n,c.name),l=_(r);if(!l?.claim||!J(l.classification,l.claim.stateDir,t))continue;i+=1;let{deviceKey:u,ownerToken:d}=l.claim;if(g(u)!==r){o+=1;continue}await O(u,async()=>{let n=_(r);if(!n?.claim||!J(n.classification,n.claim.stateDir,t)||n.claim.ownerToken!==d){s+=1;return}if((await k(n.claim,e)).status===`retained`){o+=1;return}a+=1})}return{examined:i,reconciled:a,retained:o,changed:s}}function J(e,t,n){return y(e)?e!==`owner-daemon-superseded`||C.resolve(t)===C.resolve(n):!1}const Y=S({resourceKind:`app-log`,fileName:`app-log.resource.json`,displayName:`App-log`}),X=x({resourceKind:`app-log`,displayName:`app-log`,store:Y,sessionSlot:{read:e=>e.appLog,replace:(e,t)=>({...e,appLog:t,appLogFailure:void 0})},completionMetadata:e=>({backend:e.backend,outputPath:e.outputPath,completedAt:e.completedAt}),failedFinishPolicy:`dispose-on-failed-finish`,messages:{noActive:`no app log stream active`,cleanupPendingHint:`Keep app-log.resource.json and retry cleanup through its exact runtime owner.`}});function pe(e){if(e.appLog){let t=e.appLog.handle.inspect();return{active:t.state===`active`||t.state===`recovering`,...t}}return e.appLogFailure?{active:!1,state:`failed`,backend:e.appLogFailure.backend,failureCode:e.appLogFailure.code,failureMessage:e.appLogFailure.message,hint:e.appLogFailure.hint}:{active:!1,state:`inactive`}}function me(e){return X.adoptStarted(e)}function he(e){return X.finishLive(e)}function ge(e){return X.forceCleanupLive(e)}function _e(e){let n=t(e.error);return e.sessionStore.set(e.sessionName,{...e.session,appLog:void 0,appLogFailure:{backend:e.backend,code:n.code,message:n.message,hint:n.hint}}),n}function ve(e){e.sessionStore.set(e.sessionName,{...e.session,appLogFailure:void 0})}const ye=S({resourceKind:`audio-probe`,fileName:`audio-probe.resource.json`,displayName:`Audio probe`}),Z=x({resourceKind:`audio-probe`,displayName:`audio probe`,store:ye,sessionSlot:{read:e=>e.audioProbe,replace:(e,t)=>({...e,audioProbe:t})},completionMetadata:e=>({backend:e.backend??`unknown`,source:e.source,durationMs:e.durationMs,elapsedMs:e.elapsedMs,bucketMs:e.bucketMs,sampleCount:e.sampleCount,heard:e.heard}),failedFinishPolicy:`dispose-on-failed-finish`,messages:{noActive:`no active audio probe`,cleanupPendingHint:`Keep audio-probe.resource.json and retry stop through its exact runtime owner.`}});function be(e){return Z.adoptStarted(e)}function xe(e){return Z.finishLive(e)}const Q=S({resourceKind:`perf-capture`,fileName:`perf-capture.resource.json`,displayName:`Perf capture`}),$=x({resourceKind:`perf-capture`,displayName:`perf capture`,store:Q,sessionSlot:{read:e=>e.perfCapture,replace:(e,t)=>({...e,perfCapture:t})},completionMetadata:e=>({kind:typeof e.kind==`string`?e.kind:`unknown`,mode:typeof e.mode==`string`?e.mode:`unknown`,...typeof e.outPath==`string`?{outPath:e.outPath}:{}}),failedFinishPolicy:`preserve-retry-material`,messages:{noActive:`no active native perf capture`,cleanupPendingHint:`Keep perf-capture.resource.json and retry stop through its exact runtime owner.`}});function Se(e){return $.adoptStarted(e)}function Ce(e){return $.finishLive(e)}function we(e){if(e.area===`frames`)return Object.freeze({kind:`frames`,request:e,use:c});if(e.area===`memory`)return e.action===`snapshot`?Object.freeze({kind:`memory-snapshot`,request:e,use:o}):Object.freeze({kind:`memory-sample`,request:e,use:s});if(e.area===`trace`)return e.action===`start`?Object.freeze({kind:`capture-start`,request:e,use:l}):Object.freeze({kind:`capture-stop`,request:e});switch(e.action){case`start`:return Object.freeze({kind:`capture-start`,request:e,use:l});case`stop`:return Object.freeze({kind:`capture-stop`,request:e});case`report`:return Object.freeze({kind:`profile-report`,request:e,use:a})}}function Te(t){let n=t.positionals??[],r=n[0]?.toLowerCase();if(r===`frames`){let i=n[1]?.toLowerCase();if(i!==void 0&&i!==`sample`||n.length>2||t.kind!==void 0)throw new e(`INVALID_ARGS`,`perf action must be frames, memory sample|snapshot, cpu profile start|stop|report, or trace start|stop`);return Object.freeze({area:r,action:`sample`})}if(r===`memory`)return Ee(n,t);if(r===`cpu`)return De(n,t.outPath);if(r===`trace`)return Oe(n,t.outPath);throw new e(`INVALID_ARGS`,`perf requires frames, memory, cpu, or trace`)}function Ee(t,n){let r=(t[1]??`sample`).toLowerCase();if(r!==`sample`&&r!==`snapshot`)throw new e(`INVALID_ARGS`,`perf memory requires sample or snapshot`);if(n.kind!==void 0&&r!==`snapshot`)throw new e(`INVALID_ARGS`,`--kind is only supported with perf memory snapshot`);if(r===`sample`&&t.length>2)throw new e(`INVALID_ARGS`,`perf memory sample does not accept additional positionals`);if(r===`snapshot`&&t.length>3)throw new e(`INVALID_ARGS`,`perf memory snapshot accepts at most one positional kind`);let i=n.kind??t[2];if(i!==void 0&&!u(i))throw new e(`INVALID_ARGS`,`perf memory snapshot --kind must be android-hprof or memgraph`);return Object.freeze({area:`memory`,action:r,...i===void 0?{}:{kind:i},...n.outPath===void 0?{}:{outPath:n.outPath}})}function De(t,n){if(t[1]?.toLowerCase()!==`profile`)throw new e(`INVALID_ARGS`,`perf cpu requires profile`);let r=t[2]?.toLowerCase();if(r!==`start`&&r!==`stop`&&r!==`report`)throw new e(`INVALID_ARGS`,`perf cpu profile action must be start, stop, or report`);let i=t[3]?.toLowerCase();if(i!==`xctrace`&&i!==`simpleperf`)throw new e(`INVALID_ARGS`,`perf cpu profile requires --kind xctrace or simpleperf`);let a=n??t[5];return Object.freeze({area:`cpu`,subject:`profile`,action:r,kind:i,...t[4]?{template:t[4]}:{},...a?{outPath:a}:{},...t[6]?{tracePath:t[6]}:{}})}function Oe(t,n){let r=t[1]?.toLowerCase();if(r!==`start`&&r!==`stop`)throw new e(`INVALID_ARGS`,`perf trace action must be start or stop`);let i=t[2]?.toLowerCase();if(i!==`xctrace`&&i!==`perfetto`)throw new e(`INVALID_ARGS`,`perf trace requires --kind xctrace or perfetto`);let a=n??t[4];return Object.freeze({area:`trace`,action:r,kind:i,...t[3]?{template:t[3]}:{},...a?{outPath:a}:{}})}export{fe as C,V as S,ue as T,le as _,$ as a,ce as b,xe as c,ve as d,he as f,Y as g,_e as h,Ce as i,me as l,pe as m,we as n,be as o,ge as p,Se as r,Z as s,Te as t,X as u,R as v,U as w,H as x,z as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{r as t}from"./diagnostics.js";import{_ as n,c as r,g as i,l as a,n as o,t as s}from"./exec.js";import"./diagnostics2.js";import"./command.js";import{f as c}from"./adb-executor.js";import{c as l}from"./adb-transport.js";import"./mechanics.js";import u from"node:path";import{constants as d}from"node:fs";import{createHash as f,randomUUID as p}from"node:crypto";import m from"node:os";import{access as h,mkdir as g,mkdtemp as _,open as v,readFile as y,readdir as b,rename as x,rm as S,stat as C,writeFile as w}from"node:fs/promises";var T=e({});const E=process.env;c({environment:E,files:{access:async e=>await h(e),ensureDirectory:async e=>{await g(e,{recursive:!0})},isExecutable:async e=>{try{return await h(e,d.X_OK),!0}catch{return!1}},makeTempDirectory:async e=>await _(u.join(m.tmpdir(),e)),readBytes:async e=>await y(e),readDirectory:async e=>await b(e),readText:async e=>await y(e,`utf8`),remove:async(e,t)=>await S(e,t),stat:async e=>{let t=await C(e);return{isFile:t.isFile(),size:t.size}},sha256:e=>f(`sha256`).update(e).digest(`hex`),writeAtomicText:async(e,t,n=384)=>{let r=u.dirname(e),i=u.join(r,`.${u.basename(e)}.${p()}.tmp`),a,o=!1;try{a=await v(i,`wx`,n),await a.writeFile(t,`utf8`),await a.sync(),await a.close(),a=void 0,await x(i,e),o=!0;let s;try{s=await v(r,`r`),await s.sync()}catch{}finally{s&&await s.close().catch(()=>{})}}finally{a&&await a.close().catch(()=>{}),o||await S(i,{force:!0}).catch(()=>{})}},writeBytes:async(e,t)=>await w(e,t)},execAdb:async(e,t)=>{let n=l(e,t,E);return await r(`adb`,n.args,{...n.options,detached:process.platform!==`win32`})},spawnAdb:(e,t)=>{let n=l(e,t,E),r=a(`adb`,n.args,{...n.options,allowFailure:!0,captureOutput:!1});return r.wait.catch(()=>{}),r.child},withAdbCommandExecutorOverride:i,withoutAdbCommandExecutorOverride:n,coerceAdbResult:s,execFailureDetails:o,emitDiagnostic:t,imeRecoveryMarkers:{write:async(e,t)=>{let{writeAndroidTestImeRecoveryMarker:n}=await import(`./mechanics.js`).then(e=>e.r);return await n(e,t)},clear:async(e,t)=>{let{clearAndroidTestImeRecoveryMarker:n}=await import(`./mechanics.js`).then(e=>e.r);await n(e,t)},read:async e=>{let{readAndroidTestImeRecoveryMarkers:t}=await import(`./mechanics.js`).then(e=>e.r);return await t(e)}},resolveHelperArtifact:async e=>{let{resolveAndroidHelperArtifact:t}=await import(`./mechanics.js`).then(e=>e.r);return await t(e)},ensureHelperInstalled:async(e,t)=>{let{makeEnsureAndroidHelperInstalled:n}=await import(`./mechanics.js`).then(e=>e.r);return await n(e)(t)}});export{T as t};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{C as e,T as t,j as n}from"./sdk-contracts.js";import{u as r}from"./sdk-device.js";import{i,o as a,r as o,s,t as ee}from"./apple-runner-platform.js";import c from"node:path";import l from"node:fs";import u from"node:crypto";import te from"node:os";let d;function ne(e){if(d&&d!==e)throw Error(`Apple runner host is already bound to a different implementation.`);d=e}function f(){if(!d)throw Error(`Apple runner host is not bound. Construct the client via createAppleRunnerClient() before using runner operations.`);return d}const re=(e,t,n)=>f().runCmdStreaming(e,t,n),ie=(e,t,n)=>f().runCmdSync(e,t,n),ae=(e,t,n)=>f().runCmdBackground(e,t,n),oe=(e,t,n)=>f().requireExecSuccess(e,t,n),se=e=>f().isCommandTimeoutError(e),ce=e=>f().shellQuote(e),le=e=>f().emitDiagnostic(e),ue=(e,t,n)=>f().withDiagnosticTimer(e,t,n),de=(e,t,n)=>f().retryWithPolicy(e,t,n),p=e=>f().isEnvTruthy(e),fe=e=>f().isProcessAlive(e),pe=e=>f().isProcessGroupAlive(e),me=e=>f().readProcessStartTime(e),he=e=>f().readProcessCommand(e),ge=(e,t)=>f().signalPidsBestEffort(e,t),_e=(e,t)=>f().signalProcessGroupBestEffort(e,t),m=()=>f().findProjectRoot(),ve=e=>f().readVersion(e),ye=e=>f().acquireProcessLock(e),be=(e,t,n)=>f().withKeyedLock(e,t,n),
|
|
2
|
-
`,` `)}`):{ok:!0,value:{version:t,buildVersion:n}}}function
|
|
1
|
+
import{C as e,T as t,j as n}from"./sdk-contracts.js";import{u as r}from"./sdk-device.js";import{i,o as a,r as o,s,t as ee}from"./apple-runner-platform.js";import c from"node:path";import l from"node:fs";import u from"node:crypto";import te from"node:os";let d;function ne(e){if(d&&d!==e)throw Error(`Apple runner host is already bound to a different implementation.`);d=e}function f(){if(!d)throw Error(`Apple runner host is not bound. Construct the client via createAppleRunnerClient() before using runner operations.`);return d}const re=(e,t,n)=>f().runCmdStreaming(e,t,n),ie=(e,t,n)=>f().runCmdSync(e,t,n),ae=(e,t,n)=>f().runCmdBackground(e,t,n),oe=(e,t,n)=>f().requireExecSuccess(e,t,n),se=e=>f().isCommandTimeoutError(e),ce=e=>f().shellQuote(e),le=e=>f().emitDiagnostic(e),ue=(e,t,n)=>f().withDiagnosticTimer(e,t,n),de=(e,t,n)=>f().retryWithPolicy(e,t,n),p=e=>f().isEnvTruthy(e),fe=e=>f().isProcessAlive(e),pe=e=>f().isProcessGroupAlive(e),me=e=>f().readProcessStartTime(e),he=e=>f().readProcessCommand(e),ge=(e,t)=>f().signalPidsBestEffort(e,t),_e=(e,t)=>f().signalProcessGroupBestEffort(e,t),m=()=>f().findProjectRoot(),ve=e=>f().readVersion(e),ye=e=>f().acquireProcessLock(e),be=e=>f().withProcessLock(e),xe=(e,t,n)=>f().withKeyedLock(e,t,n),Se=e=>f().publishFileSync(e),Ce=e=>f().classifyOwnerLiveness(e),h=e=>f().createTtlMemo(e),g=e=>f().parseBooleanLiteral(e),_=e=>f().isRecord(e),v=e=>f().resolveIosSimulatorDeviceSetPath(e),y=e=>f().emitRequestProgress(e),b=e=>f().getRequestSignal(e),x=e=>f().isRequestCanceled(e),S=e=>f().classifyBootFailure(e),C=e=>f().bootFailureHint(e),w=(e,t,n)=>f().runAppleToolCommand(e,t,n),T=(e,t)=>f().runXcrun(e,t),E=(e,t)=>f().readApplePlistJson(e,t),D=(e,t)=>f().buildSimctlArgsForDevice(e,t),O=e=>f().resolveIosPhysicalDeviceControl(e),k=(e,t)=>f().visitXmlPlistEntries(e,t),A=()=>f().leaseOwnerStateDir(),we=e=>f().hasDeviceClaimAuthority(e),j={fromTimeoutMs(e,t){return f().deadlineFromTimeoutMs(e,t)}},Te=c.join(`apple`,`runner`,`AgentDeviceRunner`),Ee=c.join(`dist`,`apple`,`runner`,`AgentDeviceRunner`),De=c.join(`apple`,`snapshot-presentation`),Oe=c.join(`dist`,`apple`,`snapshot-presentation`);function M(e){let t=c.join(e,Te);return l.existsSync(t)?t:c.join(e,Ee)}function ke(e){return c.join(M(e),`AgentDeviceRunner.xcodeproj`)}function Ae(e){let t=c.join(e,De);return l.existsSync(t)?t:c.join(e,Oe)}const je=new Set([`.build`,`.swiftpm`,`xcuserdata`]),Me=new Set([`.build`,`.swiftpm`,`SnapshotPresentationConformance`,`Tests`,`xcuserdata`]),N=new Map;function Ne(e){let t=[{path:M(e),ignoredDirectoryNames:je},{path:Ae(e),ignoredDirectoryNames:Me}],n=Fe(t),r=Pe(e,n),i=JSON.stringify(t.map(({path:e})=>e)),a=N.get(i);if(a?.fileStatsFingerprint===r)return a.sourceFingerprint;let o=u.createHash(`sha256`);for(let t of n){let n=c.relative(e,t);o.update(n),o.update(`\0`),o.update(l.readFileSync(t)),o.update(`\0`)}let s=o.digest(`hex`);return N.set(i,{fileStatsFingerprint:r,sourceFingerprint:s}),s}function Pe(e,t){let n=u.createHash(`sha256`);for(let r of t){let t=c.relative(e,r),i=l.statSync(r);n.update(t),n.update(`\0`),n.update(String(i.size)),n.update(`\0`),n.update(String(Math.trunc(i.mtimeMs))),n.update(`\0`)}return n.digest(`hex`)}function Fe(e){return[...new Set(e.flatMap(({path:e,ignoredDirectoryNames:t})=>Ie(e,t)))].sort((e,t)=>e.localeCompare(t))}function Ie(e,t){return l.existsSync(e)?P(e,t):[]}function P(e,t){let n=[];for(let r of l.readdirSync(e,{withFileTypes:!0})){let i=c.join(e,r.name);r.isDirectory()?t.has(r.name)||n.push(...P(i,t)):r.isFile()&&Le(r.name,i)&&n.push(i)}return n}function Le(e,t){return e===`project.pbxproj`?t.includes(`${c.sep}.xcodeproj${c.sep}`):[`.jpg`,`.json`,`.png`,`.swift`,`.m`,`.h`,`.plist`,`.entitlements`,`.xctestplan`,`.xcconfig`,`.storyboard`,`.xib`].includes(c.extname(e))}const F=c.join(te.homedir(),`.agent-device`,`apple-runner`),Re=`.agent-device-runner-cache.json`,ze=[`-IDEPackageSupportDisableManifestSandbox=1`,`-IDEPackageSupportDisablePluginExecutionSandbox=1`,`ENABLE_USER_SCRIPT_SANDBOXING=NO`];function Be(e,t){return{deadline:e!==void 0&&Number.isFinite(e)?j.fromTimeoutMs(Math.max(0,e)):void 0,signal:t}}function Ve(e,t){let n=e?.deadline;if(!n)return;let r=Math.floor(n.remainingMs());if(r<=0)throw I(t);return r}function I(t){return new e(`COMMAND_FAILED`,`The Apple runner budget ran out before this step began`,{phase:t,reason:`runner_phase_budget_exhausted`,retriable:!0})}function He(e){let n=e?.deadline,r=j.fromTimeoutMs(Math.min(45e3,n?n.remainingMs():1/0));return{attemptTimeoutMs:()=>Math.min(ee,Math.floor(r.remainingMs())),throwIfCanceled:()=>{if(e?.signal?.aborted)throw t({phase:`apple_toolchain_probe`})}}}function L(e){return e?.trim()??``}function R(e=process.env){return L(e.AGENT_DEVICE_IOS_BUNDLE_ID)||L(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||`com.callstack.agentdevice.runner`}function z(e=process.env){return L(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID)||`${R(e)}.uitests`}function Ue(e=process.env){let t=R(e),n=z(e);return Array.from(new Set([L(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}const We=Ue(process.env);function Ge(e,t=m(),n){let r=a(e);return{schemaVersion:2,packageVersion:ve(t),runnerSourceFingerprint:Ne(t),...Ke(s(r,e.kind),n),platformName:r,deviceKind:e.kind,target:e.target??`mobile`,buildDestinationFamily:o(e),runnerBundleBuildSettings:Z(process.env),runnerSigningBuildSettings:X(process.env,e.kind===`device`,e),runnerPerformanceBuildSettings:Q(),runnerSandboxBuildArgs:$()}}let B;function V(){return B??=h(),B}function Ke(e,t){let n=He(t);n.throwIfCanceled();let r=V().get(e);if(r)return r;let i=qe(e,n);if(!i.ok)throw Je(i.failures);return V().set(e,i.value),i.value}function qe(e,t){let n=Ze(H(`xcodebuild`,[`-version`],t)),r=H(`xcrun`,[`--sdk`,e,`--show-sdk-version`],t),i=H(`xcrun`,[`--sdk`,e,`--show-sdk-build-version`],t);return!n.ok||!r.ok||!i.ok?{ok:!1,failures:[n,r,i].flatMap(e=>e.ok?[]:[e.failure])}:{ok:!0,value:{xcodeVersion:n.value.version,xcodeBuildVersion:n.value.buildVersion,sdkName:e,sdkVersion:r.value,sdkBuildVersion:i.value}}}function Je(t){return new e(`COMMAND_FAILED`,`Could not read the Xcode toolchain versions the Apple runner cache is keyed on (${t.map(e=>`${e.probe}: ${e.detail}`).join(`; `)})`,{reason:`apple_toolchain_probe_unavailable`,retriable:!0,probes:t,hint:"The Apple runner cache is keyed on the toolchain version, so a cache decision cannot be made without it. Retry once the host is less loaded, or check `xcode-select -p` and `xcodebuild -version`."})}function H(e,t,r){let i=[e,...t].join(` `),a;try{a=Ye(e,t,r)}catch(e){if(r.throwIfCanceled(),n(e)||Xe(e))throw e;return W(i,`probe_error`,e instanceof Error?e.message:`${e}`)}if(a.exitCode!==0)return W(i,`nonzero_exit`,`exit ${a.exitCode}${a.stderr.trim()?`: ${a.stderr.trim()}`:``}`);let o=a.stdout.trim();return o?{ok:!0,value:o}:W(i,`empty_output`,`no output`)}function Ye(e,t,n){try{return U(e,t,n)}catch(r){if(!se(r))throw r;return U(e,t,n)}}function U(e,t,n){n.throwIfCanceled();let r=n.attemptTimeoutMs();if(r<=0)throw I(`apple_toolchain_probe`);return ie(e,t,{allowFailure:!0,timeoutMs:r,maxBuffer:131072})}function Xe(t){return t instanceof e&&t.details?.reason===`runner_phase_budget_exhausted`}function Ze(e){if(!e.ok)return e;let t=e.value.match(/^Xcode\s+(.+)$/m)?.[1]?.trim(),n=e.value.match(/^Build version\s+(.+)$/m)?.[1]?.trim();return!t||!n?W(`xcodebuild -version`,`unparsable_output`,`unrecognized output: ${e.value.replaceAll(`
|
|
2
|
+
`,` `)}`):{ok:!0,value:{version:t,buildVersion:n}}}function W(e,t,n){return{ok:!1,failure:{probe:e,reason:t,detail:n.length>200?`${n.slice(0,200)}…`:n}}}function Qe(e,t){let n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim();if(n)return c.resolve(n);let r=et(t),i=$e(e);return c.join(i,r)}function $e(e){return c.join(F,`derived`,i(e))}function et(e){return`cache-${u.createHash(`sha256`).update(J(G(e))).digest(`hex`).slice(0,16)}`}function G(e){let{artifacts:t,packageVersion:n,...r}=e;return r}function tt(e,t){let n=G(e),r=G(t);return[...new Set([...Object.keys(n),...Object.keys(r)])].sort((e,t)=>e.localeCompare(t)).flatMap(e=>{let t=K(n[e]),i=K(r[e]);return t===i?[]:[{key:e,expected:q(t),actual:q(i)}]})}function K(e){return e===void 0?`(absent)`:J(e)}function q(e){return e.length<=300?e:`${e.slice(0,149)}…${e.slice(-149)}`}function J(e){return JSON.stringify(Y(e))}function Y(e){return Array.isArray(e)?e.map(e=>Y(e)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,Y(t)]))}function nt(e){return r(e)||e.kind===`device`?`-maximum-concurrent-test-device-destinations`:`-maximum-concurrent-test-simulator-destinations`}function X(e=process.env,t=!1,n={platform:`apple`}){if(r(n))return[`CODE_SIGNING_ALLOWED=NO`,`CODE_SIGNING_REQUIRED=NO`,`CODE_SIGN_IDENTITY=`,`DEVELOPMENT_TEAM=`];if(!t)return[];let i=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||``,a=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||``,o=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||``,s=[`CODE_SIGN_STYLE=${o?`Manual`:`Automatic`}`];return i&&s.push(`DEVELOPMENT_TEAM=${i}`),a&&s.push(`CODE_SIGN_IDENTITY=${a}`),o&&s.push(`PROVISIONING_PROFILE_SPECIFIER=${o}`),s}function Z(e=process.env){let t=R(e),n=z(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}function Q(){return[`COMPILER_INDEX_STORE_ENABLE=NO`,`ENABLE_CODE_COVERAGE=NO`,`ONLY_ACTIVE_ARCH=YES`,`ENABLE_PREVIEWS=NO`,`ENABLE_DEBUG_DYLIB=NO`]}function $(){return[...ze,`OTHER_SWIFT_FLAGS=${rt(process.env)}`]}function rt(e){return p(e.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS)?`$(inherited) -disable-sandbox -D AGENT_DEVICE_RUNNER_UNIT_TESTS`:`$(inherited) -disable-sandbox`}export{xe as $,fe as A,oe as B,Ce as C,b as D,m as E,g as F,ae as G,v as H,Se as I,ce as J,re as K,E as L,_ as M,x as N,we as O,A as P,ue as Q,he as R,S,y as T,de as U,O as V,w as W,_e as X,ge as Y,k as Z,j as _,tt as a,C as b,R as c,nt as d,be as et,Q as f,ke as g,J as h,Be as i,pe as j,p as k,Z as l,X as m,Re as n,Ve as o,$ as p,T as q,G as r,Ge as s,We as t,Qe as u,ye as v,le as w,D as x,ne as y,me as z};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{C as t,T as n,j as r,w as i}from"./sdk-contracts.js";import{g as a}from"./sdk-batch-runner.js";import{c as o,l as s}from"./sdk-device.js";import{o as c}from"./sdk-remote-config.js";import{c as l,r as u}from"./diagnostics.js";import{D as d,S as f,m as p,p as m,t as h,x as g,y as _}from"./owner-identity.js";import{a as ee,f as te,l as ne,m as re,p as ie,r as ae}from"./exec.js";import{t as oe}from"./file.js";import"./diagnostics2.js";import{n as se}from"./command.js";import{i as ce,n as le,r as ue}from"./retry.js";import{n as de,r as fe}from"./version.js";import{t as pe}from"./ttl-memo.js";import"./process.js";import{n as me,t as he}from"./boot-diagnostics.js";import{t as ge}from"./keyed-lock.js";import{i as _e,r as ve}from"./request-cancel.js";import{t as ye}from"./request.js";import{r as be}from"./device-isolation.js";import{a as xe,o as Se,r as Ce}from"./tool-provider.js";import{t as we}from"./physical-device-control.js";import{t as Te}from"./simctl.js";import{a as Ee,i as De,o as Oe}from"./runner.js";import{$ as ke,A as v,B as Ae,F as je,G as Me,H as Ne,Q as Pe,T as Fe,U as Ie,W as y,_ as Le,c as Re,d as ze,i as b,o as Be,q as Ve,s as He,t as Ue,u as We,w as x,x as Ge,y as Ke}from"./runner-cache-metadata.js";import{a as qe}from"./apple-runner-platform.js";import{A as S,B as Je,C as Ye,E as Xe,F as Ze,I as Qe,L as $e,M as et,N as C,O as w,P as tt,R as T,S as nt,T as rt,_ as E,a as D,b as it,c as at,d as ot,f as st,g as ct,h as O,i as lt,j as ut,k as dt,l as ft,m as pt,n as mt,o as ht,p as gt,r as _t,t as k,u as vt,v as yt,w as bt,x as xt,y as St,z as Ct}from"./runner-disposal.js";import{t as wt}from"./plist-xml.js";import{n as Tt,t as Et}from"./runner-owner-state.js";import A from"node:path";import Dt from"node:fs";import Ot from"node:fs/promises";const kt={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function At(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?A.resolve(i):A.dirname(e);Dt.mkdirSync(a,{recursive:!0});let o=n.replaceAll(/[^a-zA-Z0-9._-]/g,`_`),s=A.join(a,`AgentDeviceRunner.env.${o}.json`),c=A.join(a,`AgentDeviceRunner.env.${o}.xctestrun`),l=await jt(e);return Ft(l,e=>Nt(e,t)),Pt(l),await Mt(l,s,c),{xctestrunPath:c,jsonPath:s}}async function jt(e){let n=await y(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(n.exitCode!==0||!n.stdout.trim())throw new t(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:n.stderr});try{let e=JSON.parse(n.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(n){throw new t(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(n)})}}async function Mt(e,t,n){Dt.writeFileSync(t,JSON.stringify(e,null,2)),Ae(await y(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function Nt(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function Pt(e){Ft(e,e=>Object.assign(e,kt),{requireTestBundlePath:!0})}function Ft(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||It(e.TestTargets,t,n);for(let n of Object.values(e)){let e=Lt(n,{requireTestBundlePath:!0});e&&t(e)}}function It(e,t,n){if(Array.isArray(e))for(let r of e){let e=Lt(r,n);e&&t(e)}}function Lt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const Rt={tap:`preflightSkippableTouchMutation`,mouseClick:`default`,longPress:`preflightSkippableTouchMutation`,drag:`preflightSkippableTouchMutation`,remotePress:`default`,type:`default`,swipe:`preflightSkippableTouchMutation`,scroll:`preflightSkippableTouchMutation`,desktopScroll:`preflightSkippableTouchMutation`,findText:`readOnly`,querySelector:`readOnly`,readText:`readOnly`,snapshot:`readOnly`,screenshot:`readOnly`,back:`default`,backInApp:`default`,backSystem:`default`,home:`default`,rotate:`default`,gesture:`preflightSkippableTouchMutation`,gestureViewport:`readOnly`,appSwitcher:`default`,keyboardDismiss:`default`,keyboardReturn:`default`,alert:`alertAction`,sequence:`preflightSkippableTouchMutation`,recordStart:`default`,recordStop:`default`,status:`readOnlyReadinessProbe`,uptime:`readOnlyReadinessProbe`,activate:`readinessPreflightExemptMutation`,terminate:`readinessPreflightExemptMutation`,targetReset:`readinessPreflightExemptMutation`,shutdown:`default`},j={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},zt={...j,readinessPreflightExempt:!0},M={...j,readOnly:!0},Bt={...M,readinessProbe:!0},Vt={...j,readinessPreflightSkipEligibleAfterHealthyMutation:!0};function N(e){return P(e).readOnly}function Ht(e){return P(e).readinessProbe}function Ut(e){return P(e).readinessPreflightExempt}function Wt(e){return P(e).readinessPreflightSkipEligibleAfterHealthyMutation}function P(e){switch(Rt[e.command]){case`default`:return j;case`readinessPreflightExemptMutation`:return zt;case`readOnly`:return M;case`alertAction`:return(e.action??`get`).toLowerCase()===`get`?M:j;case`readOnlyReadinessProbe`:return Bt;case`preflightSkippableTouchMutation`:return Vt}}function Gt(e,t){return`${e}:${t}:${Date.now()}`}function Kt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}function qt(e=process.env){return je(e.AGENT_DEVICE_IOS_RUNNER_DETACH??``)!==!1}async function Jt(e,t){if(e.kind!==`simulator`||!qt()||Ne(e.simulatorSetPath))return null;let n=gt(e.id);if(!n)return null;let r=t=>(x({level:`debug`,phase:`ios_runner_lease_adoption_skipped`,data:{deviceId:e.id,runnerPid:n.runnerPid,port:n.port,reason:t}}),null);if(t.expectedRunnerSessionId!==void 0&&n.sessionId!==t.expectedRunnerSessionId)return r(`session_identity_mismatch`);let i=n.runnerPid;if(!i)return r(`runner_pid_missing`);if(!v(i))return r(`runner_process_dead`);if(!O(n,i))return r(`runner_pid_recycled`);let a=Xt(e,t.budget);if(!a)return r(`expected_derived_unresolved`);if(!n.xctestrunPath.startsWith(`${a}${A.sep}`))return r(`artifact_fingerprint_mismatch`);if(!await Yt(e,n.port))return r(`probe_failed`);if(!v(i)||!O(n,i))return r(`runner_pid_recycled`);let o=Zt(e,n,i,a,t);try{E(o.lease)}catch{return null}return x({level:`info`,phase:`ios_runner_lease_adopted`,data:{deviceId:e.id,sessionId:o.sessionId,runnerPid:i,port:n.port,previousOwnerPid:n.ownerPid}}),o}async function Yt(e,t){try{let n=await Xe(e,t,T({command:`uptime`}),500);return JSON.parse(await n.text())?.ok===!0}catch{return!1}}function Xt(e,t){try{return We(e,He(e,void 0,t))}catch(e){if(r(e))throw e;return null}}function Zt(e,t,n,r,i){let a=t.sessionId,o={xctestrunPath:t.xctestrunPath,derived:r,cache:`exact`,artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`,reason:`adopted_from_lease`},{child:s,wait:c}=Qt(n);return{sessionId:a,device:e,deviceId:e.id,port:t.port,xctestrunPath:t.xctestrunPath,xctestrunArtifact:o,jsonPath:t.jsonPath,testPromise:c,child:s,ready:!0,startupTimeoutMs:Kt(Be(i.budget,`runner_session_adoption`)),lease:vt({deviceId:e.id,sessionId:a,runnerPid:n,port:t.port,xctestrunPath:t.xctestrunPath,jsonPath:t.jsonPath})}}function Qt(e){let t={pid:e,exitCode:null};return{child:t,wait:new Promise(n=>{let r=setInterval(()=>{v(e)||(clearInterval(r),t.exitCode=-1,n({stdout:``,stderr:``,exitCode:-1}))},1e3);r.unref?.()})}}async function $t(e){let n=await en(e.logPath)??nn(e.error);return n?new t(n.code??e.error.code,e.error.message,{...e.error.details??{},hint:typeof e.error.details?.hint==`string`?`${e.error.details.hint} ${n.hint}`:n.hint,runnerFailureReason:n.reason},e.error):e.error}async function en(e){if(!e)return;let t=await sn(e,65536);if(t)return tn(t)}function tn(e){let t=e.toLowerCase();if(rn(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_axruntime_coretext_crash`,hint:`The target iOS app appears to have crashed while XCTest/AXRuntime read accessibility attributes. This is usually a simulator/XCTest/runtime or app accessibility payload issue, not a text-entry failure. Reproduce on the latest stable simulator runtime, reinstall the app, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`};if(an(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_crash`,hint:`The target iOS app appears to have crashed while the runner was executing the command. Reopen or reinstall the app, retry on a fresh/latest stable simulator runtime, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`}}function nn(e){if(on(e.message))return{reason:`runner_main_thread_execution_timeout`,hint:`XCTest timed out waiting for main-thread work on the current iOS screen. The app may still be visually responsive, especially on focused React Native overlays or animating screens. Use screenshot as visual truth, use coordinate presses only to prove or leave the state, and retry snapshot -i after the UI settles or after navigating away.`}}function rn(e){return e.includes(`axruntime`)&&e.includes(`coretext`)&&(e.includes(`attributesforelement`)||e.includes(`axuielementcopymultipleattributevalues`)||e.includes(`reconstitutedsmuggledctfontfromdictionary`)||e.includes(`reconstitutedsmuggledattributedstringfromdictionary`))}function an(e){return e.includes(`process crashed`)||e.includes(`the application under test`)||e.includes(`terminated unexpectedly`)||e.includes(`exception type:`)&&e.includes(`thread 0 crashed`)}function on(e){return e.toLowerCase().includes(`main thread execution timed out`)}async function sn(e,t){let n;try{let r=await Ot.stat(e),i=Math.max(0,r.size-t),a=r.size-i;if(a<=0)return;n=await Ot.open(e,`r`);let o=Buffer.alloc(a);return await n.read(o,0,a,i),o.toString(`utf8`)}catch{return}finally{await n?.close().catch(()=>{})}}function cn(){let e=new AbortController,t=!1,n={stdout:``,stderr:``};return{wake:e.signal,observe:(r,i)=>{if(t)return;let a=n[r]+i;if(a.includes(`AGENT_DEVICE_RUNNER_LISTENER_READY`)){t=!0,n.stdout=``,n.stderr=``,e.abort();return}n[r]=a.slice(-33)},finish:()=>{t=!0,n.stdout=``,n.stderr=``,e.abort()}}}function ln(e){let t=cn(),n=Me(`xcodebuild`,[`test-without-building`,`-only-testing`,`AgentDeviceRunnerUITests/RunnerTests/testCommand`,`-parallel-testing-enabled`,`NO`,`-test-timeouts-enabled`,`NO`,`-collect-test-diagnostics`,`never`,ze(e.device),`1`,`-destination-timeout`,`20`,`-xctestrun`,e.xctestrunPath,`-derivedDataPath`,e.derivedPath,`-destination`,qe(e.device)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(e.port)},detached:!0,signal:e.signal}),r=(n,r)=>{t.observe(n,r),Je(r,e.logPath,e.traceLogPath,e.verbose)};return n.child.stdout?.on(`data`,e=>r(`stdout`,e)),n.child.stderr?.on(`data`,e=>r(`stderr`,e)),n.wait.then(t.finish,t.finish),{...n,startupRetryWake:t.wake}}const F=new Map,un=new Map,I=new Map,dn=1e4;function L(e,t){return ke(un,e,t)}async function R(e,t){return H(e.id),await L(e.id,async()=>{let n=b(t.startupTimeoutMs,C(t)),r=F.get(e.id);if(r){pn(r,t.expectedRunnerSessionId);let i=await gn(e,r,n);if(i)return i}return await ct(e.id,async()=>await fn(e,t,n))})}async function fn(e,t,r){let i={},a=r.signal,o=Xn(t.runnerLeaseContext,e.id);x({level:`debug`,phase:`ios_runner_session_startup`,data:{deviceId:e.id,logicalLeaseContext:o}});let s=await G(i,`adopt_detached_runner`,async()=>await Jt(e,{budget:r,expectedRunnerSessionId:t.expectedRunnerSessionId}));if(s)return s.startupTimings=i,s.logicalLeaseContext=o,F.set(e.id,s),s;mn(t.expectedRunnerSessionId),await G(i,`cleanup_stale_xcodebuild`,async()=>{await st(e,ht,o)}),await G(i,`ensure_booted`,async()=>{await On(e)}),await G(i,`verify_developer_mode`,async()=>{await An(e)}),t.cleanStaleBundles?await G(i,`cleanup_stale_bundles`,async()=>{await _n(e)}):(i.cleanup_stale_bundles=0,x({level:`debug`,phase:`ios_runner_startup_cleanup_stale_bundles_skipped`}));let c=Be(r,`runner_session_startup`),l=await G(i,`ensure_xctestrun`,async()=>await yt(e,{...t,budget:b(t.buildTimeoutMs,a)}));i.build_xctestrun=l.buildMs;let u=await G(i,`allocate_port`,async()=>await Ct()),{xctestrunPath:d,jsonPath:f}=await G(i,`prepare_xctestrun_env`,async()=>await At(l.xctestrunPath,{AGENT_DEVICE_RUNNER_PORT:String(u)},`session-${e.id}-${pt()}-${u}`,{iosXctestEnvDir:t.iosXctestEnvDir})),p=await G(i,`simulator_set_redirect`,async()=>await nt(e)),m;try{l.buildMs>0&&Fe({type:`command`,status:`progress`,message:`Starting XCTest runner...`}),m=await G(i,`launch_xcodebuild`,()=>ln({device:e,port:u,xctestrunPath:d,derivedPath:l.derived,signal:a,logPath:t.logPath,traceLogPath:t.traceLogPath,verbose:t.verbose}))}catch(e){throw await p?.release(),e}let h=Gt(e.id,u),g=vt({deviceId:e.id,sessionId:h,runnerPid:m.child.pid,port:u,xctestrunPath:d,jsonPath:f}),_={sessionId:h,device:e,deviceId:e.id,port:u,xctestrunPath:d,xctestrunArtifact:l,jsonPath:f,testPromise:m.wait,child:m.child,ready:!1,startupRetryWake:m.startupRetryWake,startupTimeoutMs:Kt(c),startupTimings:i,logicalLeaseContext:o,simulatorSetRedirect:p??void 0,lease:g,speculative:t.speculative===!0};if(a?.aborted)throw await lt(_,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),n();try{E(g)}catch(t){throw await V(e.id,_,{graceful:!1,waitTimeoutMs:k,leaseLockHeld:!0}),t}return F.set(e.id,_),_}function pn(e,t){if(t!==void 0&&e.sessionId!==t)throw hn()}function mn(e){if(e!==void 0)throw hn()}function hn(){return new t(`COMMAND_FAILED`,`Apple runner session ownership changed before command dispatch`,{reason:`runner_session_ownership_changed`})}async function gn(e,t,n){if(!D(t.child.pid))return await G({},`stop_stale_session`,async()=>{await V(e.id,t,{graceful:!1,waitTimeoutMs:k})}),null;let r=t.xctestrunArtifact;if(r?.cache===`external`)return x({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.ready,cache:r.cache,logicalLeaseContext:t.logicalLeaseContext}}),t;let i=We(e,He(e,void 0,n));return r?.derived===i?(x({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.ready,logicalLeaseContext:t.logicalLeaseContext}}),t):(x({level:`debug`,phase:`ios_runner_session_artifact_stale`,data:{deviceId:e.id,sessionId:t.sessionId,currentDerived:r?.derived,expectedDerived:i}}),await G({},`stop_stale_artifact_session`,async()=>{await V(e.id,t)}),null)}async function _n(e){e.kind===`simulator`&&await Promise.allSettled(Ue.map(async t=>{let n=await vn(e,t);!n||yn(n)}))}async function vn(e,t){try{return await Ve(Ge(e,[`uninstall`,e.id,t]),{allowFailure:!0,timeoutMs:dn})}catch(n){x({level:`warn`,phase:`ios_runner_startup_cleanup_stale_bundle_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:dn,error:n instanceof Error?n.message:String(n)}});return}}function yn(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 z(e){let t=F.get(e);return t?{sessionId:t.sessionId,alive:D(t.child.pid),ready:t.ready}:null}async function B(e,t){await L(e.deviceId,async()=>{F.get(e.deviceId)===e&&(x({level:`warn`,phase:`ios_runner_session_invalidated`,data:{deviceId:e.deviceId,sessionId:e.sessionId,reason:t}}),await V(e.deviceId,e,{graceful:!1,waitTimeoutMs:k}))})}async function V(e,t,n={}){let r=t??F.get(e);r&&(await lt(r,n),F.get(e)===r&&F.delete(e))}function bn(e){H(e);let t=xn();if(t<=0||!F.has(e))return;let n=setTimeout(()=>{I.delete(e),x({level:`info`,phase:`ios_runner_idle_stop`,data:{deviceId:e,idleMs:t}}),U(e).catch(t=>{x({level:`warn`,phase:`ios_runner_idle_stop_failed`,data:{deviceId:e,error:t instanceof Error?t.message:String(t)}})})},t);n.unref?.(),I.set(e,n),x({level:`debug`,phase:`ios_runner_idle_stop_scheduled`,data:{deviceId:e,idleMs:t}})}function H(e){let t=I.get(e);t&&(clearTimeout(t),I.delete(e))}function xn(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 Sn(e,t){e.speculative&&!Ht(t)&&(e.speculative=!1)}async function Cn(e){return await L(e,async()=>{let t=F.get(e);return t?.speculative?(x({level:`debug`,phase:`ios_runner_speculative_released`,data:{deviceId:e,sessionId:t.sessionId,ready:t.ready}}),await U(e),!0):!1})}async function U(e){H(e),await L(e,async()=>{await ct(e,async()=>{await V(e,void 0,{leaseLockHeld:!0}),await _t(e)})})}async function wn(e,t){if(t.retain&&F.get(e)?.runnerMainThreadBusy!==!0){bn(e);return}t.retain&&x({level:`info`,phase:`ios_runner_retain_skipped_busy`,data:{deviceId:e}}),await U(e)}async function Tn(){let e=Array.from(F.values());await mt(e);for(let t of e)F.get(t.deviceId)===t&&F.delete(t.deviceId)}async function En(){if(!qt())return 0;let e=0;for(let[t,n]of F)if(n.device.kind===`simulator`&&!n.simulatorSetRedirect&&!(!n.lease||!D(n.child.pid))){try{E(ft(n.lease))}catch{continue}F.delete(t),H(t),e+=1,x({level:`info`,phase:`ios_runner_session_detached`,data:{deviceId:t,sessionId:n.sessionId,runnerPid:n.child.pid,port:n.port}})}return e}async function Dn(){await Tn();let e=Array.from(F.keys());await Promise.allSettled(e.map(async e=>{await U(e)})),await at()}function On(e){return e.kind===`simulator`?e.booted?(x({level:`debug`,phase:`ios_runner_startup_ensure_booted_skipped`,data:{deviceId:e.id}}),Promise.resolve()):kn(e):Promise.resolve()}async function kn(e){await Ve(Ge(e,[`bootstatus`,e.id,`-b`]),{timeoutMs:Ye})}async function An(e){if(!s(e)||e.kind!==`device`)return;let n=await y(`DevToolsSecurity`,[`-status`],{allowFailure:!0,timeoutMs:2e3}),r=`${n.stdout}\n${n.stderr}`;if(/developer mode is currently disabled/i.test(r))throw new t(`COMMAND_FAILED`,`Developer mode is disabled for Apple development tools`,{hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach.",devToolsSecurityStatus:r.trim()})}function jn(e){if(!o(e.platform))throw new t(`UNSUPPORTED_PLATFORM`,`Unsupported platform for iOS runner: ${e.platform}`);if(e.kind!==`simulator`&&e.kind!==`device`)throw new t(`UNSUPPORTED_OPERATION`,`Unsupported iOS device kind for runner: ${e.kind}`)}async function W(e,t,n,r,i,a){Yn(t,n.command);let o=T(n),s=N(o),c=Le.fromTimeoutMs(i),l=Gn(t,o);l.action===`run`?await In({device:e,session:t,runnerCommand:o,logPath:r,deadline:c,signal:a,decision:l}):Ln(o,t,l);let u;try{u=await Fn({device:e,session:t,runnerCommand:o,logPath:r,deadline:c,timeoutMs:i,signal:a,readOnlyCommand:s})}catch(e){throw Pn(e,t,l)}try{let e=await Rn(u,t,r),n=Mn(e);n!==void 0&&(t.runnerMainThreadBusy=n);let i=Wn(e);return i?(t.lastHealthyMutation=void 0,await B(t,i)):Wt(o)&&(t.lastHealthyMutation={atMs:Date.now(),appBundleId:o.appBundleId}),e}catch(e){ut(e)?t.runnerMainThreadBusy=!0:Nn(e)&&(t.runnerMainThreadBusy=!1);let n=et(e);throw n?(t.lastHealthyMutation=void 0,await B(t,n),e):Nn(e)?e:Pn(e,t,l)}}function Mn(e){return typeof e.runnerMainThreadBusy==`boolean`?e.runnerMainThreadBusy:void 0}function Nn(e){return e instanceof t&&e.details?.runner!==void 0}function Pn(e,t,n){return n.action!==`skip`||n.reason!==`recent_healthy_mutation`?e:(t.lastHealthyMutation=void 0,qn(e,{runnerReadinessPreflightSkipped:!0,runnerReadinessPreflightSkipReason:n.reason,runnerReadinessPreflightSkippedAgeMs:n.lastHealthyMutationAgeMs}))}async function Fn(e){let{device:n,session:r,runnerCommand:i,logPath:a,deadline:o,timeoutMs:s,signal:c,readOnlyCommand:l}=e,u=o.remainingMs();if(u<=0)throw new t(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:s});let d=l?{command:i.command,commandId:i.commandId,readOnly:!0,sessionReady:r.ready,timeoutMs:u}:{command:i.command,commandId:i.commandId};return await Pe(`ios_runner_command_send`,async()=>l?await bt(n,r.port,i,a,u,r,c):await Xe(n,r.port,i,u,c),d)}async function In(e){let{device:t,session:n,runnerCommand:r,logPath:i,deadline:a,signal:o,decision:s}=e,c=n.ready?Math.min(1e3,a.remainingMs()):Math.min(Jn(n),a.remainingMs());try{await Rn(await Pe(`ios_runner_readiness_preflight`,async()=>await bt(t,n.port,T({command:`uptime`}),i,c,n,o),{command:r.command,commandId:r.commandId,reason:s.reason,lastHealthyMutationAgeMs:s.lastHealthyMutationAgeMs,sessionReady:n.ready,timeoutMs:c}),n,i)}catch(e){throw Kn(e)}}function Ln(e,t,n){x({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:n.reason,lastHealthyMutationAgeMs:n.reason===`recent_healthy_mutation`?n.lastHealthyMutationAgeMs:void 0,sessionReady:t.ready}})}async function Rn(e,t,n){let r=zn(await e.text());if(!r.ok)throw await $t({error:Bn(r,n),logPath:n});return t.ready=!0,Hn(r)}function zn(e){try{let t=JSON.parse(e);return t&&typeof t==`object`?t:{}}catch{throw new t(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}}function Bn(e,n){let r=Vn(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=dt(r);return new t(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:n})}function Vn(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function Hn(e){if(!e.data||typeof e.data!=`object`||Array.isArray(e.data))return{};let t=e.data;return Un(t),t}function Un(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&x({level:`debug`,phase:`ios_runner_gesture_fallback`,data:{fallback:t,message:typeof e.gestureFallbackMessage==`string`?e.gestureFallbackMessage:void 0,hint:typeof e.gestureFallbackHint==`string`?e.gestureFallbackHint:void 0}})}function Wn(e){if(e.runnerFatal===!0)return typeof e.runnerFatalReason==`string`&&e.runnerFatalReason.trim().length>0?e.runnerFatalReason:`runner_reported_fatal_response`}function Gn(e,t){let n=N(t);if(Ut(t))return{action:`skip`,reason:`preflight_exempt_command`};if(!e.ready)return n?{action:`skip`,reason:`read_only_startup_command`}:{action:`run`,reason:`startup`};if(Ht(t))return{action:`skip`,reason:`readiness_probe_command`};if(!Wt(t))return{action:`run`,reason:`conservative_command`};let r=e.lastHealthyMutation;if(!r)return{action:`run`,reason:`no_recent_healthy_mutation`};if(t.appBundleId!==r.appBundleId)return{action:`run`,reason:`app_activation_uncertain`};let i=Date.now()-r.atMs;return i>5e3?{action:`run`,reason:`healthy_mutation_stale`,lastHealthyMutationAgeMs:i}:{action:`skip`,reason:`recent_healthy_mutation`,lastHealthyMutationAgeMs:i}}function Kn(e){return qn(e,{runnerReadinessPreflightFailed:!0})}function qn(e,n){let r=e instanceof t?e:new t(`COMMAND_FAILED`,e instanceof Error?e.message:String(e),void 0,e);return new t(r.code,r.message,{...r.details??{},...n},r.cause??e)}function Jn(e){return e.startupTimeoutMs??45e3}async function G(e,t,n){let r=Date.now();try{return await n()}finally{let n=Date.now()-r;e[t]=n,x({level:`debug`,phase:`ios_runner_startup_${t}`,durationMs:n})}}function Yn(e,t){if(e.startupTimingsReported||!e.startupTimings)return;e.startupTimingsReported=!0;let n=Object.values(e.startupTimings).reduce((e,t)=>e+t,0);x({level:`info`,phase:`ios_runner_session_startup_timings`,durationMs:n,data:{command:t,sessionId:e.sessionId,ready:e.ready,logicalLeaseContext:e.logicalLeaseContext,timings:e.startupTimings}})}function Xn(e,t){if(!e)return;let n={leaseId:K(e.leaseId),clientId:K(e.clientId),tenantId:K(e.tenantId),runId:K(e.runId),leaseProvider:K(e.leaseProvider),deviceKey:K(e.deviceKey)??t},r=Object.entries(n).filter(([,e])=>e!==void 0);return r.length>0?Object.fromEntries(r):void 0}function K(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}async function Zn(e){let{device:t,session:n,command:r,transportError:i,options:a,signal:o,invalidationReason:s}=e;return await Qn(await nr(t,n,r,i,a,o),{command:r,session:n,transportError:i,invalidationReason:s,invalidateSession:e.invalidateSession})}async function Qn(e,t){if(!e)return await tr(t,`status_recovery_unavailable`);if(e.type===`recovered`)return $n(e,t);if(e.type===`skipInvalidation`)throw er(e,t);return await tr(t,e.reason,e.lifecycleState,e.error)}function $n(e,t){return _r({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.data}function er(e,t){return _r({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.error}async function tr(e,t,n,r){throw _r({command:e.command,session:e.session,transportError:e.transportError,decision:`retained`,reason:t,lifecycleState:n}),await e.invalidateSession(e.session,e.invalidationReason),r??e.transportError}async function nr(e,t,n,r,i,a){if(n.command===`status`||!n.commandId?.trim())return;let o=q(r),s;try{s=await W(e,t,{command:`status`,statusCommandId:n.commandId},i.logPath,3e3,a)}catch(e){return x({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`}}let c=typeof s.lifecycleState==`string`?s.lifecycleState:``;return x({level:`debug`,phase:`ios_runner_command_status_recovery`,data:{command:n.command,commandId:n.commandId,lifecycleState:c,...o}}),rr(s,c,n,r,i)}function rr(e,n,r,i,a){return n===`completed`?ir(e,r,i,a):n===`failed`?{type:`skipInvalidation`,reason:`runner_reported_failure`,lifecycleState:n,error:ar(e,r,i,a)}:n===`accepted`||n===`started`?{type:`skipInvalidation`,reason:`command_still_in_flight`,lifecycleState:n,error:or(n,r,i,a)}:{type:`retainInvalidation`,reason:n?`unknown_lifecycle_state`:`missing_lifecycle_state`,lifecycleState:n,error:new t(`COMMAND_FAILED`,`Runner command "${r.command}" lost its transport response and lifecycle status was ${n?`"${n}"`:`missing`}, so agent-device invalidated the runner session instead of replaying the command.`,{command:r.command,commandId:r.commandId,lifecycleState:n,recovery:`lifecycle_state_not_recoverable`,hint:gr(r.command),logPath:a.logPath,transportError:i.message},i)}}function ir(e,n,r,i){let a=sr(e.lifecycleResponseJson);if(a)return{type:`recovered`,data:a,reason:`completed_with_retained_response`,lifecycleState:`completed`};if(N(n))return{type:`skipInvalidation`,error:r,reason:`read_only_completed_without_retained_response`,lifecycleState:`completed`};let o=q(r);return{type:`skipInvalidation`,reason:`completed_without_retained_response`,lifecycleState:`completed`,error:new t(`COMMAND_FAILED`,`Runner command "${n.command}" completed after the transport response was lost, but no recoverable response was retained.`,{command:n.command,commandId:n.commandId,lifecycleState:`completed`,recovery:`completed_without_retained_response`,...o,hint:lr(n.command,o),logPath:i.logPath,transportError:r.message},r)}}function ar(e,n,r,i){let a=typeof e.lifecycleErrorCode==`string`?e.lifecycleErrorCode:void 0,o=typeof e.lifecycleErrorMessage==`string`?e.lifecycleErrorMessage:`Runner command failed`,s=typeof e.lifecycleErrorHint==`string`?e.lifecycleErrorHint:void 0,c=q(r),l=dt(a);return new t(l.code,o,{command:n.command,commandId:n.commandId,lifecycleState:`failed`,recovery:`runner_reported_failure`,...l.details,...c,hint:s??ur(n.command,c),logPath:i.logPath,transportError:r.message},r)}function or(e,n,r,i){if(N(n))return r;let a=q(r);return new t(`COMMAND_FAILED`,`Runner command "${n.command}" is still ${e} after the transport response was lost.`,{command:n.command,commandId:n.commandId,lifecycleState:e,recovery:`command_still_in_flight`,...a,hint:dr(n.command,e,a),logPath:i.logPath,transportError:r.message},r)}function sr(e){if(typeof e!=`string`||e.trim().length===0)return;let t=cr(e);if(t.ok)return t.data&&typeof t.data==`object`&&!Array.isArray(t.data)?t.data:{}}function cr(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`)return t}catch{}return{}}function lr(e,t){return`${fr(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 ur(e,t){return`${fr(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 dr(e,t,n){return`${fr(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 fr(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 pr(e,t){let n=e.details?.[t];return typeof n==`boolean`?n:void 0}function mr(e,t){let n=e.details?.[t];return typeof n==`string`?n:void 0}function hr(e,t){let n=e.details?.[t];return typeof n==`number`?n:void 0}function q(e){let t={},n=pr(e,`runnerReadinessPreflightSkipped`);n!==void 0&&(t.readinessPreflightSkipped=n);let r=mr(e,`runnerReadinessPreflightSkipReason`);r!==void 0&&(t.readinessPreflightSkipReason=r);let i=hr(e,`runnerReadinessPreflightSkippedAgeMs`);return i!==void 0&&(t.readinessPreflightSkippedAgeMs=i),t}function gr(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 _r(e){let{command:t,session:n,transportError:r,decision:i,reason:a,lifecycleState:o}=e;x({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 J=new Map;function vr(e,t){let n=e.requestId?.trim();if(n)return`request:${n}`;let r=t.commandId?.trim();if(r)return`command:${r}`}function yr(e){if(!e)return;let t=wr(e);t.touchedSession=!0,Y(e,t)}function br(e){return e?J.get(e)?.touchedSession===!0:!1}function xr(e){if(!e)return!0;let t=wr(e);return t.recycles>=1?(Y(e,t),!1):(Y(e,t),!0)}function Sr(e){if(!e)return;let t=wr(e);t.recycles+=1,Y(e,t)}function Cr(e,n){return x({level:`warn`,phase:`ios_runner_recycle_budget_exhausted`,data:{command:e.command,commandId:e.commandId,requestId:n.requestId,maxRecycles:1}}),new t(`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:n.logPath})}function wr(e){return Tr(),J.get(e)??{touchedSession:!1,recycles:0,lastAtMs:Date.now()}}function Y(e,t){t.lastAtMs=Date.now(),J.delete(e),J.set(e,t)}function Tr(){let e=Date.now()-6e5;for(let[t,n]of J)n.lastAtMs<e&&J.delete(t);for(;J.size>512;){let e=J.keys().next().value;if(e===void 0)break;J.delete(e)}}async function Er(e,n){w(n.requestId);let r=C(n),i=T({command:`uptime`}),a;for(let t=1;t<=2;t+=1){let o=await Dr({device:e,command:i,options:n,signal:r,attempt:t,recoveryReason:a});if(o.kind===`prepared`)return o.result;a=o.recoveryReason}throw new t(`COMMAND_FAILED`,`iOS runner prepare failed`)}async function Dr(e){let{device:t,command:n,options:r,signal:i,attempt:a,recoveryReason:o}=e,s=Date.now(),c=await R(t,{...r,cleanStaleBundles:a>1||r.cleanStaleBundles,...Pr(r,`runner_session`)}),l=Date.now()-s;try{return{kind:`prepared`,result:zr(t,await Nr(t,c,n,r,i,l,{recoveryReason:o}))}}catch(e){return await Or({device:t,session:c,command:n,options:r,signal:i,attempt:a,error:e})}}async function Or(e){let{device:t,session:n,command:a,options:o,signal:s,attempt:c,error:l}=e,u=i(l,`COMMAND_FAILED`);if(r(u))throw await X(n,`prepare_runner_request_canceled`),l;if(c===1&&Ir(u,n))return{kind:`prepared`,result:await kr({device:t,session:n,command:a,options:o,signal:s,error:u})};if(!Ar(u))throw l;let d=u.message||`runner_health_failed`;if(c>=2)throw await X(n,`prepare_runner_health_failed`),l;return w(o.requestId),await B(n,`prepare_runner_health_retry`),x({level:`warn`,phase:`ios_runner_prepare_health_retry`,data:{command:a.command,commandId:a.commandId,sessionId:n.sessionId,attempt:c,maxAttempts:2,reason:d}}),{kind:`retry`,recoveryReason:d}}async function kr(e){let{device:t,session:n,command:r,options:i,signal:a,error:o}=e,s=o.message||`runner_health_failed`;await B(n,`prepare_cached_runner_health_failed`),await xt(n.xctestrunArtifact,s);let c=Date.now(),l=await R(t,{...i,cleanStaleBundles:!0,forceRunnerXctestrunRebuild:!0,...Pr(i,`runner_rebuild`)}),u=Date.now()-c;try{let e=await Nr(t,l,r,i,a,u,{recoveryReason:s});return x({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}}),zr(t,e)}catch(e){await X(l,`prepare_rebuilt_runner_health_failed`);let n=Lr(e,l,s);throw Br(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 B(e,t)}catch{}}function Ar(e){return r(e)?!1:S(e)||$e(e)}async function jr(e,t,n){w(n.requestId);let a=C(n),o=vr(n,t),s,c=!1;try{if(!z(e.id)?.alive&&br(o)){if(!xr(o))throw Cr(t,n);c=!0}s=await R(e,n),pn(s,n.expectedRunnerSessionId),Sn(s,t),c&&Sr(o),yr(o);let r=s.ready?rt:Jn(s);return await W(e,s,t,n.logPath,r,a)}catch(o){if(n.expectedRunnerSessionId!==void 0)throw o;let c=i(o,`COMMAND_FAILED`);if(s&&!s.ready&&r(c))throw await X(s,`runner_startup_request_canceled`),o;if(Qe(c)&&s)return w(n.requestId),await Mr({device:e,session:s,command:t,options:n,signal:a,restartReason:`runner_connect_failed_before_command_send`});if(s&&Ze(c))return w(n.requestId),await Mr({device:e,session:s,command:t,options:n,signal:a,restartReason:`runner_readiness_preflight_failed_before_command_send`,recoveredDiagnosticPhase:`ios_runner_readiness_preflight_recovered`});if(s&&S(c))return await Zn({device:e,session:s,command:t,transportError:c,options:n,signal:a,invalidationReason:`transport_error_after_command_send`,invalidateSession:B});throw o}}async function Mr(e){let{device:t,command:n,options:r,signal:a,restartReason:o}=e,s=vr(r,n);if(!xr(s))throw Cr(n,r);await B(e.session,o);let c=await R(t,{...r,cleanStaleBundles:!0}).catch(t=>{throw Z(t,e)});Sr(s);try{let i=await W(t,c,n,r.logPath,Ye,a);return e.recoveredDiagnosticPhase&&x({level:`debug`,phase:e.recoveredDiagnosticPhase,data:{command:n.command,commandId:n.commandId,recovery:`session_restarted`,sessionId:c.sessionId}}),i}catch(o){let s=i(o,`COMMAND_FAILED`);if(S(s))try{return await Zn({device:t,session:c,command:n,transportError:s,options:r,signal:a,invalidationReason:`transport_error_after_retry_command_send`,invalidateSession:B})}catch(t){throw Z(t,e,c)}throw Z(o,e,c)}}function Z(e,n,r){return e instanceof t?new t(e.code,e.message,{...e.details??{},runnerRestarted:!0,runnerRestartReason:n.restartReason,runnerRestartCommand:n.command.command,...n.command.commandId?{runnerRestartCommandId:n.command.commandId}:{},runnerInvalidatedSessionId:n.session.sessionId,...r?{runnerRestartSessionId:r.sessionId}:{},...e.details?.logPath===void 0&&n.options.logPath?{logPath:n.options.logPath}:{}},e.cause??e):e}async function Nr(e,t,n,r,i,a,o){let s=Date.now(),c=Fr(r.prepareDeadline,r.healthTimeoutMs,`runner_health`);return Rr(await W(e,t,n,r.logPath,c,i),t,a,Date.now()-s,o)}function Pr(e,t){if(!e.prepareDeadline)return{};let n=Fr(e.prepareDeadline,e.buildTimeoutMs,t);return{buildTimeoutMs:n,startupTimeoutMs:n}}function Fr(e,n,r){if(!e)return n??45e3;let i=Math.floor(e.remainingMs());if(i<=0)throw new t(`COMMAND_FAILED`,`prepare ios-runner timed out`,{phase:r,reason:`prepare_deadline_expired`});return i}function Ir(e,t){let n=t.xctestrunArtifact;return!n||n.cache===`miss`?!1:tt(e)}function Lr(e,n,r){let a=i(e,`COMMAND_FAILED`);return new t(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 Rr(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 zr(e,t){return Br(e,t),t}function Br(e,t){x({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}})}async function Vr(e,t,n={}){jn(e),w(n.requestId);let r=T(t),i=Q(e,n);return N(r)?Ie(()=>(w(n.requestId),i.runCommand(e,r,n)),{shouldRetry:e=>(w(n.requestId),S(e))}):i.runCommand(e,r,n)}async function Hr(e,t={}){if(s(e))try{await Vr(e,{command:`targetReset`},t)}catch(t){x({level:`warn`,phase:`ios_runner_target_reset_failed`,data:{deviceId:e.id,error:t instanceof Error?t.message:String(t)}}),await U(e.id)}}function Ur(e,t={}){if(s(e))return Gr({device:e,options:t,failurePhase:`ios_runner_cache_prewarm_failed`,task:async t=>{await yt(e,{...t,budget:b(t.buildTimeoutMs,t.signal)})}})}function Wr(e,t={}){if(!s(e))return;let n=Q(e,t).prewarm;if(!n){x({level:`debug`,phase:`ios_runner_session_prewarm_unavailable`,data:{deviceId:e.id}});return}return Gr({device:e,options:t,failurePhase:`ios_runner_session_prewarm_failed`,task:async t=>{await n(e,t)}})}function Gr(e){let{device:t,options:n,failurePhase:r,task:i}=e,{propagateError:a=!1,...o}=n;return i(o).catch(e=>{if(x({level:`warn`,phase:r,data:{deviceId:t.id,error:e instanceof Error?e.message:String(e)}}),a)throw e})}async function Kr(e,t){jn(e),w(t.requestId);let n=T({command:`uptime`}),r=Q(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 Q(e,t){return Oe(e,Yr,void 0,{requestId:t.requestId})}function qr(e,t={}){return s(e)?Q(e,t).hasLiveSession(e):!1}async function Jr(e,t={}){if(!s(e))return!1;let n=Q(e,t).releaseSpeculativeSession;return n?await n(e):!1}const Yr=Ee(jr,{prepare:Er,hasLiveSession:e=>{let t=z(e.id);return t!==null&&t.alive&&t.ready},releaseSpeculativeSession:async e=>await Cn(e.id),prewarm:async(e,t)=>{let{healthCheck:n,...r}=t;if(n===!1){await R(e,{...r,speculative:!0});return}await Er(e,{...r,speculative:!0,healthTimeoutMs:rt})}});function Xr(e){return Ke(e),{runAppleRunnerCommand:Vr,notifyIosRunnerAppRelaunched:Hr,hasLiveIosRunnerSession:qr,releaseSpeculativeIosRunnerSessionFor:Jr,prewarmAppleRunnerCache:Ur,prewarmIosRunnerSession:Wr,prepareIosRunner:Kr,resolveRunnerAppBundleId:Re,hasCachedAppleRunnerArtifact:St,detachIosSimulatorRunnerSessionsForShutdown:En,getRunnerSessionSnapshot:z,releaseIosRunnerOnClose:wn,stopIosRunnerSession:U,stopAllIosRunnerSessions:Dn,runApplePressSeries:De,cleanupRunnerLeasesForOwner:ot,readStaleRunnerLease:gt,verifyLeaseRunnerPidIdentity:O,runnerLeaseCleanupAdapter:ht,applyXctestRunnerAppIconFromDerivedPath:it}}const Zr={runCmdStreaming:te,runCmdSync:ie,runCmdBackground:ne,requireExecSuccess:ee,isCommandTimeoutError:ae,shellQuote:se,emitDiagnostic:u,withDiagnosticTimer:l,retryWithPolicy:ce,isEnvTruthy:ue,deadlineFromTimeoutMs:(e,t)=>le.fromTimeoutMs(e,t),isProcessAlive:m,isProcessGroupAlive:p,readProcessStartTime:g,readProcessCommand:_,signalPidsBestEffort:f,signalProcessGroupBestEffort:re,findProjectRoot:de,readVersion:fe,acquireProcessLock:oe,withKeyedLock:ge,publishFileSync:d,classifyOwnerLiveness:h,createTtlMemo:pe,parseBooleanLiteral:c,isRecord:a,resolveIosSimulatorDeviceSetPath:be,emitRequestProgress:ye,getRequestSignal:ve,isRequestCanceled:_e,classifyBootFailure:me,bootFailureHint:he,runAppleToolCommand:xe,runXcrun:Se,readApplePlistJson:Ce,buildSimctlArgsForDevice:Te,resolveIosPhysicalDeviceControl:we,visitXmlPlistEntries:wt,leaseOwnerStateDir:Tt,hasDeviceClaimAuthority:e=>Et()?.(e)??!1};var Qr=e({applyXctestRunnerAppIconFromDerivedPath:()=>_i,cleanupRunnerLeasesForOwner:()=>mi,detachIosSimulatorRunnerSessionsForShutdown:()=>ci,getRunnerSessionSnapshot:()=>li,hasCachedAppleRunnerArtifact:()=>si,hasLiveIosRunnerSession:()=>ti,notifyIosRunnerAppRelaunched:()=>ei,prepareIosRunner:()=>ai,prewarmAppleRunnerCache:()=>ri,prewarmIosRunnerSession:()=>ii,readStaleRunnerLease:()=>hi,releaseIosRunnerOnClose:()=>ui,releaseSpeculativeIosRunnerSessionFor:()=>ni,resolveRunnerAppBundleId:()=>oi,runApplePressSeries:()=>pi,runAppleRunnerCommand:()=>$r,stopAllIosRunnerSessions:()=>fi,stopIosRunnerSession:()=>di,verifyLeaseRunnerPidIdentity:()=>gi});const $=Xr(Zr),$r=$.runAppleRunnerCommand,ei=$.notifyIosRunnerAppRelaunched,ti=$.hasLiveIosRunnerSession,ni=$.releaseSpeculativeIosRunnerSessionFor,ri=$.prewarmAppleRunnerCache,ii=$.prewarmIosRunnerSession,ai=$.prepareIosRunner,oi=$.resolveRunnerAppBundleId,si=$.hasCachedAppleRunnerArtifact,ci=$.detachIosSimulatorRunnerSessionsForShutdown,li=$.getRunnerSessionSnapshot,ui=$.releaseIosRunnerOnClose,di=$.stopIosRunnerSession,fi=$.stopAllIosRunnerSessions,pi=$.runApplePressSeries,mi=$.cleanupRunnerLeasesForOwner,hi=$.readStaleRunnerLease,gi=$.verifyLeaseRunnerPidIdentity,_i=$.applyXctestRunnerAppIconFromDerivedPath;export{fi as _,ti as a,ri as c,ui as d,ni as f,Qr as g,$r as h,si as i,ii as l,pi as m,ci as n,ei as o,oi as p,li as r,ai as s,_i as t,hi as u,di as v,gi as y};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{C as t,T as n,j as r,w as i}from"./sdk-contracts.js";import{g as a}from"./sdk-batch-runner.js";import{c as o,l as s}from"./sdk-device.js";import{o as c}from"./sdk-remote-config.js";import{c as l,r as u}from"./diagnostics.js";import{D as d,S as f,m as p,p as m,t as ee,x as te,y as h}from"./owner-identity.js";import{a as ne,f as re,l as ie,m as ae,p as oe,r as se}from"./exec.js";import{n as ce,t as le}from"./file.js";import"./diagnostics2.js";import{n as ue}from"./command.js";import{i as de,n as fe,r as pe}from"./retry.js";import{n as me,r as he}from"./version.js";import{t as ge}from"./ttl-memo.js";import"./process.js";import{n as _e,t as ve}from"./boot-diagnostics.js";import{t as ye}from"./keyed-lock.js";import{i as be,r as xe}from"./request-cancel.js";import{t as Se}from"./request.js";import{r as Ce}from"./device-isolation.js";import{a as we,o as Te,r as Ee}from"./tool-provider.js";import{t as De}from"./physical-device-control.js";import{t as Oe}from"./simctl.js";import{a as ke,i as Ae,o as je}from"./runner.js";import{$ as Me,A as g,B as Ne,F as Pe,G as Fe,H as Ie,Q as Le,T as Re,U as ze,W as _,_ as Be,c as Ve,d as He,i as v,o as Ue,q as We,s as Ge,t as Ke,u as qe,w as y,x as Je,y as Ye}from"./runner-cache-metadata.js";import{a as Xe}from"./apple-runner-platform.js";import{A as b,B as Ze,C as Qe,E as $e,F as et,I as tt,L as nt,M as rt,N as x,O as S,P as it,R as C,S as at,T as ot,_ as w,a as T,b as st,c as ct,d as lt,f as ut,g as dt,h as E,i as ft,j as pt,k as mt,l as ht,m as gt,n as _t,o as vt,p as yt,r as bt,t as D,u as xt,v as St,w as Ct,x as wt,y as Tt,z as Et}from"./runner-disposal.js";import{t as Dt}from"./plist-xml.js";import{n as Ot,t as kt}from"./runner-owner-state.js";import O from"node:path";import At from"node:fs";import jt from"node:fs/promises";const Mt={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function Nt(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?O.resolve(i):O.dirname(e);At.mkdirSync(a,{recursive:!0});let o=n.replaceAll(/[^a-zA-Z0-9._-]/g,`_`),s=O.join(a,`AgentDeviceRunner.env.${o}.json`),c=O.join(a,`AgentDeviceRunner.env.${o}.xctestrun`),l=await Pt(e);return Rt(l,e=>It(e,t)),Lt(l),await Ft(l,s,c),{xctestrunPath:c,jsonPath:s}}async function Pt(e){let n=await _(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(n.exitCode!==0||!n.stdout.trim())throw new t(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:n.stderr});try{let e=JSON.parse(n.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(n){throw new t(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(n)})}}async function Ft(e,t,n){At.writeFileSync(t,JSON.stringify(e,null,2)),Ne(await _(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function It(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function Lt(e){Rt(e,e=>Object.assign(e,Mt),{requireTestBundlePath:!0})}function Rt(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||zt(e.TestTargets,t,n);for(let n of Object.values(e)){let e=Bt(n,{requireTestBundlePath:!0});e&&t(e)}}function zt(e,t,n){if(Array.isArray(e))for(let r of e){let e=Bt(r,n);e&&t(e)}}function Bt(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const Vt={tap:`preflightSkippableTouchMutation`,mouseClick:`default`,longPress:`preflightSkippableTouchMutation`,drag:`preflightSkippableTouchMutation`,remotePress:`default`,type:`default`,swipe:`preflightSkippableTouchMutation`,scroll:`preflightSkippableTouchMutation`,desktopScroll:`preflightSkippableTouchMutation`,findText:`readOnly`,querySelector:`readOnly`,readText:`readOnly`,snapshot:`readOnly`,screenshot:`readOnly`,back:`default`,backInApp:`default`,backSystem:`default`,home:`default`,rotate:`default`,gesture:`preflightSkippableTouchMutation`,gestureViewport:`readOnly`,appSwitcher:`default`,keyboardDismiss:`default`,keyboardReturn:`default`,alert:`alertAction`,sequence:`preflightSkippableTouchMutation`,recordStart:`default`,recordStop:`default`,status:`readOnlyReadinessProbe`,uptime:`readOnlyReadinessProbe`,activate:`readinessPreflightExemptMutation`,terminate:`readinessPreflightExemptMutation`,targetReset:`readinessPreflightExemptMutation`,shutdown:`default`},k={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},Ht={...k,readinessPreflightExempt:!0},Ut={...k,readOnly:!0},Wt={...Ut,readinessProbe:!0},Gt={...k,readinessPreflightSkipEligibleAfterHealthyMutation:!0};function A(e){return j(e).readOnly}function Kt(e){return j(e).readinessProbe}function qt(e){return j(e).readinessPreflightExempt}function Jt(e){return j(e).readinessPreflightSkipEligibleAfterHealthyMutation}function j(e){switch(Vt[e.command]){case`default`:return k;case`readinessPreflightExemptMutation`:return Ht;case`readOnly`:return Ut;case`alertAction`:return(e.action??`get`).toLowerCase()===`get`?Ut:k;case`readOnlyReadinessProbe`:return Wt;case`preflightSkippableTouchMutation`:return Gt}}function Yt(e,t){return`${e}:${t}:${Date.now()}`}function Xt(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}function Zt(e=process.env){return Pe(e.AGENT_DEVICE_IOS_RUNNER_DETACH??``)!==!1}async function Qt(e,t){if(e.kind!==`simulator`||!Zt()||Ie(e.simulatorSetPath))return null;let n=yt(e.id);if(!n)return null;let r=t=>(y({level:`debug`,phase:`ios_runner_lease_adoption_skipped`,data:{deviceId:e.id,runnerPid:n.runnerPid,port:n.port,reason:t}}),null);if(t.expectedRunnerSessionId!==void 0&&n.sessionId!==t.expectedRunnerSessionId)return r(`session_identity_mismatch`);let i=n.runnerPid;if(!i)return r(`runner_pid_missing`);if(!g(i))return r(`runner_process_dead`);if(!E(n,i))return r(`runner_pid_recycled`);let a=en(e,t.budget);if(!a)return r(`expected_derived_unresolved`);if(!n.xctestrunPath.startsWith(`${a}${O.sep}`))return r(`artifact_fingerprint_mismatch`);if(!await $t(e,n.port))return r(`probe_failed`);if(!g(i)||!E(n,i))return r(`runner_pid_recycled`);let o=tn(e,n,i,a,t);try{w(o.lease)}catch{return null}return y({level:`info`,phase:`ios_runner_lease_adopted`,data:{deviceId:e.id,sessionId:o.sessionId,runnerPid:i,port:n.port,previousOwnerPid:n.ownerPid}}),o}async function $t(e,t){try{let n=await $e(e,t,C({command:`uptime`}),500);return JSON.parse(await n.text())?.ok===!0}catch{return!1}}function en(e,t){try{return qe(e,Ge(e,void 0,t))}catch(e){if(r(e))throw e;return null}}function tn(e,t,n,r,i){let a=t.sessionId,o={xctestrunPath:t.xctestrunPath,derived:r,cache:`exact`,artifact:`valid`,buildMs:0,xctestrunPathSource:`manifest`,reason:`adopted_from_lease`},{child:s,wait:c}=nn(n);return{sessionId:a,device:e,deviceId:e.id,port:t.port,xctestrunPath:t.xctestrunPath,xctestrunArtifact:o,jsonPath:t.jsonPath,testPromise:c,child:s,ready:!0,startupTimeoutMs:Xt(Ue(i.budget,`runner_session_adoption`)),lease:xt({deviceId:e.id,sessionId:a,runnerPid:n,port:t.port,xctestrunPath:t.xctestrunPath,jsonPath:t.jsonPath})}}function nn(e){let t={pid:e,exitCode:null};return{child:t,wait:new Promise(n=>{let r=setInterval(()=>{g(e)||(clearInterval(r),t.exitCode=-1,n({stdout:``,stderr:``,exitCode:-1}))},1e3);r.unref?.()})}}async function rn(e){let n=await an(e.logPath)??sn(e.error);return n?new t(n.code??e.error.code,e.error.message,{...e.error.details??{},hint:typeof e.error.details?.hint==`string`?`${e.error.details.hint} ${n.hint}`:n.hint,runnerFailureReason:n.reason},e.error):e.error}async function an(e){if(!e)return;let t=await dn(e,65536);if(t)return on(t)}function on(e){let t=e.toLowerCase();if(cn(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_axruntime_coretext_crash`,hint:`The target iOS app appears to have crashed while XCTest/AXRuntime read accessibility attributes. This is usually a simulator/XCTest/runtime or app accessibility payload issue, not a text-entry failure. Reproduce on the latest stable simulator runtime, reinstall the app, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`};if(ln(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_crash`,hint:`The target iOS app appears to have crashed while the runner was executing the command. Reopen or reinstall the app, retry on a fresh/latest stable simulator runtime, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`}}function sn(e){if(un(e.message))return{reason:`runner_main_thread_execution_timeout`,hint:`XCTest timed out waiting for main-thread work on the current iOS screen. The app may still be visually responsive, especially on focused React Native overlays or animating screens. Use screenshot as visual truth, use coordinate presses only to prove or leave the state, and retry snapshot -i after the UI settles or after navigating away.`}}function cn(e){return e.includes(`axruntime`)&&e.includes(`coretext`)&&(e.includes(`attributesforelement`)||e.includes(`axuielementcopymultipleattributevalues`)||e.includes(`reconstitutedsmuggledctfontfromdictionary`)||e.includes(`reconstitutedsmuggledattributedstringfromdictionary`))}function ln(e){return e.includes(`process crashed`)||e.includes(`the application under test`)||e.includes(`terminated unexpectedly`)||e.includes(`exception type:`)&&e.includes(`thread 0 crashed`)}function un(e){return e.toLowerCase().includes(`main thread execution timed out`)}async function dn(e,t){let n;try{let r=await jt.stat(e),i=Math.max(0,r.size-t),a=r.size-i;if(a<=0)return;n=await jt.open(e,`r`);let o=Buffer.alloc(a);return await n.read(o,0,a,i),o.toString(`utf8`)}catch{return}finally{await n?.close().catch(()=>{})}}function fn(){let e=new AbortController,t=!1,n={stdout:``,stderr:``};return{wake:e.signal,observe:(r,i)=>{if(t)return;let a=n[r]+i;if(a.includes(`AGENT_DEVICE_RUNNER_LISTENER_READY`)){t=!0,n.stdout=``,n.stderr=``,e.abort();return}n[r]=a.slice(-33)},finish:()=>{t=!0,n.stdout=``,n.stderr=``,e.abort()}}}function pn(e){let t=fn(),n=Fe(`xcodebuild`,[`test-without-building`,`-only-testing`,`AgentDeviceRunnerUITests/RunnerTests/testCommand`,`-parallel-testing-enabled`,`NO`,`-test-timeouts-enabled`,`NO`,`-collect-test-diagnostics`,`never`,He(e.device),`1`,`-destination-timeout`,`20`,`-xctestrun`,e.xctestrunPath,`-derivedDataPath`,e.derivedPath,`-destination`,Xe(e.device)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(e.port)},detached:!0,signal:e.signal}),r=(n,r)=>{t.observe(n,r),Ze(r,e.logPath,e.traceLogPath,e.verbose)};return n.child.stdout?.on(`data`,e=>r(`stdout`,e)),n.child.stderr?.on(`data`,e=>r(`stderr`,e)),n.wait.then(t.finish,t.finish),{...n,startupRetryWake:t.wake}}const M=new Map,mn=new Map,N=new Map,hn=1e4;function P(e,t){return Me(mn,e,t)}async function F(e,t){return z(e.id),await P(e.id,async()=>{let n=v(t.startupTimeoutMs,x(t)),r=M.get(e.id);if(r){_n(r,t.expectedRunnerSessionId);let i=await bn(e,r,n);if(i)return i}return await dt(e.id,async()=>await gn(e,t,n))})}async function gn(e,t,r){let i={},a=r.signal,o=er(t.runnerLeaseContext,e.id);y({level:`debug`,phase:`ios_runner_session_startup`,data:{deviceId:e.id,logicalLeaseContext:o}});let s=await H(i,`adopt_detached_runner`,async()=>await Qt(e,{budget:r,expectedRunnerSessionId:t.expectedRunnerSessionId}));if(s)return s.startupTimings=i,s.logicalLeaseContext=o,M.set(e.id,s),s;vn(t.expectedRunnerSessionId),await H(i,`cleanup_stale_xcodebuild`,async()=>{await ut(e,vt,o)}),await H(i,`ensure_booted`,async()=>{await Mn(e)}),await H(i,`verify_developer_mode`,async()=>{await Pn(e)}),t.cleanStaleBundles?await H(i,`cleanup_stale_bundles`,async()=>{await xn(e)}):(i.cleanup_stale_bundles=0,y({level:`debug`,phase:`ios_runner_startup_cleanup_stale_bundles_skipped`}));let c=Ue(r,`runner_session_startup`),l=await H(i,`ensure_xctestrun`,async()=>await St(e,{...t,budget:v(t.buildTimeoutMs,a)}));i.build_xctestrun=l.buildMs;let u=await H(i,`allocate_port`,async()=>await Et()),{xctestrunPath:d,jsonPath:f}=await H(i,`prepare_xctestrun_env`,async()=>await Nt(l.xctestrunPath,{AGENT_DEVICE_RUNNER_PORT:String(u)},`session-${e.id}-${gt()}-${u}`,{iosXctestEnvDir:t.iosXctestEnvDir})),p=await H(i,`simulator_set_redirect`,async()=>await at(e)),m;try{l.buildMs>0&&Re({type:`command`,status:`progress`,message:`Starting XCTest runner...`}),m=await H(i,`launch_xcodebuild`,()=>pn({device:e,port:u,xctestrunPath:d,derivedPath:l.derived,signal:a,logPath:t.logPath,traceLogPath:t.traceLogPath,verbose:t.verbose}))}catch(e){throw await p?.releaseBestEffort(),e}let ee=Yt(e.id,u),te=xt({deviceId:e.id,sessionId:ee,runnerPid:m.child.pid,port:u,xctestrunPath:d,jsonPath:f}),h={sessionId:ee,device:e,deviceId:e.id,port:u,xctestrunPath:d,xctestrunArtifact:l,jsonPath:f,testPromise:m.wait,child:m.child,ready:!1,startupRetryWake:m.startupRetryWake,startupTimeoutMs:Xt(c),startupTimings:i,logicalLeaseContext:o,simulatorSetRedirect:p??void 0,lease:te,speculative:t.speculative===!0};if(a?.aborted)throw await ft(h,{graceful:!1,waitTimeoutMs:D,leaseLockHeld:!0}),n();try{w(te)}catch(t){throw await R(e.id,h,{graceful:!1,waitTimeoutMs:D,leaseLockHeld:!0}),t}return M.set(e.id,h),h}function _n(e,t){if(t!==void 0&&e.sessionId!==t)throw yn()}function vn(e){if(e!==void 0)throw yn()}function yn(){return new t(`COMMAND_FAILED`,`Apple runner session ownership changed before command dispatch`,{reason:`runner_session_ownership_changed`})}async function bn(e,t,n){if(!T(t.child.pid))return await H({},`stop_stale_session`,async()=>{await R(e.id,t,{graceful:!1,waitTimeoutMs:D})}),null;let r=t.xctestrunArtifact;if(r?.cache===`external`)return y({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.ready,cache:r.cache,logicalLeaseContext:t.logicalLeaseContext}}),t;let i=qe(e,Ge(e,void 0,n));return r?.derived===i?(y({level:`debug`,phase:`ios_runner_session_reuse`,data:{deviceId:e.id,sessionId:t.sessionId,ready:t.ready,logicalLeaseContext:t.logicalLeaseContext}}),t):(y({level:`debug`,phase:`ios_runner_session_artifact_stale`,data:{deviceId:e.id,sessionId:t.sessionId,currentDerived:r?.derived,expectedDerived:i}}),await H({},`stop_stale_artifact_session`,async()=>{await R(e.id,t)}),null)}async function xn(e){e.kind===`simulator`&&await Promise.allSettled(Ke.map(async t=>{let n=await Sn(e,t);!n||Cn(n)}))}async function Sn(e,t){try{return await We(Je(e,[`uninstall`,e.id,t]),{allowFailure:!0,timeoutMs:hn})}catch(n){y({level:`warn`,phase:`ios_runner_startup_cleanup_stale_bundle_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:hn,error:n instanceof Error?n.message:String(n)}});return}}function Cn(e){if(e.exitCode===0)return!0;let t=`${e.stdout}\n${e.stderr}`.toLowerCase();return t.includes(`not installed`)||t.includes(`found nothing`)||t.includes(`no such file`)||t.includes(`invalid device`)||t.includes(`could not find`)}function I(e){let t=M.get(e);return t?{sessionId:t.sessionId,alive:T(t.child.pid),ready:t.ready}:null}async function L(e,t){await P(e.deviceId,async()=>{M.get(e.deviceId)===e&&(y({level:`warn`,phase:`ios_runner_session_invalidated`,data:{deviceId:e.deviceId,sessionId:e.sessionId,reason:t}}),await R(e.deviceId,e,{graceful:!1,waitTimeoutMs:D}))})}async function R(e,t,n={}){let r=t??M.get(e);r&&(await ft(r,n),M.get(e)===r&&M.delete(e))}function wn(e){z(e);let t=Tn();if(t<=0||!M.has(e))return;let n=setTimeout(()=>{N.delete(e),y({level:`info`,phase:`ios_runner_idle_stop`,data:{deviceId:e,idleMs:t}}),B(e).catch(t=>{y({level:`warn`,phase:`ios_runner_idle_stop_failed`,data:{deviceId:e,error:t instanceof Error?t.message:String(t)}})})},t);n.unref?.(),N.set(e,n),y({level:`debug`,phase:`ios_runner_idle_stop_scheduled`,data:{deviceId:e,idleMs:t}})}function z(e){let t=N.get(e);t&&(clearTimeout(t),N.delete(e))}function Tn(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 En(e,t){e.speculative&&!Kt(t)&&(e.speculative=!1)}async function Dn(e){return await P(e,async()=>{let t=M.get(e);return t?.speculative?(y({level:`debug`,phase:`ios_runner_speculative_released`,data:{deviceId:e,sessionId:t.sessionId,ready:t.ready}}),await B(e),!0):!1})}async function B(e){z(e),await P(e,async()=>{await dt(e,async()=>{await R(e,void 0,{leaseLockHeld:!0}),await bt(e)})})}async function On(e,t){if(t.retain&&M.get(e)?.runnerMainThreadBusy!==!0){wn(e);return}t.retain&&y({level:`info`,phase:`ios_runner_retain_skipped_busy`,data:{deviceId:e}}),await B(e)}async function kn(){let e=Array.from(M.values());await _t(e);for(let t of e)M.get(t.deviceId)===t&&M.delete(t.deviceId)}async function An(){if(!Zt())return 0;let e=0;for(let[t,n]of M)if(n.device.kind===`simulator`&&!n.simulatorSetRedirect&&!(!n.lease||!T(n.child.pid))){try{w(ht(n.lease))}catch{continue}M.delete(t),z(t),e+=1,y({level:`info`,phase:`ios_runner_session_detached`,data:{deviceId:t,sessionId:n.sessionId,runnerPid:n.child.pid,port:n.port}})}return e}async function jn(){await kn();let e=Array.from(M.keys());await Promise.allSettled(e.map(async e=>{await B(e)})),await ct()}function Mn(e){return e.kind===`simulator`?e.booted?(y({level:`debug`,phase:`ios_runner_startup_ensure_booted_skipped`,data:{deviceId:e.id}}),Promise.resolve()):Nn(e):Promise.resolve()}async function Nn(e){await We(Je(e,[`bootstatus`,e.id,`-b`]),{timeoutMs:Qe})}async function Pn(e){if(!s(e)||e.kind!==`device`)return;let n=await _(`DevToolsSecurity`,[`-status`],{allowFailure:!0,timeoutMs:2e3}),r=`${n.stdout}\n${n.stderr}`;if(/developer mode is currently disabled/i.test(r))throw new t(`COMMAND_FAILED`,`Developer mode is disabled for Apple development tools`,{hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach.",devToolsSecurityStatus:r.trim()})}function Fn(e){if(!o(e.platform))throw new t(`UNSUPPORTED_PLATFORM`,`Unsupported platform for iOS runner: ${e.platform}`);if(e.kind!==`simulator`&&e.kind!==`device`)throw new t(`UNSUPPORTED_OPERATION`,`Unsupported iOS device kind for runner: ${e.kind}`)}async function V(e,t,n,r,i,a){$n(t,n.command);let o=C(n),s=A(o),c=Be.fromTimeoutMs(i),l=Yn(t,o);l.action===`run`?await Bn({device:e,session:t,runnerCommand:o,logPath:r,deadline:c,signal:a,decision:l}):Vn(o,t,l);let u;try{u=await zn({device:e,session:t,runnerCommand:o,logPath:r,deadline:c,timeoutMs:i,signal:a,readOnlyCommand:s})}catch(e){throw Rn(e,t,l)}try{let e=await Hn(u,t,r),n=In(e);n!==void 0&&(t.runnerMainThreadBusy=n);let i=Jn(e);return i?(t.lastHealthyMutation=void 0,await L(t,i)):Jt(o)&&(t.lastHealthyMutation={atMs:Date.now(),appBundleId:o.appBundleId}),e}catch(e){pt(e)?t.runnerMainThreadBusy=!0:Ln(e)&&(t.runnerMainThreadBusy=!1);let n=rt(e);throw n?(t.lastHealthyMutation=void 0,await L(t,n),e):Ln(e)?e:Rn(e,t,l)}}function In(e){return typeof e.runnerMainThreadBusy==`boolean`?e.runnerMainThreadBusy:void 0}function Ln(e){return e instanceof t&&e.details?.runner!==void 0}function Rn(e,t,n){return n.action!==`skip`||n.reason!==`recent_healthy_mutation`?e:(t.lastHealthyMutation=void 0,Zn(e,{runnerReadinessPreflightSkipped:!0,runnerReadinessPreflightSkipReason:n.reason,runnerReadinessPreflightSkippedAgeMs:n.lastHealthyMutationAgeMs}))}async function zn(e){let{device:n,session:r,runnerCommand:i,logPath:a,deadline:o,timeoutMs:s,signal:c,readOnlyCommand:l}=e,u=o.remainingMs();if(u<=0)throw new t(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:s});let d=l?{command:i.command,commandId:i.commandId,readOnly:!0,sessionReady:r.ready,timeoutMs:u}:{command:i.command,commandId:i.commandId};return await Le(`ios_runner_command_send`,async()=>l?await Ct(n,r.port,i,a,u,r,c):await $e(n,r.port,i,u,c),d)}async function Bn(e){let{device:t,session:n,runnerCommand:r,logPath:i,deadline:a,signal:o,decision:s}=e,c=n.ready?Math.min(1e3,a.remainingMs()):Math.min(Qn(n),a.remainingMs());try{await Hn(await Le(`ios_runner_readiness_preflight`,async()=>await Ct(t,n.port,C({command:`uptime`}),i,c,n,o),{command:r.command,commandId:r.commandId,reason:s.reason,lastHealthyMutationAgeMs:s.lastHealthyMutationAgeMs,sessionReady:n.ready,timeoutMs:c}),n,i)}catch(e){throw Xn(e)}}function Vn(e,t,n){y({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:n.reason,lastHealthyMutationAgeMs:n.reason===`recent_healthy_mutation`?n.lastHealthyMutationAgeMs:void 0,sessionReady:t.ready}})}async function Hn(e,t,n){let r=Un(await e.text());if(!r.ok)throw await rn({error:Wn(r,n),logPath:n});return t.ready=!0,Kn(r)}function Un(e){try{let t=JSON.parse(e);return t&&typeof t==`object`?t:{}}catch{throw new t(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}}function Wn(e,n){let r=Gn(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=mt(r);return new t(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:n})}function Gn(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function Kn(e){if(!e.data||typeof e.data!=`object`||Array.isArray(e.data))return{};let t=e.data;return qn(t),t}function qn(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&y({level:`debug`,phase:`ios_runner_gesture_fallback`,data:{fallback:t,message:typeof e.gestureFallbackMessage==`string`?e.gestureFallbackMessage:void 0,hint:typeof e.gestureFallbackHint==`string`?e.gestureFallbackHint:void 0}})}function Jn(e){if(e.runnerFatal===!0)return typeof e.runnerFatalReason==`string`&&e.runnerFatalReason.trim().length>0?e.runnerFatalReason:`runner_reported_fatal_response`}function Yn(e,t){let n=A(t);if(qt(t))return{action:`skip`,reason:`preflight_exempt_command`};if(!e.ready)return n?{action:`skip`,reason:`read_only_startup_command`}:{action:`run`,reason:`startup`};if(Kt(t))return{action:`skip`,reason:`readiness_probe_command`};if(!Jt(t))return{action:`run`,reason:`conservative_command`};let r=e.lastHealthyMutation;if(!r)return{action:`run`,reason:`no_recent_healthy_mutation`};if(t.appBundleId!==r.appBundleId)return{action:`run`,reason:`app_activation_uncertain`};let i=Date.now()-r.atMs;return i>5e3?{action:`run`,reason:`healthy_mutation_stale`,lastHealthyMutationAgeMs:i}:{action:`skip`,reason:`recent_healthy_mutation`,lastHealthyMutationAgeMs:i}}function Xn(e){return Zn(e,{runnerReadinessPreflightFailed:!0})}function Zn(e,n){let r=e instanceof t?e:new t(`COMMAND_FAILED`,e instanceof Error?e.message:String(e),void 0,e);return new t(r.code,r.message,{...r.details??{},...n},r.cause??e)}function Qn(e){return e.startupTimeoutMs??45e3}async function H(e,t,n){let r=Date.now();try{return await n()}finally{let n=Date.now()-r;e[t]=n,y({level:`debug`,phase:`ios_runner_startup_${t}`,durationMs:n})}}function $n(e,t){if(e.startupTimingsReported||!e.startupTimings)return;e.startupTimingsReported=!0;let n=Object.values(e.startupTimings).reduce((e,t)=>e+t,0);y({level:`info`,phase:`ios_runner_session_startup_timings`,durationMs:n,data:{command:t,sessionId:e.sessionId,ready:e.ready,logicalLeaseContext:e.logicalLeaseContext,timings:e.startupTimings}})}function er(e,t){if(!e)return;let n={leaseId:U(e.leaseId),clientId:U(e.clientId),tenantId:U(e.tenantId),runId:U(e.runId),leaseProvider:U(e.leaseProvider),deviceKey:U(e.deviceKey)??t},r=Object.entries(n).filter(([,e])=>e!==void 0);return r.length>0?Object.fromEntries(r):void 0}function U(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}async function tr(e){let{device:t,session:n,command:r,transportError:i,options:a,signal:o,invalidationReason:s}=e;return await nr(await or(t,n,r,i,a,o),{command:r,session:n,transportError:i,invalidationReason:s,invalidateSession:e.invalidateSession})}async function nr(e,t){if(!e)return await ar(t,`status_recovery_unavailable`);if(e.type===`recovered`)return rr(e,t);if(e.type===`skipInvalidation`)throw ir(e,t);return await ar(t,e.reason,e.lifecycleState,e.error)}function rr(e,t){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.data}function ir(e,t){return K({command:t.command,session:t.session,transportError:t.transportError,decision:`skipped`,reason:e.reason,lifecycleState:e.lifecycleState}),e.error}async function ar(e,t,n,r){throw K({command:e.command,session:e.session,transportError:e.transportError,decision:`retained`,reason:t,lifecycleState:n}),await e.invalidateSession(e.session,e.invalidationReason),r??e.transportError}async function or(e,t,n,r,i,a){if(n.command===`status`||!n.commandId?.trim())return;let o=G(r),s;try{s=await V(e,t,{command:`status`,statusCommandId:n.commandId},i.logPath,3e3,a)}catch(e){return y({level:`debug`,phase:`ios_runner_command_status_recovery_failed`,data:{command:n.command,commandId:n.commandId,error:e instanceof Error?e.message:String(e),...o}}),{type:`retainInvalidation`,reason:`status_probe_failed`}}let c=typeof s.lifecycleState==`string`?s.lifecycleState:``;return y({level:`debug`,phase:`ios_runner_command_status_recovery`,data:{command:n.command,commandId:n.commandId,lifecycleState:c,...o}}),sr(s,c,n,r,i)}function sr(e,n,r,i,a){return n===`completed`?cr(e,r,i,a):n===`failed`?{type:`skipInvalidation`,reason:`runner_reported_failure`,lifecycleState:n,error:lr(e,r,i,a)}:n===`accepted`||n===`started`?{type:`skipInvalidation`,reason:`command_still_in_flight`,lifecycleState:n,error:ur(n,r,i,a)}:{type:`retainInvalidation`,reason:n?`unknown_lifecycle_state`:`missing_lifecycle_state`,lifecycleState:n,error:new t(`COMMAND_FAILED`,`Runner command "${r.command}" lost its transport response and lifecycle status was ${n?`"${n}"`:`missing`}, so agent-device invalidated the runner session instead of replaying the command.`,{command:r.command,commandId:r.commandId,lifecycleState:n,recovery:`lifecycle_state_not_recoverable`,hint:yr(r.command),logPath:a.logPath,transportError:i.message},i)}}function cr(e,n,r,i){let a=dr(e.lifecycleResponseJson);if(a)return{type:`recovered`,data:a,reason:`completed_with_retained_response`,lifecycleState:`completed`};if(A(n))return{type:`skipInvalidation`,error:r,reason:`read_only_completed_without_retained_response`,lifecycleState:`completed`};let o=G(r);return{type:`skipInvalidation`,reason:`completed_without_retained_response`,lifecycleState:`completed`,error:new t(`COMMAND_FAILED`,`Runner command "${n.command}" completed after the transport response was lost, but no recoverable response was retained.`,{command:n.command,commandId:n.commandId,lifecycleState:`completed`,recovery:`completed_without_retained_response`,...o,hint:pr(n.command,o),logPath:i.logPath,transportError:r.message},r)}}function lr(e,n,r,i){let a=typeof e.lifecycleErrorCode==`string`?e.lifecycleErrorCode:void 0,o=typeof e.lifecycleErrorMessage==`string`?e.lifecycleErrorMessage:`Runner command failed`,s=typeof e.lifecycleErrorHint==`string`?e.lifecycleErrorHint:void 0,c=G(r),l=mt(a);return new t(l.code,o,{command:n.command,commandId:n.commandId,lifecycleState:`failed`,recovery:`runner_reported_failure`,...l.details,...c,hint:s??mr(n.command,c),logPath:i.logPath,transportError:r.message},r)}function ur(e,n,r,i){if(A(n))return r;let a=G(r);return new t(`COMMAND_FAILED`,`Runner command "${n.command}" is still ${e} after the transport response was lost.`,{command:n.command,commandId:n.commandId,lifecycleState:e,recovery:`command_still_in_flight`,...a,hint:hr(n.command,e,a),logPath:i.logPath,transportError:r.message},r)}function dr(e){if(typeof e!=`string`||e.trim().length===0)return;let t=fr(e);if(t.ok)return t.data&&typeof t.data==`object`&&!Array.isArray(t.data)?t.data:{}}function fr(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`)return t}catch{}return{}}function pr(e,t){return`${W(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 mr(e,t){return`${W(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 hr(e,t,n){return`${W(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 W(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 gr(e,t){let n=e.details?.[t];return typeof n==`boolean`?n:void 0}function _r(e,t){let n=e.details?.[t];return typeof n==`string`?n:void 0}function vr(e,t){let n=e.details?.[t];return typeof n==`number`?n:void 0}function G(e){let t={},n=gr(e,`runnerReadinessPreflightSkipped`);n!==void 0&&(t.readinessPreflightSkipped=n);let r=_r(e,`runnerReadinessPreflightSkipReason`);r!==void 0&&(t.readinessPreflightSkipReason=r);let i=vr(e,`runnerReadinessPreflightSkippedAgeMs`);return i!==void 0&&(t.readinessPreflightSkippedAgeMs=i),t}function yr(e){return`The runner did not confirm that "${e}" reached a safe terminal state, so agent-device kept the conservative invalidation path. Run snapshot -i before retrying if the UI may have changed.`}function K(e){let{command:t,session:n,transportError:r,decision:i,reason:a,lifecycleState:o}=e;y({level:i===`retained`?`warn`:`debug`,phase:`ios_runner_command_invalidation_decision`,data:{command:t.command,commandId:t.commandId,decision:i,reason:a,lifecycleState:o,runnerReachable:o!==void 0,sessionId:n.sessionId,transportError:r.message}})}const q=new Map;function br(e,t){let n=e.requestId?.trim();if(n)return`request:${n}`;let r=t.commandId?.trim();if(r)return`command:${r}`}function xr(e){if(!e)return;let t=J(e);t.touchedSession=!0,Y(e,t)}function Sr(e){return e?q.get(e)?.touchedSession===!0:!1}function Cr(e){if(!e)return!0;let t=J(e);return t.recycles>=1?(Y(e,t),!1):(Y(e,t),!0)}function wr(e){if(!e)return;let t=J(e);t.recycles+=1,Y(e,t)}function Tr(e,n){return y({level:`warn`,phase:`ios_runner_recycle_budget_exhausted`,data:{command:e.command,commandId:e.commandId,requestId:n.requestId,maxRecycles:1}}),new t(`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:n.logPath})}function J(e){return Er(),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 Er(){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 Dr(e,n){S(n.requestId);let r=x(n),i=C({command:`uptime`}),a;for(let t=1;t<=2;t+=1){let o=await Or({device:e,command:i,options:n,signal:r,attempt:t,recoveryReason:a});if(o.kind===`prepared`)return o.result;a=o.recoveryReason}throw new t(`COMMAND_FAILED`,`iOS runner prepare failed`)}async function Or(e){let{device:t,command:n,options:r,signal:i,attempt:a,recoveryReason:o}=e,s=Date.now(),c=await F(t,{...r,cleanStaleBundles:a>1||r.cleanStaleBundles,...Fr(r,`runner_session`)}),l=Date.now()-s;try{return{kind:`prepared`,result:Br(t,await Pr(t,c,n,r,i,l,{recoveryReason:o}))}}catch(e){return await kr({device:t,session:c,command:n,options:r,signal:i,attempt:a,error:e})}}async function kr(e){let{device:t,session:n,command:a,options:o,signal:s,attempt:c,error:l}=e,u=i(l,`COMMAND_FAILED`);if(r(u))throw await X(n,`prepare_runner_request_canceled`),l;if(c===1&&Lr(u,n))return{kind:`prepared`,result:await Ar({device:t,session:n,command:a,options:o,signal:s,error:u})};if(!jr(u))throw l;let d=u.message||`runner_health_failed`;if(c>=2)throw await X(n,`prepare_runner_health_failed`),l;return S(o.requestId),await L(n,`prepare_runner_health_retry`),y({level:`warn`,phase:`ios_runner_prepare_health_retry`,data:{command:a.command,commandId:a.commandId,sessionId:n.sessionId,attempt:c,maxAttempts:2,reason:d}}),{kind:`retry`,recoveryReason:d}}async function Ar(e){let{device:t,session:n,command:r,options:i,signal:a,error:o}=e,s=o.message||`runner_health_failed`;await L(n,`prepare_cached_runner_health_failed`),await wt(n.xctestrunArtifact,s);let c=Date.now(),l=await F(t,{...i,cleanStaleBundles:!0,forceRunnerXctestrunRebuild:!0,...Fr(i,`runner_rebuild`)}),u=Date.now()-c;try{let e=await Pr(t,l,r,i,a,u,{recoveryReason:s});return y({level:`info`,phase:`ios_runner_prepare_bad_cache_recovered`,data:{command:r.command,commandId:r.commandId,sessionId:l.sessionId,xctestrunPath:l.xctestrunArtifact?.xctestrunPath,reason:s}}),Br(t,e)}catch(e){await X(l,`prepare_rebuilt_runner_health_failed`);let n=Rr(e,l,s);throw Vr(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 L(e,t)}catch{}}function jr(e){return r(e)?!1:b(e)||nt(e)}async function Mr(e,t,n){S(n.requestId);let a=x(n),o=br(n,t),s,c=!1;try{if(!I(e.id)?.alive&&Sr(o)){if(!Cr(o))throw Tr(t,n);c=!0}s=await F(e,n),_n(s,n.expectedRunnerSessionId),En(s,t),c&&wr(o),xr(o);let r=s.ready?ot:Qn(s);return await V(e,s,t,n.logPath,r,a)}catch(o){if(n.expectedRunnerSessionId!==void 0)throw o;let c=i(o,`COMMAND_FAILED`);if(s&&!s.ready&&r(c))throw await X(s,`runner_startup_request_canceled`),o;if(tt(c)&&s)return S(n.requestId),await Nr({device:e,session:s,command:t,options:n,signal:a,restartReason:`runner_connect_failed_before_command_send`});if(s&&et(c))return S(n.requestId),await Nr({device:e,session:s,command:t,options:n,signal:a,restartReason:`runner_readiness_preflight_failed_before_command_send`,recoveredDiagnosticPhase:`ios_runner_readiness_preflight_recovered`});if(s&&b(c))return await tr({device:e,session:s,command:t,transportError:c,options:n,signal:a,invalidationReason:`transport_error_after_command_send`,invalidateSession:L});throw o}}async function Nr(e){let{device:t,command:n,options:r,signal:a,restartReason:o}=e,s=br(r,n);if(!Cr(s))throw Tr(n,r);await L(e.session,o);let c=await F(t,{...r,cleanStaleBundles:!0}).catch(t=>{throw Z(t,e)});wr(s);try{let i=await V(t,c,n,r.logPath,Qe,a);return e.recoveredDiagnosticPhase&&y({level:`debug`,phase:e.recoveredDiagnosticPhase,data:{command:n.command,commandId:n.commandId,recovery:`session_restarted`,sessionId:c.sessionId}}),i}catch(o){let s=i(o,`COMMAND_FAILED`);if(b(s))try{return await tr({device:t,session:c,command:n,transportError:s,options:r,signal:a,invalidationReason:`transport_error_after_retry_command_send`,invalidateSession:L})}catch(t){throw Z(t,e,c)}throw Z(o,e,c)}}function Z(e,n,r){return e instanceof t?new t(e.code,e.message,{...e.details??{},runnerRestarted:!0,runnerRestartReason:n.restartReason,runnerRestartCommand:n.command.command,...n.command.commandId?{runnerRestartCommandId:n.command.commandId}:{},runnerInvalidatedSessionId:n.session.sessionId,...r?{runnerRestartSessionId:r.sessionId}:{},...e.details?.logPath===void 0&&n.options.logPath?{logPath:n.options.logPath}:{}},e.cause??e):e}async function Pr(e,t,n,r,i,a,o){let s=Date.now(),c=Ir(r.prepareDeadline,r.healthTimeoutMs,`runner_health`);return zr(await V(e,t,n,r.logPath,c,i),t,a,Date.now()-s,o)}function Fr(e,t){if(!e.prepareDeadline)return{};let n=Ir(e.prepareDeadline,e.buildTimeoutMs,t);return{buildTimeoutMs:n,startupTimeoutMs:n}}function Ir(e,n,r){if(!e)return n??45e3;let i=Math.floor(e.remainingMs());if(i<=0)throw new t(`COMMAND_FAILED`,`prepare ios-runner timed out`,{phase:r,reason:`prepare_deadline_expired`});return i}function Lr(e,t){let n=t.xctestrunArtifact;return!n||n.cache===`miss`?!1:it(e)}function Rr(e,n,r){let a=i(e,`COMMAND_FAILED`);return new t(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 zr(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 Br(e,t){return Vr(e,t),t}function Vr(e,t){y({level:t.failureReason?`warn`:`info`,phase:`apple_runner_prepare`,data:{platform:e.platform,target:e.target,deviceId:e.id,cache:t.cache,artifact:t.artifact,buildMs:t.buildMs,connectMs:t.connectMs,healthCheckMs:t.healthCheckMs,timingContainment:t.buildMs===void 0?{healthCheckMs:[]}:{connectMs:[`buildMs`],healthCheckMs:[]},xctestrunPath:t.xctestrunPath,recoveryReason:t.recoveryReason,failureReason:t.failureReason}})}async function Hr(e,t,n={}){Fn(e),S(n.requestId);let r=C(t),i=Q(e,n);return A(r)?ze(()=>(S(n.requestId),i.runCommand(e,r,n)),{shouldRetry:e=>(S(n.requestId),b(e))}):i.runCommand(e,r,n)}async function Ur(e,t={}){if(s(e))try{await Hr(e,{command:`targetReset`},t)}catch(t){y({level:`warn`,phase:`ios_runner_target_reset_failed`,data:{deviceId:e.id,error:t instanceof Error?t.message:String(t)}}),await B(e.id)}}function Wr(e,t={}){if(s(e))return Kr({device:e,options:t,failurePhase:`ios_runner_cache_prewarm_failed`,task:async t=>{await St(e,{...t,budget:v(t.buildTimeoutMs,t.signal)})}})}function Gr(e,t={}){if(!s(e))return;let n=Q(e,t).prewarm;if(!n){y({level:`debug`,phase:`ios_runner_session_prewarm_unavailable`,data:{deviceId:e.id}});return}return Kr({device:e,options:t,failurePhase:`ios_runner_session_prewarm_failed`,task:async t=>{await n(e,t)}})}function Kr(e){let{device:t,options:n,failurePhase:r,task:i}=e,{propagateError:a=!1,...o}=n;return i(o).catch(e=>{if(y({level:`warn`,phase:r,data:{deviceId:t.id,error:e instanceof Error?e.message:String(e)}}),a)throw e})}async function qr(e,t){Fn(e),S(t.requestId);let n=C({command:`uptime`}),r=Q(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 Q(e,t){return je(e,Xr,void 0,{requestId:t.requestId})}function Jr(e,t={}){return s(e)?Q(e,t).hasLiveSession(e):!1}async function Yr(e,t={}){if(!s(e))return!1;let n=Q(e,t).releaseSpeculativeSession;return n?await n(e):!1}const Xr=ke(Mr,{prepare:Dr,hasLiveSession:e=>{let t=I(e.id);return t!==null&&t.alive&&t.ready},releaseSpeculativeSession:async e=>await Dn(e.id),prewarm:async(e,t)=>{let{healthCheck:n,...r}=t;if(n===!1){await F(e,{...r,speculative:!0});return}await Dr(e,{...r,speculative:!0,healthTimeoutMs:ot})}});function Zr(e){return Ye(e),{runAppleRunnerCommand:Hr,notifyIosRunnerAppRelaunched:Ur,hasLiveIosRunnerSession:Jr,releaseSpeculativeIosRunnerSessionFor:Yr,prewarmAppleRunnerCache:Wr,prewarmIosRunnerSession:Gr,prepareIosRunner:qr,resolveRunnerAppBundleId:Ve,hasCachedAppleRunnerArtifact:Tt,detachIosSimulatorRunnerSessionsForShutdown:An,getRunnerSessionSnapshot:I,releaseIosRunnerOnClose:On,stopIosRunnerSession:B,stopAllIosRunnerSessions:jn,runApplePressSeries:Ae,cleanupRunnerLeasesForOwner:lt,readStaleRunnerLease:yt,verifyLeaseRunnerPidIdentity:E,runnerLeaseCleanupAdapter:vt,applyXctestRunnerAppIconFromDerivedPath:st}}const Qr={runCmdStreaming:re,runCmdSync:oe,runCmdBackground:ie,requireExecSuccess:ne,isCommandTimeoutError:se,shellQuote:ue,emitDiagnostic:u,withDiagnosticTimer:l,retryWithPolicy:de,isEnvTruthy:pe,deadlineFromTimeoutMs:(e,t)=>fe.fromTimeoutMs(e,t),isProcessAlive:m,isProcessGroupAlive:p,readProcessStartTime:te,readProcessCommand:h,signalPidsBestEffort:f,signalProcessGroupBestEffort:ae,findProjectRoot:me,readVersion:he,acquireProcessLock:le,withProcessLock:ce,withKeyedLock:ye,publishFileSync:d,classifyOwnerLiveness:ee,createTtlMemo:ge,parseBooleanLiteral:c,isRecord:a,resolveIosSimulatorDeviceSetPath:Ce,emitRequestProgress:Se,getRequestSignal:xe,isRequestCanceled:be,classifyBootFailure:_e,bootFailureHint:ve,runAppleToolCommand:we,runXcrun:Te,readApplePlistJson:Ee,buildSimctlArgsForDevice:Oe,resolveIosPhysicalDeviceControl:De,visitXmlPlistEntries:Dt,leaseOwnerStateDir:Ot,hasDeviceClaimAuthority:e=>kt()?.(e)??!1};var $r=e({applyXctestRunnerAppIconFromDerivedPath:()=>vi,cleanupRunnerLeasesForOwner:()=>hi,detachIosSimulatorRunnerSessionsForShutdown:()=>li,getRunnerSessionSnapshot:()=>ui,hasCachedAppleRunnerArtifact:()=>ci,hasLiveIosRunnerSession:()=>ni,notifyIosRunnerAppRelaunched:()=>ti,prepareIosRunner:()=>oi,prewarmAppleRunnerCache:()=>ii,prewarmIosRunnerSession:()=>ai,readStaleRunnerLease:()=>gi,releaseIosRunnerOnClose:()=>di,releaseSpeculativeIosRunnerSessionFor:()=>ri,resolveRunnerAppBundleId:()=>si,runApplePressSeries:()=>mi,runAppleRunnerCommand:()=>ei,stopAllIosRunnerSessions:()=>pi,stopIosRunnerSession:()=>fi,verifyLeaseRunnerPidIdentity:()=>_i});const $=Zr(Qr),ei=$.runAppleRunnerCommand,ti=$.notifyIosRunnerAppRelaunched,ni=$.hasLiveIosRunnerSession,ri=$.releaseSpeculativeIosRunnerSessionFor,ii=$.prewarmAppleRunnerCache,ai=$.prewarmIosRunnerSession,oi=$.prepareIosRunner,si=$.resolveRunnerAppBundleId,ci=$.hasCachedAppleRunnerArtifact,li=$.detachIosSimulatorRunnerSessionsForShutdown,ui=$.getRunnerSessionSnapshot,di=$.releaseIosRunnerOnClose,fi=$.stopIosRunnerSession,pi=$.stopAllIosRunnerSessions,mi=$.runApplePressSeries,hi=$.cleanupRunnerLeasesForOwner,gi=$.readStaleRunnerLease,_i=$.verifyLeaseRunnerPidIdentity,vi=$.applyXctestRunnerAppIconFromDerivedPath;export{pi as _,ni as a,ii as c,di as d,ri as f,$r as g,ei as h,ci as i,ai as l,mi as m,li as n,ti as o,si as p,ui as r,oi as s,vi as t,gi as u,fi as v,_i as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{A as t,C as n,T as r,j as i,w as a,z as o}from"./sdk-contracts.js";import{l as s,u as c}from"./sdk-device.js";import{i as l}from"./alert-contract.js";import{n as u}from"./entities.js";import{t as d}from"./parser.js";import{$ as f,A as p,B as m,C as ee,D as te,E as h,H as ne,I as re,J as ie,K as ae,L as oe,M as g,N as se,O as ce,P as le,R as ue,S as _,T as de,U as fe,V as pe,W as v,X as me,Y as he,Z as ge,_ as y,a as _e,b,d as ve,f as ye,g as be,h as xe,j as Se,k as Ce,l as we,m as Te,n as Ee,o as De,p as Oe,q as ke,r as Ae,s as je,t as Me,u as Ne,v as Pe,w as x,x as Fe,z as S}from"./runner-cache-metadata.js";import{c as Ie,n as Le}from"./apple-runner-platform.js";import C from"node:path";import w from"node:fs";import T from"node:crypto";import E from"node:os";import Re from"node:net";import ze from"node:http";async function Be(){return await new Promise((e,t)=>{let r=Re.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>t(new n(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,t)})}function D(e,t,n,r){t&&Ve(t,e),n&&Ve(n,e),r&&process.stderr.write(e)}const O=new Map;function Ve(e,t){let n=(O.get(e)??Promise.resolve()).catch(()=>{}).then(async()=>{await w.promises.mkdir(C.dirname(e),{recursive:!0}),await w.promises.appendFile(e,t)}).catch(()=>{}).finally(()=>{O.get(e)===n&&O.delete(e)});O.set(e,n)}function He(e){try{w.existsSync(e)&&w.unlinkSync(e)}catch{}}const k=new Map;function Ue(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return A(e,t,null,!1);let o=pe(e);if(o.backend===`xctest`||!r)return Ge(e,t);if(!a){let r=Ke(e.id);if(r)return A(e,t,r,!0);if(n!==void 0)return A(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&qe(e.id,s),A(e,t,s,!1)}}}function We(e){k.delete(e)}function Ge(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function A(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function Ke(e){let t=k.get(e);return t?t.expiresAt<=Date.now()?(k.delete(e),null):t.ip:null}function qe(e,t){k.set(e,{ip:t,expiresAt:Date.now()+3e4})}const j=`RUNNER_BUSY`,Je=`MAIN_THREAD_TIMEOUT`,Ye="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function Xe(e){let t=te(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}const Ze=e=>e.retriable===!0,Qe=e=>e.usbmuxDeviceAttached===!1,$e=[{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:Qe},verdicts:{connectRetry:!1}},{reason:`flagged_retriable`,match:{code:`COMMAND_FAILED`,details:Ze},verdicts:{retryable:!0,connectRetry:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`xcodebuild exited early`]},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:e=>e.runnerReadinessPreflightFailed===!0&&!t(e)},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`runner did not accept connection`]},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`runner endpoint probe failed`]},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:`RUNNER_WEDGED`},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}}];function et(e,t){return t.code!==void 0&&e.code!==t.code||!tt(e,t.details)?!1:nt(e,t.messageIncludesAll)}function tt(e,t){return t===void 0||t(e.details??{})}function nt(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function M(e,t){if(e instanceof n){for(let n of $e)if(n.verdicts[t]!==void 0&&et(e,n.match))return n.verdicts[t]}}function rt(e){return!(e instanceof n)||e.code!==`COMMAND_FAILED`?!1:M(e,`retryable`)??!1}function it(e){if(!(e instanceof n))return!1;let t=e.details?.runnerErrorCode;return t===j||t===Je}function N(e){return!(e instanceof n)||e.code!==`DEVICE_NOT_FOUND`?!1:Qe(e.details??{})}function at(e){return M(e,`connectRetry`)??!0}function ot(e){return M(e,`restartAfterReadinessPreflight`)??!1}function st(e){return M(e,`artifactSuspect`)??!1}function ct(e){return M(e,`sessionFatalReason`)}function lt(e){return(M(e,`restartBeforeSend`)??!1)&&at(e)}const ut=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,dt=new Set([j,Je,l,ut]);function ft(e){let t=e!==void 0&&dt.has(e);return Object.freeze({code:t?`COMMAND_FAILED`:o(e),details:Object.freeze({runnerErrorCode:e,...e===j?{retriable:!0}:{}})})}function pt(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?b(a):`${b(a)} ${Ye}`}function mt(e){let{port:t,endpoints:r,logPath:i,lastError:a}=e,o=`Runner did not accept connection`;return new n(`COMMAND_FAILED`,o,{port:t,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:_({error:a,message:o,context:{platform:`ios`,phase:`connect`}}),hint:b(`IOS_RUNNER_CONNECT_TIMEOUT`)})}async function ht(e){let{session:t,port:r,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=_({message:o,stdout:a.stdout,stderr:a.stderr,context:{platform:`ios`,phase:`connect`}});return new n(`COMMAND_FAILED`,o,{port:r,logPath:i,xcodebuild:{exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr},reason:s,hint:pt(o,a.stdout,a.stderr,s)})}function gt(e){let t=e.details?JSON.stringify(e.details):``,n=`${e.message}\n${t}`.toLowerCase();if(n.includes(`failed registering bundle identifier`)||n.includes(`app identifier`)&&n.includes(`not available`))return`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`;if(n.includes(`requires a development team`))return`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`;if(n.includes(`no profiles for`)||n.includes(`provisioning profile`))return`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`;if(n.includes(`code signing`))return`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}function _t(e){return gt(e)??Ye}function vt(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:yt()}}function yt(){return`runner-${T.randomUUID()}`}function bt(e){if(se(e))throw r()}const xt=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function St(e,t,n,r,i){let a=y.fromTimeoutMs(r);return await wt(e,t,await Ct(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function Ct(e,t,r,i){let a=await Tt(e,r,i);try{await Et(a,1,Ot(`ListDevices`));let e=kt((await Dt(a,r,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new n(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:xt})}finally{a.destroy()}}async function wt(e,t,n,r,i,a){let o=await Tt(e,i,a);try{await Et(o,2,Ot(`Connect`,{DeviceID:n,PortNumber:Pt(r)}));let e=jt((await Dt(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw Nt({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function Tt(e,t,i){if(Ft(t,`connect to usbmuxd`),i?.aborted)throw r();return await new Promise((a,o)=>{let s=Re.createConnection(e),c=!1,l=setTimeout(()=>{p(new n(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:t}))},t),u=()=>p(),d=e=>p(e),f=()=>p(r()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function Et(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function Dt(e,t,i){if(Ft(t,`read usbmuxd response`),i?.aborted)throw r();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new n(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:t})),t),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new n(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new n(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(r()),m=(t,n)=>{c||(c=!0,clearTimeout(l),e.off(`data`,u),e.off(`error`,d),e.off(`close`,f),i?.removeEventListener(`abort`,p),e.pause(),t?o(t):a(n))};e.on(`data`,u),e.once(`error`,d),e.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),e.resume()})}function Ot(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${u(e)}</key><integer>${t}</integer>`:`<key>${u(e)}</key><string>${u(t)}</string>`).join(``)}</dict></plist>`}function kt(e,t){for(let n of Mt(d(e))){let e=At(n);if(e?.udid===t)return e.id}}function At(e){if(e.name!==`dict`)return;let t=P(e,`Properties`);if(t?.name!==`dict`)return;let n=P(t,`SerialNumber`)?.text,r=Number(P(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function jt(e,t){for(let n of Mt(d(e))){if(n.name!==`dict`)continue;let e=P(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function P(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*Mt(e){for(let t of e)yield t,yield*Mt(t.children)}function Nt(e){let{result:t,udid:r,deviceId:i,port:a}=e;return t===2?new n(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:xt}):t===3?new n(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new n(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Pt(e){return(e&255)<<8|e>>>8&255}function Ft(e,t){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function It(e){return{postCommand:async(t,n,r,i,a)=>{let o=y.fromTimeoutMs(i),s=await St(e,t,n,o.remainingMs(),a);try{return await Rt(s,r,o.remainingMs(),a)}catch(e){throw s.destroy(),e}}}}const Lt=It(`/var/run/usbmuxd`);async function Rt(e,t,i,a){if(Vt(i),a?.aborted)throw r();let o=Buffer.from(JSON.stringify(t),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new ze.Agent;l.createConnection=(t,n)=>(n?.(null,e),e);try{let t=await zt(l,e,o,c);return new Response((await Bt(t)).toString(`utf8`),{status:t.statusCode??500})}catch(e){throw a?.aborted?r():s.aborted?new n(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):e}finally{l.destroy(),e.destroy()}}async function zt(e,t,n,r){return await new Promise((i,a)=>{let o=ze.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function Bt(e){let t=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new n(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function Vt(e){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const Ht=45e3;async function Ut(e,t,i,a=Ht,o){if(o?.aborted)throw r();let s=y.fromTimeoutMs(a),c=Ue(e,t),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await Wt(e,t,i,s,o)}catch(t){if(!Gt(e,t))throw t;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new n(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:t,endpoints:l.endpoints});return await Kt(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function Wt(e,t,r,i,a){let o=i.remainingMs();if(o<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await Lt.postCommand(e.id,t,r,o,a)}function Gt(e,t){return N(t)?pe(e).backend!==`xctest`:!1}async function Kt(e,t,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:r},e):e}}const qt=45e3,Jt=2e4;async function Yt(e,t,n,a,o=qt,s,c){let l=y.fromTimeoutMs(o),{resolveRoute:u,markUsbmuxUnattached:d}=Ue(e,t),f=await u(l.remainingMs()),p=null,m=Math.max(1,Math.ceil(o/250));try{return await fe(async({deadline:r})=>{let i=await Xt({device:e,port:t,command:n,timeoutMs:o,logPath:a,session:s,route:f,resolveRoute:u,markUsbmuxUnattached:d,signal:c,attemptDeadline:r,setRoute:e=>{f=e},setLastError:e=>{p=e}});if(i)return i;throw tn({port:t,endpoints:f.endpoints,lastError:p,signal:c})},{maxAttempts:m,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:at},{deadline:l,phase:`ios_runner_connect`,signal:c,retryWakeSignal:e.kind===`simulator`?s?.startupRetryWake:void 0})}catch(e){if(c?.aborted||i(e))throw r();if(N(e))throw e;p||=e}if(c?.aborted)throw r();if(e.kind===`simulator`){let r=l.remainingMs();if(r<=0)throw mt({port:t,endpoints:f.endpoints,logPath:a,lastError:p});let i=await on(e,t,n,r,c);return new Response(i.body,{status:i.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?await ht({session:s,port:t,logPath:a}):mt({port:t,endpoints:f.endpoints,logPath:a,lastError:p})}async function Xt(e){await Zt(e);let t=await Qt(e);return t.response?t.response:await $t(e)||await en(e,t.usedCachedTunnelIp)}async function Zt(e){if(e.attemptDeadline?.isExpired())throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await ht({session:e.session,port:e.port,logPath:e.logPath})}async function Qt(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await nn(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&We(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function $t(e){return e.device.kind!==`simulator`||!e.session?.ready?null:await an(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function en(e,t){if(e.device.kind!==`device`||!t)return null;We(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await nn(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function tn(e){if(e.signal?.aborted)throw r();return new n(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,endpoints:e.endpoints,lastError:e.lastError?String(e.lastError):void 0})}async function nn(e,t,a){if(t.kind===`network`)return await rn(t.endpoints,a);let o=t.endpoints[0];try{let t=a.attemptDeadline?.remainingMs()??a.timeoutMs;if(t<=0)throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:a.port,timeoutMs:a.timeoutMs});return await Lt.postCommand(e.id,a.port,a.command,Math.min(Jt,t),a.signal)}catch(t){if(a.signal?.aborted||i(t))throw r();if(N(t)){if(!Gt(e,t))throw t;return a.onUsbmuxUnattached?.(),null}return a.onError(o,t),null}}async function rn(e,t){let{command:a,port:o,timeoutMs:s,signal:c,attemptDeadline:l,onError:u}=t;for(let t of e)try{let e=l?.remainingMs()??s;if(e<=0)throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o,timeoutMs:s});return await Kt(t,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(a)},Math.min(Jt,e),c)}catch(e){if(c?.aborted||i(e))throw r();u(t,e)}return null}async function an(e,t,n,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let r=await on(e,t,n,l,o);return new Response(r.body,{status:r.status})}catch(e){if(o?.aborted||i(e))throw r();return c(e),null}}async function on(e,t,n,r,i){let a=JSON.stringify(n),o=Fe(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]);return{status:200,body:m(await ke(o,{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=_({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:b(n)}}).stdout}}const sn=`XCTestDevices`,cn=`.agent-device-backup`,ln=`.agent-device-xctestdevices-backup-`;function un(e=E.homedir()){return C.join(e,`Library`,`Developer`,`XCTestDevices`)}function dn(e=E.homedir()){return C.join(e,`.agent-device`,`xctest-device-set.lock`)}function fn(e=un()){return`${e}${cn}`}async function pn(e,t={}){if(!s(e)||e.kind!==`simulator`)return null;let r=ne(e.simulatorSetPath);if(!r)return null;let i=C.resolve(r),a=C.resolve(t.xctestDeviceSetPath??un()),o=C.resolve(t.backupPath??fn(a)),c=C.resolve(t.lockDirPath??dn()),l=t.ownerStartTime??S(process.pid),u=await yn({lockDirPath:c,owner:{pid:t.ownerPid??process.pid,startTime:l,acquiredAtMs:t.nowMs??Date.now()}});try{if(mn({xctestDeviceSetPath:a,backupPath:o}),vn(i,a))return await u(),null;w.mkdirSync(i,{recursive:!0}),w.existsSync(a)&&w.renameSync(a,o),gn({requestedSetPath:i,xctestDeviceSetPath:a})}catch(e){throw mn({xctestDeviceSetPath:a,backupPath:o}),await u(),new n(`COMMAND_FAILED`,`Failed to redirect XCTest device set path`,{requestedSetPath:i,xctestDeviceSetPath:a,backupPath:o,error:String(e)})}let d=!1;return{release:async()=>{if(!d){d=!0;try{mn({xctestDeviceSetPath:a,backupPath:o})}finally{await u()}}}}}function mn(e){let{xctestDeviceSetPath:t,backupPath:n}=e,r=[n,...hn(n)],i=r.find(e=>w.existsSync(e)),a=_n(t);if(i){if(a&&F(t),!w.existsSync(t))w.mkdirSync(C.dirname(t),{recursive:!0}),w.renameSync(i,t);else if(a)i===n?w.rmSync(n,{recursive:!0,force:!0}):w.rmSync(i,{recursive:!0,force:!0});else{x({level:`warn`,phase:`ios_runner_xctest_device_set_restore_collision`,data:{xctestDeviceSetPath:t,activeBackupPath:i}});return}for(let e of r)e!==i&&w.existsSync(e)&&w.rmSync(e,{recursive:!0,force:!0});return}a&&(x({level:`warn`,phase:`ios_runner_xctest_device_set_orphaned_symlink`,data:{xctestDeviceSetPath:t}}),F(t))}function hn(e){let t=C.dirname(e),n=C.basename(e).replace(cn,``),r=n===sn?ln:`${n}${ln}`;try{return w.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>C.join(t,e))}catch{return[]}}function gn(e){let{requestedSetPath:t,xctestDeviceSetPath:n}=e,r=C.dirname(n),i=C.join(r,`${sn}.agent-device-link-${process.pid}-${Date.now()}`);w.mkdirSync(r,{recursive:!0});try{w.symlinkSync(t,i,`dir`),w.renameSync(i,n)}catch(e){throw F(i),e}}function _n(e){return w.lstatSync(e,{throwIfNoEntry:!1})?.isSymbolicLink()??!1}function F(e){_n(e)&&w.unlinkSync(e)}function vn(e,t){if(C.resolve(e)===C.resolve(t))return!0;try{return w.realpathSync.native(e)===w.realpathSync.native(t)}catch{return!1}}async function yn(e){return await Pe({lockDirPath:e.lockDirPath,owner:e.owner,timeoutMs:e.timeoutMs??3e4,pollMs:e.pollMs??100,ownerGraceMs:5e3,description:e.description??`XCTest device set lock`})}const I=new Set;function bn(e){return C.join(e,Ee)}function xn(e,t){w.mkdirSync(e,{recursive:!0}),w.writeFileSync(bn(e),`${JSON.stringify(t,null,2)}\n`)}async function Sn(e,t){if(e.cache===`external`){B(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}I.add(e.derived);let n=await Cn(e.derived);try{B(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),z(e.derived),L(e.derived)}finally{await n()}}async function Cn(e){return await wn({lockDirPath:Tn(e),owner:{pid:process.pid,startTime:S(process.pid),acquiredAtMs:Date.now()},description:`iOS runner cache lock`})}async function wn(e){return await Pe({lockDirPath:e.lockDirPath,owner:e.owner,timeoutMs:e.timeoutMs??6e5,pollMs:100,ownerGraceMs:5e3,description:e.description??`iOS runner cache lock`})}function Tn(e){return C.join(C.dirname(e),`${C.basename(e)}.lock`)}function En(e,t){!zn()&&!t&&!I.has(e)||(B(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),z(e),L(e),I.delete(e))}function Dn(e,t,n,r){xn(e,Mn(t,n,r))}function L(e){try{if(!w.existsSync(e))return;if(C.basename(e)!==`derived`){w.rmSync(e,{recursive:!0,force:!0});return}for(let t of w.readdirSync(e,{withFileTypes:!0}))kn(t.name)&&w.rmSync(C.join(e,t.name),{recursive:!0,force:!0})}catch{}}const On=new Set([Ee,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function kn(e){return On.has(e)}function An(e){try{let t=JSON.parse(w.readFileSync(bn(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function jn(e,t){let n=An(e);return n?xe(Ae(n))===xe(Ae(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:_e(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function Mn(e,t,n){let r=Nn(t,n);return r?{...e,artifacts:r}:e}function Nn(e,t){let n=R(e);if(n===null||t.length===0)return null;let r=[];for(let e of t){let t=R(e);if(t===null)return null;r.push({path:e,...t})}return{xctestrunPath:e,xctestrunMtimeMs:n.mtimeMs,xctestrunSize:n.size,productPaths:r}}function Pn(e,t){let n=t?.artifacts;if(!Fn(n)||!Rn(n.xctestrunPath,e)||!Ln(n.xctestrunPath,{mtimeMs:n.xctestrunMtimeMs,size:n.xctestrunSize}))return null;let r=[];for(let t of n.productPaths){if(!Rn(t.path,e)||!Ln(t.path,t))return null;r.push(t.path)}return{xctestrunPath:n.xctestrunPath,productPaths:r}}function Fn(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.xctestrunPath==`string`&&Number.isInteger(t.xctestrunMtimeMs)&&Number.isInteger(t.xctestrunSize)&&Array.isArray(t.productPaths)&&t.productPaths.length>0&&t.productPaths.every(In)}function In(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.path==`string`&&Number.isInteger(t.mtimeMs)&&Number.isInteger(t.size)}function R(e){try{let t=w.statSync(e);return{mtimeMs:Math.trunc(t.mtimeMs),size:t.size}}catch{return null}}function Ln(e,t){let n=R(e);return n?.mtimeMs===t.mtimeMs&&n.size===t.size}function Rn(e,t){let n=C.relative(C.resolve(t),C.resolve(e));return n!==``&&!n.startsWith(`..`)&&!C.isAbsolute(n)}function zn(){return Ce(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function z(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!Bn(e))throw new n(`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(h(),`.tmp`)}.`})}function Bn(e){let t=C.resolve(h(),`.tmp`),n=C.relative(t,C.resolve(e));return n!==``&&!n.startsWith(`..`)&&!C.isAbsolute(n)}async function Vn(e){let t=jn(e.derived,e.expectedCacheMetadata),n=t.ok?Pn(e.derived,t.metadata):null,r=n?.xctestrunPath??e.findXctestrun(e.derived);if(!r)return{reason:`missing_xctestrun`,xctestrunPath:null};let i=n?.xctestrunPath===r,a=i?`manifest`:`scan`,o=i?n.productPaths:await e.resolveExistingXctestrunProductPaths(r);return o?!e.xctestrunReferencesProjectRoot(r,e.projectRoot)&&!i?{reason:`project_root_mismatch`,xctestrunPath:r,productPaths:o,source:a}:t.ok?{reason:`reuse_ready`,xctestrunPath:r,productPaths:o,source:a}:t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:r,productPaths:o,source:a,metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:r,productPaths:o,source:a}:{reason:`missing_products`,xctestrunPath:r,productPaths:[],source:a}}function Hn(e,t){B(`rebuild`,e.reason,{derived:t,xctestrunPath:e.xctestrunPath,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{}})}function B(e,t,n){x({level:e===`rebuild`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const Un=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),Wn=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function Gn(e,t,r){if(!c(e))return;if(t.length===0)throw new n(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:r});let i=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of i)if(!w.existsSync(e))throw new n(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:r});for(let e of i)await Yn(e)||await Kn(e,r)}async function Kn(e,t){try{let t=C.join(e,`Contents`,`Frameworks`),n=w.existsSync(t)?w.readdirSync(t).sort().map(e=>C.join(t,e)):[];for(let e of n)await v(`codesign`,[...Wn,e]);await v(`codesign`,[...Wn,e])}catch(n){let r=a(n,`COMMAND_FAILED`);throw qn(e,t,r.message,r.details)}if(!await Yn(e))throw qn(e,t,`Product still fails code signature verification after re-signing`)}function qn(e,t,r,i){return new n(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:r,details:i})}function Jn(e){if(!(e instanceof n))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&Un.has(t)}async function Yn(e){return(await v(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const Xn=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function Zn(e){let t=await er(e);if(!t||t.length===0)return null;let n=C.dirname(e),r=new Set,i=Qn(t,n);for(let e of i.testRootPaths){if(!w.existsSync(e))return null;r.add(e)}for(let e of $n(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Qn(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=sr(e);o&&r.add(C.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function $n(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>w.existsSync(C.join(e,t)));return n?C.join(n,t):null})}async function er(e){let t=await oe(e);if(t)return tr(t);if(process.platform===`darwin`)return null;try{return ar(w.readFileSync(e,`utf8`))}catch{return null}}function tr(e){let t=new Set;for(let n of[e,...nr(e),...rr(e)])for(let e of ir(n))t.add(e);return Array.from(t)}function nr(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 rr(e){return Object.values(e).filter(e=>g(e)&&`TestBundlePath`in e)}function ir(e){let t=new Set;for(let[n,r]of Object.entries(e))if(Xn.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 ar(e){return or(d(e))}function or(e){let t=new Set;return ge(e,(e,n)=>{if(Xn.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 sr(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const cr=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function lr(e){await ur(Cr(e))}async function ur(e){let t=e.filter(xr);if(t.length===0)return;let n=e.filter(e=>V(e)&&!Sr(e));for(let e of t){let t=br(e,n);t&&await dr(t,e)}}async function dr(e,t){let n=fr(e,t),r=await pr(e,t);(n||r)&&(await gr(t),yr(t))}function fr(e,t){let n=!1;for(let r of w.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!vr(r.name)||_r(C.join(e,r.name),C.join(t,r.name))&&(n=!0);return n}async function pr(e,t){let n=C.join(e,`Info.plist`),r=C.join(t,`Info.plist`),i=await oe(n),a=await oe(r);if(!i||!a)return!1;let o=mr(i,a);if(o.length===0)return!1;for(let e of o)await hr(r,e.key,e.value,e.shouldInsert);return!0}function mr(e,t){return cr.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 hr(e,t,n,r){m(await v(`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 gr(e){m(await v(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function _r(e,t){if(w.existsSync(t)){let n=w.readFileSync(e),r=w.readFileSync(t);return!n.equals(r)&&(w.copyFileSync(e,t),!0)}return w.copyFileSync(e,t),!0}function vr(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function yr(e){let t=new Date;w.utimesSync(e,t,t)}function br(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 xr(e){return V(e)&&Sr(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function Sr(e){return C.basename(e).endsWith(`-Runner.app`)}function V(e){return C.basename(e).endsWith(`.app`)}function Cr(e){if(!w.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of w.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=C.join(e,r.name);if(V(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const wr=new Map,H=new Set;async function Tr(e,t){let n=Er(t);if(n)return n;let r=h(),i=je(e,r,t.budget),a=Ne(e,i);return await f(wr,a,async()=>{let n=await Cn(a);try{return await Or({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}finally{await n()}})}function Er(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let r=C.resolve(t);if(!w.existsSync(r))throw new n(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:r});let i=e.iosXctestDerivedDataPath?.trim(),a=i?C.resolve(i):Dr(r);return B(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:r}),{xctestrunPath:r,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function Dr(e){let t=T.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return C.join(E.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function Or(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;En(a,e.forceRebuild);let o=await Nr({device:t,derived:a,projectRoot:r,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:o.xctestrunPath?`restore-key`:`miss`;return o.reason!==`reuse_ready`&&Hn(o,a),await kr({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.xctestrunPath&&(z(a),L(a)),await Ar({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function kr(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await jr(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,artifact:`valid`,buildMs:0,xctestrunPathSource:i.source}:null}async function Ar(e){let{device:t,options:r,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=be(i);if(!w.existsSync(l))throw new n(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=De(r.budget,`runner_xctestrun_build`),d=Date.now();de({type:`command`,status:`progress`,message:`Building Apple runner...`}),await zr(t,l,o,r,u);let f=Math.max(0,Date.now()-d),p=Pr(o,t);if(!p)throw new n(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await Zn(p);if(!m)throw new n(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await Gn(t,m,p),await ur(m),Dn(o,a,p,m),B(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function jr(e,t,n,r){try{return await Gn(e,r.productPaths,r.xctestrunPath),B(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),Dn(t,n,r.xctestrunPath,r.productPaths),r.xctestrunPath}catch(e){if(!Jn(e))throw e;return B(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function Mr(e){try{let t=h(),n=je(e,t);return(await Nr({device:e,derived:Ne(e,n),projectRoot:t,expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function Nr(e){let{device:t,derived:n,projectRoot:r,expectedCacheMetadata:i}=e;return Vn({derived:n,projectRoot:r,expectedCacheMetadata:i,findXctestrun:e=>Pr(e,t),xctestrunReferencesProjectRoot:Rr,resolveExistingXctestrunProductPaths:Zn})}function Pr(e,t){let n=Fr(e);return n.length===0?null:(n.sort((e,n)=>Ir(e,n,t)),n[0]?.path??null)}function Fr(e){if(!w.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=w.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=w.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function Ir(e,t,n){if(n){let r=Lr(t.path,n)-Lr(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function Lr(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=Ie(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}function Rr(e,t){try{let n=w.readFileSync(e,`utf8`),r=new Set([t]);try{r.add(w.realpathSync(t))}catch{}for(let e of r)if(n.includes(e))return!0;return!1}catch{return!1}}async function zr(e,t,r,a,o){let s=we(process.env),c=Te(process.env,e.kind===`device`,e),l=e.kind===`device`?[`-allowProvisioningUpdates`]:[],u=ye(),d=Oe(),f=await pn(e);try{await ae(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,ve(e),`1`,`-destination`,Le(e),`-derivedDataPath`,r,...u,...d,...s,...l,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:e=>{H.add(e),e.on(`close`,()=>{H.delete(e)})},onStdoutChunk:e=>{D(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{D(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(e){if(i(e))throw e;let t=e instanceof n?e:new n(`COMMAND_FAILED`,String(e)),r=_t(t);throw new n(`COMMAND_FAILED`,`xcodebuild build-for-testing failed`,{error:t.message,details:t.details,logPath:a.logPath,hint:r})}finally{await f?.release()}}const U=process.pid;let Br;function W(){return Br??={value:S(process.pid)},Br.value}function G(){return vi(U,W())}function Vr(e){return{schemaVersion:1,deviceId:e.deviceId,ownerToken:G(),ownerPid:U,ownerStartTime:W(),ownerStateDir:Jr(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?S(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,jsonPath:e.jsonPath,createdAtMs:Date.now(),deviceClaimProtocol:1}}async function Hr(e,t){let n=await Pe({lockDirPath:`${J(e)}.lock`,owner:{pid:U,startTime:W(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,ownerGraceMs:5e3,description:`iOS runner lease for ${e}`});try{return await t()}finally{await n()}}function K(e){try{return ui(JSON.parse(w.readFileSync(J(e),`utf8`)),e)}catch{return null}}function q(e){if(!e)return{type:`empty`};if(e.ownerToken===G())return{type:`owned`,lease:e};let t=ee({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 Ur(e,t,r){let i=e.id,a=q(K(i));if(a.type===`empty`){await t.cleanupRunnerXcodebuildProcesses(i,void 0);return}if(a.type===`busy`){if(Wr(a.lease)){await X(a.lease,`same-state-dir`,t);return}if(Gr(a.lease,e)){await X(a.lease,`device-claim-takeover`,t);return}if(Kr(a.lease,r)){await X(a.lease,`logical-lease-takeover`,t);return}throw new n(`COMMAND_FAILED`,r?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:r,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:Yr(a.lease,r)})}await X(a.lease,a.type,t)}function Wr(e){let t=Jr();return!t||!e.ownerStateDir?!1:C.resolve(t)===C.resolve(e.ownerStateDir)}function Gr(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&ce(t)}function Kr(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:qr(t.deviceKey,e.deviceId)}function qr(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function Jr(){return le()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function Yr(e,t){let n=Xr(e),r=Zr(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 Xr(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function Zr(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${Qr(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function Qr(e,t){return`${e}=${ie(t)}`}function $r(e){let t=q(K(e));return t.type===`stale`&&(t.staleReason===`owner-process-dead`||t.staleReason===`owner-process-reused`)?t.lease:null}function ei(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function ti(e,t){let n=q(K(e));n.type===`owned`&&await X(n.lease,`owned`,t)}async function ni(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=ci(e);await Promise.all(n.map(async e=>{await X(e,`owned`,t)}))}function ri(e){return K(e)?.ownerToken??null}function ii(e){e&&oi({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function ai(e){let t=J(e.deviceId);w.mkdirSync(C.dirname(t),{recursive:!0}),re({destination:t,contents:JSON.stringify(e,null,2)})}function oi(e){let t=K(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{w.unlinkSync(J(e.deviceId))}catch{}}function J(e){return C.join(si(),`${yi(e)}.json`)}function si(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?C.resolve(e):C.join(E.homedir(),`.agent-device`,`apple-runner`,`leases`)}function ci(e){let t,n=si();try{t=w.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=li(C.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function li(e){try{let t=JSON.parse(w.readFileSync(e,`utf8`)),n=Y(t.deviceId);return n?ui(t,n):null}catch{return null}}function ui(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=di(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:fi(n.ownerStartTime),ownerStateDir:fi(n.ownerStateDir)??void 0,runnerPid:pi(n.runnerPid),runnerStartTime:fi(n.runnerStartTime),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function di(e){let t={ownerToken:Y(e.ownerToken),ownerPid:pi(e.ownerPid),sessionId:Y(e.sessionId),port:pi(e.port),xctestrunPath:Y(e.xctestrunPath),jsonPath:Y(e.jsonPath),createdAtMs:mi(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function Y(e){return typeof e==`string`&&e.length>0?e:null}function fi(e){return typeof e==`string`?e:null}function pi(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function mi(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function X(e,t,n){x({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(hi(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses(e.deviceId,e.ownerToken),await n.cleanupRunnerProcessTree(hi(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),ii(e)}function hi(e){let t=e.runnerPid??void 0;if(!(!t||!p(t))){if(gi(e,t))return t;x({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function gi(e,t){return e.runnerStartTime?S(t)===e.runnerStartTime:_i(ue(t))}function _i(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function vi(e,t){let n=T.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function yi(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var bi=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>xi,abortRunnerSessionsAndPrepProcesses:()=>Ti,cleanupOwnedIosRunnerLease:()=>wi,disposeRunnerSession:()=>Ci,isRunnerProcessAlive:()=>Ii,runnerLeaseCleanupAdapter:()=>Z,stopRunnerPrepProcesses:()=>Ei});const xi=1e3,Si=2e3,Z={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Ri,cleanupTempFile:He};async function Ci(e,t={}){let n=!1;if(t.graceful!==!1)n=await Di(e);else if(c(e.device)){await ki([e]),await ji(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await Oi(e,t.waitTimeoutMs??1e4),Fi(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await ji(e,t)}async function wi(e){await ti(e,Z)}async function Ti(e){let t=Array.from(H),n=e.filter(e=>c(e.device)),r=e.filter(e=>!c(e.device));await Q(r,`SIGINT`),await Li(t,`SIGINT`),await Q(r,`SIGTERM`),await Li(t,`SIGTERM`),await Q(r,`SIGKILL`),await Li(t,`SIGKILL`),await ki(n),await Promise.allSettled(e.map(async e=>{await ji(e)}))}async function Ei(){let e=Array.from(H);await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{H.delete(e)}}))}async function Di(e){try{return await Yt(e.device,e.port,vt({command:`shutdown`}),void 0,15e3),!1}catch{return c(e.device)?(await ki([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function Oi(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!Fi(e.child.pid)}finally{n&&clearTimeout(n)}}async function ki(e){if(e.length===0)return;await Q(e,`SIGINT`);let t=await Ai(e,5e3);await Q(t,`SIGTERM`),await Q(await Ai(t,2e3),`SIGKILL`)}async function Ai(e,t){let n=await Promise.all(e.map(async e=>await Oi(e,t)));return e.filter((e,t)=>!n[t])}async function ji(e,t={}){await Mi(e,t),He(e.xctestrunPath),He(e.jsonPath),await e.simulatorSetRedirect?.release()}async function Mi(e,t){let n=async()=>{if(!Ni(e))try{await Pi(e.device)}finally{ii(e.lease)}};if(t.leaseLockHeld){await n();return}try{await Hr(e.deviceId,n)}catch(t){x({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 Ni(e){let t=ri(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Pi(e){e.kind===`simulator`&&await Promise.allSettled(Me.map(async t=>{try{await ke(Fe(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:Si})}catch(n){x({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:Si,error:n instanceof Error?n.message:String(n)}})}}))}function Fi(e){return e?Ii(e)||Se(e):!1}function Ii(e){return e?p(e):!1}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Li(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&H.delete(e)}))}async function $(e,t){if(!e||e<=0)return;me(e,t),he([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await v(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Ri(e,t){let n=t?`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${zi(e)}-${zi(t)}-`:`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${zi(e)}-[0-9]`;for(let t of[`TERM`,`KILL`])try{await v(`pkill`,[`-${t}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){x({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:e,signal:t,error:n instanceof Error?n.message:String(n)}})}}function zi(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}export{rt as A,D as B,qt as C,ut as D,Ut as E,ot as F,lt as I,at as L,ct as M,Xe as N,bt as O,st as P,vt as R,pn as S,Ht as T,ai as _,Ii as a,lr as b,Ei as c,ni as d,Ur as f,Hr as g,gi as h,Ci as i,it as j,ft as k,ei as l,G as m,Ti as n,Z as o,$r as p,wi as r,bi as s,xi as t,Vr as u,Tr as v,Yt as w,Sn as x,Mr as y,Be as z};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{A as t,C as n,T as r,j as i,w as a,z as o}from"./sdk-contracts.js";import{l as s,u as c}from"./sdk-device.js";import{i as l}from"./alert-contract.js";import{n as u}from"./entities.js";import{t as d}from"./parser.js";import{$ as f,A as p,B as m,C as ee,D as te,E as h,H as ne,I as re,J as ie,K as ae,L as oe,M as se,N as ce,O as le,P as ue,R as de,S as fe,T as pe,U as me,V as he,W as g,X as ge,Y as _e,Z as ve,_,a as ye,b as v,d as be,et as y,f as xe,g as Se,h as Ce,j as we,k as Te,l as Ee,m as De,n as Oe,o as ke,p as Ae,q as je,r as Me,s as Ne,t as Pe,u as Fe,v as b,w as x,x as Ie,z as S}from"./runner-cache-metadata.js";import{c as Le,n as Re}from"./apple-runner-platform.js";import C from"node:path";import w from"node:fs";import ze from"node:crypto";import T from"node:os";import Be from"node:net";import Ve from"node:http";async function He(){return await new Promise((e,t)=>{let r=Be.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>t(new n(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,t)})}function Ue(e,t,n,r){t&&We(t,e),n&&We(n,e),r&&process.stderr.write(e)}const E=new Map;function We(e,t){let n=(E.get(e)??Promise.resolve()).catch(()=>{}).then(async()=>{await w.promises.mkdir(C.dirname(e),{recursive:!0}),await w.promises.appendFile(e,t)}).catch(()=>{}).finally(()=>{E.get(e)===n&&E.delete(e)});E.set(e,n)}function D(e){try{w.existsSync(e)&&w.unlinkSync(e)}catch{}}const O=new Map;function Ge(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return k(e,t,null,!1);let o=he(e);if(o.backend===`xctest`||!r)return qe(e,t);if(!a){let r=Je(e.id);if(r)return k(e,t,r,!0);if(n!==void 0)return k(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&Ye(e.id,s),k(e,t,s,!1)}}}function Ke(e){O.delete(e)}function qe(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function k(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function Je(e){let t=O.get(e);return t?t.expiresAt<=Date.now()?(O.delete(e),null):t.ip:null}function Ye(e,t){O.set(e,{ip:t,expiresAt:Date.now()+3e4})}const Xe=`RUNNER_BUSY`,Ze=`MAIN_THREAD_TIMEOUT`,Qe="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function $e(e){let t=te(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}const et=e=>e.retriable===!0,tt=e=>e.usbmuxDeviceAttached===!1,nt=[{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:tt},verdicts:{connectRetry:!1}},{reason:`flagged_retriable`,match:{code:`COMMAND_FAILED`,details:et},verdicts:{retryable:!0,connectRetry:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`xcodebuild exited early`]},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:e=>e.runnerReadinessPreflightFailed===!0&&!t(e)},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`runner did not accept connection`]},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`runner endpoint probe failed`]},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:`RUNNER_WEDGED`},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}}];function rt(e,t){return t.code!==void 0&&e.code!==t.code||!it(e,t.details)?!1:at(e,t.messageIncludesAll)}function it(e,t){return t===void 0||t(e.details??{})}function at(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function A(e,t){if(e instanceof n){for(let n of nt)if(n.verdicts[t]!==void 0&&rt(e,n.match))return n.verdicts[t]}}function ot(e){return!(e instanceof n)||e.code!==`COMMAND_FAILED`?!1:A(e,`retryable`)??!1}function st(e){if(!(e instanceof n))return!1;let t=e.details?.runnerErrorCode;return t===Xe||t===Ze}function j(e){return!(e instanceof n)||e.code!==`DEVICE_NOT_FOUND`?!1:tt(e.details??{})}function ct(e){return A(e,`connectRetry`)??!0}function lt(e){return A(e,`restartAfterReadinessPreflight`)??!1}function ut(e){return A(e,`artifactSuspect`)??!1}function dt(e){return A(e,`sessionFatalReason`)}function ft(e){return(A(e,`restartBeforeSend`)??!1)&&ct(e)}const pt=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,mt=new Set([Xe,Ze,l,pt]);function ht(e){let t=e!==void 0&&mt.has(e);return Object.freeze({code:t?`COMMAND_FAILED`:o(e),details:Object.freeze({runnerErrorCode:e,...e===Xe?{retriable:!0}:{}})})}function gt(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?v(a):`${v(a)} ${Qe}`}function _t(e){let{port:t,endpoints:r,logPath:i,lastError:a}=e,o=`Runner did not accept connection`;return new n(`COMMAND_FAILED`,o,{port:t,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:fe({error:a,message:o,context:{platform:`ios`,phase:`connect`}}),hint:v(`IOS_RUNNER_CONNECT_TIMEOUT`)})}async function vt(e){let{session:t,port:r,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=fe({message:o,stdout:a.stdout,stderr:a.stderr,context:{platform:`ios`,phase:`connect`}});return new n(`COMMAND_FAILED`,o,{port:r,logPath:i,xcodebuild:{exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr},reason:s,hint:gt(o,a.stdout,a.stderr,s)})}function yt(e){let t=e.details?JSON.stringify(e.details):``,n=`${e.message}\n${t}`.toLowerCase();if(n.includes(`failed registering bundle identifier`)||n.includes(`app identifier`)&&n.includes(`not available`))return`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`;if(n.includes(`requires a development team`))return`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`;if(n.includes(`no profiles for`)||n.includes(`provisioning profile`))return`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`;if(n.includes(`code signing`))return`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}function bt(e){return yt(e)??Qe}function xt(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:St()}}function St(){return`runner-${ze.randomUUID()}`}function Ct(e){if(ce(e))throw r()}const wt=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function Tt(e,t,n,r,i){let a=_.fromTimeoutMs(r);return await Dt(e,t,await Et(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function Et(e,t,r,i){let a=await Ot(e,r,i);try{await kt(a,1,jt(`ListDevices`));let e=Mt((await At(a,r,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new n(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:wt})}finally{a.destroy()}}async function Dt(e,t,n,r,i,a){let o=await Ot(e,i,a);try{await kt(o,2,jt(`Connect`,{DeviceID:n,PortNumber:It(r)}));let e=Pt((await At(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw Ft({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function Ot(e,t,i){if(Lt(t,`connect to usbmuxd`),i?.aborted)throw r();return await new Promise((a,o)=>{let s=Be.createConnection(e),c=!1,l=setTimeout(()=>{p(new n(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:t}))},t),u=()=>p(),d=e=>p(e),f=()=>p(r()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function kt(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function At(e,t,i){if(Lt(t,`read usbmuxd response`),i?.aborted)throw r();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new n(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:t})),t),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new n(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new n(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(r()),m=(t,n)=>{c||(c=!0,clearTimeout(l),e.off(`data`,u),e.off(`error`,d),e.off(`close`,f),i?.removeEventListener(`abort`,p),e.pause(),t?o(t):a(n))};e.on(`data`,u),e.once(`error`,d),e.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),e.resume()})}function jt(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${u(e)}</key><integer>${t}</integer>`:`<key>${u(e)}</key><string>${u(t)}</string>`).join(``)}</dict></plist>`}function Mt(e,t){for(let n of N(d(e))){let e=Nt(n);if(e?.udid===t)return e.id}}function Nt(e){if(e.name!==`dict`)return;let t=M(e,`Properties`);if(t?.name!==`dict`)return;let n=M(t,`SerialNumber`)?.text,r=Number(M(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function Pt(e,t){for(let n of N(d(e))){if(n.name!==`dict`)continue;let e=M(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function M(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*N(e){for(let t of e)yield t,yield*N(t.children)}function Ft(e){let{result:t,udid:r,deviceId:i,port:a}=e;return t===2?new n(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:wt}):t===3?new n(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new n(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function It(e){return(e&255)<<8|e>>>8&255}function Lt(e,t){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function Rt(e){return{postCommand:async(t,n,r,i,a)=>{let o=_.fromTimeoutMs(i),s=await Tt(e,t,n,o.remainingMs(),a);try{return await Bt(s,r,o.remainingMs(),a)}catch(e){throw s.destroy(),e}}}}const zt=Rt(`/var/run/usbmuxd`);async function Bt(e,t,i,a){if(Ut(i),a?.aborted)throw r();let o=Buffer.from(JSON.stringify(t),`utf8`),s=AbortSignal.timeout(i),c=a?AbortSignal.any([a,s]):s,l=new Ve.Agent;l.createConnection=(t,n)=>(n?.(null,e),e);try{let t=await Vt(l,e,o,c);return new Response((await Ht(t)).toString(`utf8`),{status:t.statusCode??500})}catch(e){throw a?.aborted?r():s.aborted?new n(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:i}):e}finally{l.destroy(),e.destroy()}}async function Vt(e,t,n,r){return await new Promise((i,a)=>{let o=Ve.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function Ht(e){let t=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new n(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function Ut(e){if(!(e>0))throw new n(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const Wt=45e3;async function Gt(e,t,i,a=Wt,o){if(o?.aborted)throw r();let s=_.fromTimeoutMs(a),c=Ge(e,t),l=await c.resolveRoute(s.remainingMs());if(l.kind===`usbmux`)try{return await Kt(e,t,i,s,o)}catch(t){if(!qt(e,t))throw t;c.markUsbmuxUnattached(),l=await c.resolveRoute(s.remainingMs())}let u=s.remainingMs();if(u<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:a});let d=l.endpoints[0];if(!d)throw new n(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:t,endpoints:l.endpoints});return await Jt(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)},u,o)}async function Kt(e,t,r,i,a){let o=i.remainingMs();if(o<=0)throw new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:t,timeoutMs:o});return await zt.postCommand(e.id,t,r,o,a)}function qt(e,t){return j(t)?he(e).backend!==`xctest`:!1}async function Jt(e,t,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,signal:o})}catch(e){throw e===a.reason?new n(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:r},e):e}}const Yt=45e3,Xt=2e4;async function Zt(e,t,n,a,o=Yt,s,c){let l=_.fromTimeoutMs(o),{resolveRoute:u,markUsbmuxUnattached:d}=Ge(e,t),f=await u(l.remainingMs()),p=null,m=Math.max(1,Math.ceil(o/250));try{return await me(async({deadline:r})=>{let i=await Qt({device:e,port:t,command:n,timeoutMs:o,logPath:a,session:s,route:f,resolveRoute:u,markUsbmuxUnattached:d,signal:c,attemptDeadline:r,setRoute:e=>{f=e},setLastError:e=>{p=e}});if(i)return i;throw rn({port:t,endpoints:f.endpoints,lastError:p,signal:c})},{maxAttempts:m,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:ct},{deadline:l,phase:`ios_runner_connect`,signal:c,retryWakeSignal:e.kind===`simulator`?s?.startupRetryWake:void 0})}catch(e){if(c?.aborted||i(e))throw r();if(j(e))throw e;p||=e}if(c?.aborted)throw r();if(e.kind===`simulator`){let r=l.remainingMs();if(r<=0)throw _t({port:t,endpoints:f.endpoints,logPath:a,lastError:p});let i=await cn(e,t,n,r,c);return new Response(i.body,{status:i.status})}throw s?.child.exitCode!==null&&s?.child.exitCode!==void 0?await vt({session:s,port:t,logPath:a}):_t({port:t,endpoints:f.endpoints,logPath:a,lastError:p})}async function Qt(e){await $t(e);let t=await en(e);return t.response?t.response:await tn(e)||await nn(e,t.usedCachedTunnelIp)}async function $t(e){if(e.attemptDeadline?.isExpired())throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await vt({session:e.session,port:e.port,logPath:e.logPath})}async function en(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await an(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&Ke(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function tn(e){return e.device.kind!==`simulator`||!e.session?.ready?null:await sn(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function nn(e,t){if(e.device.kind!==`device`||!t)return null;Ke(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await an(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function rn(e){if(e.signal?.aborted)throw r();return new n(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,endpoints:e.endpoints,lastError:e.lastError?String(e.lastError):void 0})}async function an(e,t,a){if(t.kind===`network`)return await on(t.endpoints,a);let o=t.endpoints[0];try{let t=a.attemptDeadline?.remainingMs()??a.timeoutMs;if(t<=0)throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:a.port,timeoutMs:a.timeoutMs});return await zt.postCommand(e.id,a.port,a.command,Math.min(Xt,t),a.signal)}catch(t){if(a.signal?.aborted||i(t))throw r();if(j(t)){if(!qt(e,t))throw t;return a.onUsbmuxUnattached?.(),null}return a.onError(o,t),null}}async function on(e,t){let{command:a,port:o,timeoutMs:s,signal:c,attemptDeadline:l,onError:u}=t;for(let t of e)try{let e=l?.remainingMs()??s;if(e<=0)throw new n(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:o,timeoutMs:s});return await Jt(t,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(a)},Math.min(Xt,e),c)}catch(e){if(c?.aborted||i(e))throw r();u(t,e)}return null}async function sn(e,t,n,a){let{signal:o,attemptDeadline:s,onError:c}=a,l=s?.remainingMs()??45e3;if(l<=0)return null;try{let r=await cn(e,t,n,l,o);return new Response(r.body,{status:r.status})}catch(e){if(o?.aborted||i(e))throw r();return c(e),null}}async function cn(e,t,n,r,i){let a=JSON.stringify(n),o=Ie(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]);return{status:200,body:m(await je(o,{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=fe({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:v(n)}}).stdout}}const ln=`XCTestDevices`,un=`.agent-device-backup`,dn=`.agent-device-xctestdevices-backup-`;function fn(e=T.homedir()){return C.join(e,`Library`,`Developer`,`XCTestDevices`)}function pn(e=T.homedir()){return C.join(e,`.agent-device`,`xctest-device-set.lock`)}function mn(e=fn()){return`${e}${un}`}async function hn(e,t,n={}){let r=await gn(e,n);return r?await y({acquire:async()=>r.release,task:t}):await t()}async function gn(e,t={}){if(!s(e)||e.kind!==`simulator`)return null;let n=ne(e.simulatorSetPath);if(!n)return null;let r=C.resolve(n),i=C.resolve(t.xctestDeviceSetPath??fn()),a=C.resolve(t.backupPath??mn(i)),o=C.resolve(t.lockDirPath??pn()),c=await b({lockDirPath:o,owner:{pid:process.pid,startTime:S(process.pid),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,ownerGraceMs:5e3,description:`XCTest device set lock`}),l={xctestDeviceSetPath:i,backupPath:a},u=!1;try{Sn(l),u=!Tn(r,i),u&&_n(l,r)}catch(e){throw vn(e,await P(l,o,c),{requestedSetPath:r,...l})}if(!u){let e=await P(l,o,c);if(e.restoreFailure!==null)throw e.restoreFailure;return null}let d=!1,f=async e=>{if(d)return;d=!0;let t=await P(l,o,c);if(t.restoreFailure!==null)throw t.restoreFailure;if(t.releaseFailure!==null&&e)throw t.releaseFailure};return{release:()=>f(!0),releaseBestEffort:()=>f(!1)}}function _n(e,t){w.mkdirSync(t,{recursive:!0}),w.existsSync(e.xctestDeviceSetPath)&&w.renameSync(e.xctestDeviceSetPath,e.backupPath),wn({requestedSetPath:t,xctestDeviceSetPath:e.xctestDeviceSetPath})}function vn(e,t,r){return new n(`COMMAND_FAILED`,`Failed to redirect XCTest device set path`,{...r,error:String(e),...t.restoreFailure===null?{}:{restoreError:String(t.restoreFailure)},...t.renamedAsidePath===null?{}:{hint:`The host's own device set is still renamed aside at ${t.renamedAsidePath}: restore it, or remove that path, before another runner build redirects it.`}})}async function P(e,t,n){let r=null,i=null,a=null;try{Sn(e)}catch(t){r=t,i=yn(e)}try{await n()}catch(e){a=e}return bn(a,t),{restoreFailure:r,renamedAsidePath:i,releaseFailure:a}}function yn(e){let{xctestDeviceSetPath:t,backupPath:n}=e;return!F(t)&&w.existsSync(t)?null:[n,...Cn(n)].find(e=>w.existsSync(e))??null}function bn(e,t){e===null||xn(e)||x({level:`warn`,phase:`ios_runner_xctest_device_set_hand_back_failed`,data:{lockDirPath:t,error:String(e)}})}function xn(e){return e instanceof n&&e.details?.ownerReleaseUnverified===!0}function Sn(e){let{xctestDeviceSetPath:t,backupPath:n}=e,r=[n,...Cn(n)],i=r.find(e=>w.existsSync(e)),a=F(t);if(i){if(a&&I(t),!w.existsSync(t))w.mkdirSync(C.dirname(t),{recursive:!0}),w.renameSync(i,t);else if(a)i===n?w.rmSync(n,{recursive:!0,force:!0}):w.rmSync(i,{recursive:!0,force:!0});else{x({level:`warn`,phase:`ios_runner_xctest_device_set_restore_collision`,data:{xctestDeviceSetPath:t,activeBackupPath:i}});return}for(let e of r)e!==i&&w.existsSync(e)&&w.rmSync(e,{recursive:!0,force:!0});return}a&&(x({level:`warn`,phase:`ios_runner_xctest_device_set_orphaned_symlink`,data:{xctestDeviceSetPath:t}}),I(t))}function Cn(e){let t=C.dirname(e),n=C.basename(e).replace(un,``),r=n===ln?dn:`${n}${dn}`;try{return w.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>C.join(t,e))}catch{return[]}}function wn(e){let{requestedSetPath:t,xctestDeviceSetPath:n}=e,r=C.dirname(n),i=C.join(r,`${ln}.agent-device-link-${process.pid}-${Date.now()}`);w.mkdirSync(r,{recursive:!0});try{w.symlinkSync(t,i,`dir`),w.renameSync(i,n)}catch(e){throw I(i),e}}function F(e){return w.lstatSync(e,{throwIfNoEntry:!1})?.isSymbolicLink()??!1}function I(e){F(e)&&w.unlinkSync(e)}function Tn(e,t){if(C.resolve(e)===C.resolve(t))return!0;try{return w.realpathSync.native(e)===w.realpathSync.native(t)}catch{return!1}}const L=new Set;function En(e){return C.join(e,Oe)}function Dn(e,t){w.mkdirSync(e,{recursive:!0}),w.writeFileSync(En(e),`${JSON.stringify(t,null,2)}\n`)}async function On(e,t){if(e.cache===`external`){V(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}L.add(e.derived),await y({acquire:()=>kn(e.derived),task:async()=>{V(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),B(e.derived),R(e.derived)}})}async function kn(e){return await b({lockDirPath:An(e),owner:{pid:process.pid,startTime:S(process.pid),acquiredAtMs:Date.now()},timeoutMs:6e5,pollMs:100,ownerGraceMs:5e3,description:`iOS runner cache lock`})}function An(e){return C.join(C.dirname(e),`${C.basename(e)}.lock`)}function jn(e,t){!Wn()&&!t&&!L.has(e)||(V(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),B(e),R(e),L.delete(e))}function Mn(e,t,n,r){Dn(e,Ln(t,n,r))}function R(e){try{if(!w.existsSync(e))return;if(C.basename(e)!==`derived`){w.rmSync(e,{recursive:!0,force:!0});return}for(let t of w.readdirSync(e,{withFileTypes:!0}))Pn(t.name)&&w.rmSync(C.join(e,t.name),{recursive:!0,force:!0})}catch{}}const Nn=new Set([Oe,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Pn(e){return Nn.has(e)}function Fn(e){try{let t=JSON.parse(w.readFileSync(En(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function In(e,t){let n=Fn(e);return n?Ce(Me(n))===Ce(Me(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:ye(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function Ln(e,t,n){let r=Rn(t,n);return r?{...e,artifacts:r}:e}function Rn(e,t){let n=z(e);if(n===null||t.length===0)return null;let r=[];for(let e of t){let t=z(e);if(t===null)return null;r.push({path:e,...t})}return{xctestrunPath:e,xctestrunMtimeMs:n.mtimeMs,xctestrunSize:n.size,productPaths:r}}function zn(e,t){let n=t?.artifacts;if(!Bn(n)||!Un(n.xctestrunPath,e)||!Hn(n.xctestrunPath,{mtimeMs:n.xctestrunMtimeMs,size:n.xctestrunSize}))return null;let r=[];for(let t of n.productPaths){if(!Un(t.path,e)||!Hn(t.path,t))return null;r.push(t.path)}return{xctestrunPath:n.xctestrunPath,productPaths:r}}function Bn(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.xctestrunPath==`string`&&Number.isInteger(t.xctestrunMtimeMs)&&Number.isInteger(t.xctestrunSize)&&Array.isArray(t.productPaths)&&t.productPaths.length>0&&t.productPaths.every(Vn)}function Vn(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.path==`string`&&Number.isInteger(t.mtimeMs)&&Number.isInteger(t.size)}function z(e){try{let t=w.statSync(e);return{mtimeMs:Math.trunc(t.mtimeMs),size:t.size}}catch{return null}}function Hn(e,t){let n=z(e);return n?.mtimeMs===t.mtimeMs&&n.size===t.size}function Un(e,t){let n=C.relative(C.resolve(t),C.resolve(e));return n!==``&&!n.startsWith(`..`)&&!C.isAbsolute(n)}function Wn(){return Te(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function B(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!Gn(e))throw new n(`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(h(),`.tmp`)}.`})}function Gn(e){let t=C.resolve(h(),`.tmp`),n=C.relative(t,C.resolve(e));return n!==``&&!n.startsWith(`..`)&&!C.isAbsolute(n)}async function Kn(e){let t=In(e.derived,e.expectedCacheMetadata),n=t.ok?zn(e.derived,t.metadata):null,r=n?.xctestrunPath??e.findXctestrun(e.derived);if(!r)return{reason:`missing_xctestrun`,xctestrunPath:null};let i=n?.xctestrunPath===r,a=i?`manifest`:`scan`,o=i?n.productPaths:await e.resolveExistingXctestrunProductPaths(r);return o?!e.xctestrunReferencesProjectRoot(r,e.projectRoot)&&!i?{reason:`project_root_mismatch`,xctestrunPath:r,productPaths:o,source:a}:t.ok?{reason:`reuse_ready`,xctestrunPath:r,productPaths:o,source:a}:t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:r,productPaths:o,source:a,metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:r,productPaths:o,source:a}:{reason:`missing_products`,xctestrunPath:r,productPaths:[],source:a}}function qn(e,t){V(`rebuild`,e.reason,{derived:t,xctestrunPath:e.xctestrunPath,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{}})}function V(e,t,n){x({level:e===`rebuild`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const Jn=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]),Yn=[`--force`,`--preserve-metadata=identifier,entitlements,flags,runtime`,`--sign`,`-`];async function Xn(e,t,r){if(!c(e))return;if(t.length===0)throw new n(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:r});let i=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of i)if(!w.existsSync(e))throw new n(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:r});for(let e of i)await er(e)||await Zn(e,r)}async function Zn(e,t){try{let t=C.join(e,`Contents`,`Frameworks`),n=w.existsSync(t)?w.readdirSync(t).sort().map(e=>C.join(t,e)):[];for(let e of n)await g(`codesign`,[...Yn,e]);await g(`codesign`,[...Yn,e])}catch(n){let r=a(n,`COMMAND_FAILED`);throw Qn(e,t,r.message,r.details)}if(!await er(e))throw Qn(e,t,`Product still fails code signature verification after re-signing`)}function Qn(e,t,r,i){return new n(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:t,error:r,details:i})}function $n(e){if(!(e instanceof n))return!1;let t=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof t==`string`&&Jn.has(t)}async function er(e){return(await g(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const tr=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function nr(e){let t=await ar(e);if(!t||t.length===0)return null;let n=C.dirname(e),r=new Set,i=rr(t,n);for(let e of i.testRootPaths){if(!w.existsSync(e))return null;r.add(e)}for(let e of ir(i)){if(!e)return null;r.add(e)}return Array.from(r)}function rr(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=fr(e);o&&r.add(C.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function ir(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>w.existsSync(C.join(e,t)));return n?C.join(n,t):null})}async function ar(e){let t=await oe(e);if(t)return or(t);if(process.platform===`darwin`)return null;try{return ur(w.readFileSync(e,`utf8`))}catch{return null}}function or(e){let t=new Set;for(let n of[e,...sr(e),...cr(e)])for(let e of lr(n))t.add(e);return Array.from(t)}function sr(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!se(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(se))}return n}function cr(e){return Object.values(e).filter(e=>se(e)&&`TestBundlePath`in e)}function lr(e){let t=new Set;for(let[n,r]of Object.entries(e))if(tr.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 ur(e){return dr(d(e))}function dr(e){let t=new Set;return ve(e,(e,n)=>{if(tr.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 fr(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const pr=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function mr(e){await hr(Or(e))}async function hr(e){let t=e.filter(Er);if(t.length===0)return;let n=e.filter(e=>H(e)&&!Dr(e));for(let e of t){let t=Tr(e,n);t&&await gr(t,e)}}async function gr(e,t){let n=_r(e,t),r=await vr(e,t);(n||r)&&(await xr(t),wr(t))}function _r(e,t){let n=!1;for(let r of w.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!Cr(r.name)||Sr(C.join(e,r.name),C.join(t,r.name))&&(n=!0);return n}async function vr(e,t){let n=C.join(e,`Info.plist`),r=C.join(t,`Info.plist`),i=await oe(n),a=await oe(r);if(!i||!a)return!1;let o=yr(i,a);if(o.length===0)return!1;for(let e of o)await br(r,e.key,e.value,e.shouldInsert);return!0}function yr(e,t){return pr.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 br(e,t,n,r){m(await g(`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 xr(e){m(await g(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function Sr(e,t){if(w.existsSync(t)){let n=w.readFileSync(e),r=w.readFileSync(t);return!n.equals(r)&&(w.copyFileSync(e,t),!0)}return w.copyFileSync(e,t),!0}function Cr(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function wr(e){let t=new Date;w.utimesSync(e,t,t)}function Tr(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 Er(e){return H(e)&&Dr(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function Dr(e){return C.basename(e).endsWith(`-Runner.app`)}function H(e){return C.basename(e).endsWith(`.app`)}function Or(e){if(!w.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop();for(let r of w.readdirSync(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let i=C.join(e,r.name);if(H(i)){t.push(i);continue}n.push(i)}}return t.sort((e,t)=>e.localeCompare(t))}const kr=new Map,U=new Set;async function Ar(e,t){let n=jr(t);if(n)return n;let r=h(),i=Ne(e,r,t.budget),a=Fe(e,i);return await f(kr,a,async()=>await y({acquire:()=>kn(a),task:()=>Nr({device:e,options:t,projectRoot:r,expectedCacheMetadata:i,derived:a,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}))}function jr(e){let t=e.iosXctestrunFile?.trim();if(!t)return null;let r=C.resolve(t);if(!w.existsSync(r))throw new n(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:r});let i=e.iosXctestDerivedDataPath?.trim(),a=i?C.resolve(i):Mr(r);return V(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:r}),{xctestrunPath:r,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function Mr(e){let t=ze.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return C.join(T.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function Nr(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;jn(a,e.forceRebuild);let o=await Rr({device:t,derived:a,projectRoot:r,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:o.xctestrunPath?`restore-key`:`miss`;return o.reason!==`reuse_ready`&&qn(o,a),await Pr({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.xctestrunPath&&(B(a),R(a)),await Fr({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function Pr(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await Ir(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,artifact:`valid`,buildMs:0,xctestrunPathSource:i.source}:null}async function Fr(e){let{device:t,options:r,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=Se(i);if(!w.existsSync(l))throw new n(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=ke(r.budget,`runner_xctestrun_build`),d=Date.now();pe({type:`command`,status:`progress`,message:`Building Apple runner...`}),await Wr(t,l,o,r,u);let f=Math.max(0,Date.now()-d),p=zr(o,t);if(!p)throw new n(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let m=await nr(p);if(!m)throw new n(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:p});return await Xn(t,m,p),await hr(m),Mn(o,a,p,m),V(`build`,`built_new`,{derived:o,xctestrunPath:p}),{xctestrunPath:p,derived:o,cache:s,artifact:`rebuilt`,buildMs:f,xctestrunPathSource:`build`,reason:c}}async function Ir(e,t,n,r){try{return await Xn(e,r.productPaths,r.xctestrunPath),V(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),Mn(t,n,r.xctestrunPath,r.productPaths),r.xctestrunPath}catch(e){if(!$n(e))throw e;return V(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function Lr(e){try{let t=h(),n=Ne(e,t);return(await Rr({device:e,derived:Fe(e,n),projectRoot:t,expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function Rr(e){let{device:t,derived:n,projectRoot:r,expectedCacheMetadata:i}=e;return Kn({derived:n,projectRoot:r,expectedCacheMetadata:i,findXctestrun:e=>zr(e,t),xctestrunReferencesProjectRoot:Ur,resolveExistingXctestrunProductPaths:nr})}function zr(e,t){let n=Br(e);return n.length===0?null:(n.sort((e,n)=>Vr(e,n,t)),n[0]?.path??null)}function Br(e){if(!w.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=w.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=w.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function Vr(e,t,n){if(n){let r=Hr(t.path,n)-Hr(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function Hr(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=Le(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}function Ur(e,t){try{let n=w.readFileSync(e,`utf8`),r=new Set([t]);try{r.add(w.realpathSync(t))}catch{}for(let e of r)if(n.includes(e))return!0;return!1}catch{return!1}}async function Wr(e,t,r,a,o){let s=Ee(process.env),c=De(process.env,e.kind===`device`,e),l=e.kind===`device`?[`-allowProvisioningUpdates`]:[],u=xe(),d=Ae();await hn(e,async()=>{try{await ae(`xcodebuild`,[`build-for-testing`,`-project`,t,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,be(e),`1`,`-destination`,Re(e),`-derivedDataPath`,r,...u,...d,...s,...l,...c],{detached:!0,timeoutMs:o,signal:a.budget?.signal,onSpawn:e=>{U.add(e),e.on(`close`,()=>{U.delete(e)})},onStdoutChunk:e=>{Ue(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{Ue(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(e){if(i(e))throw e;let t=e instanceof n?e:new n(`COMMAND_FAILED`,String(e)),r=bt(t);throw new n(`COMMAND_FAILED`,`xcodebuild build-for-testing failed`,{error:t.message,details:t.details,logPath:a.logPath,hint:r})}})}const W=process.pid;let Gr;function G(){return Gr??={value:S(process.pid)},Gr.value}function K(){return wi(W,G())}function Kr(e){return{schemaVersion:1,deviceId:e.deviceId,ownerToken:K(),ownerPid:W,ownerStartTime:G(),ownerStateDir:ei(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?S(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,jsonPath:e.jsonPath,createdAtMs:Date.now(),deviceClaimProtocol:1}}async function qr(e,t){return await y({acquire:()=>b({lockDirPath:`${J(e)}.lock`,owner:{pid:W,startTime:G(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,ownerGraceMs:5e3,description:`iOS runner lease for ${e}`}),task:t})}function q(e){try{return gi(JSON.parse(w.readFileSync(J(e),`utf8`)),e)}catch{return null}}function Jr(e){if(!e)return{type:`empty`};if(e.ownerToken===K())return{type:`owned`,lease:e};let t=ee({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 Yr(e,t,r){let i=e.id,a=Jr(q(i));if(a.type===`empty`){await t.cleanupRunnerXcodebuildProcesses(i,void 0);return}if(a.type===`busy`){if(Xr(a.lease)){await X(a.lease,`same-state-dir`,t);return}if(Zr(a.lease,e)){await X(a.lease,`device-claim-takeover`,t);return}if(Qr(a.lease,r)){await X(a.lease,`logical-lease-takeover`,t);return}throw new n(`COMMAND_FAILED`,r?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:r,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:ti(a.lease,r)})}await X(a.lease,a.type,t)}function Xr(e){let t=ei();return!t||!e.ownerStateDir?!1:C.resolve(t)===C.resolve(e.ownerStateDir)}function Zr(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&le(t)}function Qr(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:$r(t.deviceKey,e.deviceId)}function $r(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function ei(){return ue()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function ti(e,t){let n=ni(e),r=ri(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 ni(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function ri(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${ii(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function ii(e,t){return`${e}=${ie(t)}`}function ai(e){let t=Jr(q(e));return t.type===`stale`&&(t.staleReason===`owner-process-dead`||t.staleReason===`owner-process-reused`)?t.lease:null}function oi(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function si(e,t){let n=Jr(q(e));n.type===`owned`&&await X(n.lease,`owned`,t)}async function ci(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=mi(e);await Promise.all(n.map(async e=>{await X(e,`owned`,t)}))}function li(e){return q(e)?.ownerToken??null}function ui(e){e&&fi({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function di(e){let t=J(e.deviceId);w.mkdirSync(C.dirname(t),{recursive:!0}),re({destination:t,contents:JSON.stringify(e,null,2)})}function fi(e){let t=q(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{w.unlinkSync(J(e.deviceId))}catch{}}function J(e){return C.join(pi(),`${Ti(e)}.json`)}function pi(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?C.resolve(e):C.join(T.homedir(),`.agent-device`,`apple-runner`,`leases`)}function mi(e){let t,n=pi();try{t=w.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=hi(C.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime)&&r.push(t)}return r}function hi(e){try{let t=JSON.parse(w.readFileSync(e,`utf8`)),n=Y(t.deviceId);return n?gi(t,n):null}catch{return null}}function gi(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=_i(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:vi(n.ownerStartTime),ownerStateDir:vi(n.ownerStateDir)??void 0,runnerPid:yi(n.runnerPid),runnerStartTime:vi(n.runnerStartTime),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function _i(e){let t={ownerToken:Y(e.ownerToken),ownerPid:yi(e.ownerPid),sessionId:Y(e.sessionId),port:yi(e.port),xctestrunPath:Y(e.xctestrunPath),jsonPath:Y(e.jsonPath),createdAtMs:bi(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function Y(e){return typeof e==`string`&&e.length>0?e:null}function vi(e){return typeof e==`string`?e:null}function yi(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function bi(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function X(e,t,n){x({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(xi(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses(e.deviceId,e.ownerToken),await n.cleanupRunnerProcessTree(xi(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),ui(e)}function xi(e){let t=e.runnerPid??void 0;if(!(!t||!p(t))){if(Si(e,t))return t;x({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function Si(e,t){return e.runnerStartTime?S(t)===e.runnerStartTime:Ci(de(t))}function Ci(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function wi(e,t){let n=ze.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function Ti(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}var Ei=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>Di,abortRunnerSessionsAndPrepProcesses:()=>Mi,cleanupOwnedIosRunnerLease:()=>ji,disposeRunnerSession:()=>Ai,isRunnerProcessAlive:()=>Z,runnerLeaseCleanupAdapter:()=>ki,stopRunnerPrepProcesses:()=>Ni});const Di=1e3,Oi=2e3,ki={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Wi,cleanupTempFile:D};async function Ai(e,t={}){let n=!1;if(t.graceful!==!1)n=await Pi(e);else if(c(e.device)){await Ii([e]),await Ri(e,t);return}else await $(e.child.pid,`SIGTERM`);n||(await Fi(e,t.waitTimeoutMs??1e4),Hi(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Ri(e,t)}async function ji(e){await si(e,ki)}async function Mi(e){let t=Array.from(U),n=e.filter(e=>c(e.device)),r=e.filter(e=>!c(e.device));await Q(r,`SIGINT`),await Ui(t,`SIGINT`),await Q(r,`SIGTERM`),await Ui(t,`SIGTERM`),await Q(r,`SIGKILL`),await Ui(t,`SIGKILL`),await Ii(n),await Promise.allSettled(e.map(async e=>{await Ri(e)}))}async function Ni(){let e=Array.from(U);await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{U.delete(e)}}))}async function Pi(e){try{return await Zt(e.device,e.port,xt({command:`shutdown`}),void 0,15e3),!1}catch{return c(e.device)?(await Ii([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function Fi(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!Hi(e.child.pid)}finally{n&&clearTimeout(n)}}async function Ii(e){if(e.length===0)return;await Q(e,`SIGINT`);let t=await Li(e,5e3);await Q(t,`SIGTERM`),await Q(await Li(t,2e3),`SIGKILL`)}async function Li(e,t){let n=await Promise.all(e.map(async e=>await Fi(e,t)));return e.filter((e,t)=>!n[t])}async function Ri(e,t={}){await zi(e,t),D(e.xctestrunPath),D(e.jsonPath),await e.simulatorSetRedirect?.releaseBestEffort()}async function zi(e,t){let n=async()=>{if(!Bi(e))try{await Vi(e.device)}finally{ui(e.lease)}};if(t.leaseLockHeld){await n();return}try{await qr(e.deviceId,n)}catch(t){x({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 Bi(e){let t=li(e.deviceId);return t!==null&&t!==e.lease?.ownerToken}async function Vi(e){e.kind===`simulator`&&await Promise.allSettled(Pe.map(async t=>{try{await je(Ie(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:Oi})}catch(n){x({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:Oi,error:n instanceof Error?n.message:String(n)}})}}))}function Hi(e){return e?Z(e)||we(e):!1}function Z(e){return e?p(e):!1}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Ui(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&U.delete(e)}))}async function $(e,t){if(!e||e<=0)return;ge(e,t),_e([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await g(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Wi(e,t){let n=t?`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${Gi(e)}-${Gi(t)}-`:`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${Gi(e)}-[0-9]`;for(let t of[`TERM`,`KILL`])try{await g(`pkill`,[`-${t}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){x({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:e,signal:t,error:n instanceof Error?n.message:String(n)}})}}function Gi(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}export{ot as A,Ue as B,Yt as C,pt as D,Gt as E,lt as F,ft as I,ct as L,dt as M,$e as N,Ct as O,ut as P,xt as R,gn as S,Wt as T,di as _,Z as a,mr as b,Ni as c,ci as d,Yr as f,qr as g,Si as h,Ai as i,st as j,ht as k,oi as l,K as m,Mi as n,ki as o,ai as p,ji as r,Ei as s,Di as t,Kr as u,Ar as v,Zt as w,On as x,Lr as y,He as z};
|