agent-device 0.11.10 → 0.11.11

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.
@@ -1,47 +1,47 @@
1
- let e,t,r,a;import{__webpack_require__ as n}from"./1~rslib-runtime.js";import i,{createHash as o}from"node:crypto";import s,{existsSync as l,promises as d}from"node:fs";import u,{hostname as c}from"node:os";import p from"node:path";import f from"node:net";import{AsyncLocalStorage as m}from"node:async_hooks";import{URL as h,fileURLToPath as w,pathToFileURL as g}from"node:url";import{XMLParser as y}from"fast-xml-parser";import{spawn as v}from"node:child_process";import I from"node:http";import"node:https";import b from"node:dns/promises";import A from"node:fs/promises";import{TextDecoder as S}from"node:util";import{setTimeout as N}from"node:timers/promises";import{PNG as _}from"pngjs";import{formatSnapshotLine as x,decodePng as D,readProcessCommand as M,isNodeVisibleInEffectiveViewport as k,isMacOsSettingSupported as E,normalizeTenantId as O,isAgentDeviceDaemonProcess as L,runCmdDetached as C,runCmdBackground as P,SETTINGS_INVALID_ARGS_MESSAGE as R,validateAndNormalizeBatchSteps as T,runCmd as $,containsPoint as F,resolveDeployResultTarget as U,isScrollableType as G,displayLabel as V,distanceFromSafeViewportBand as B,asAppError as j,expandUserHomePath as q,withSuccessText as H,AppError as W,extractReadableText as z,resolveEffectiveViewportRect as J,getUnsupportedMacOsSettingMessage as K,resolveDaemonCodeSignature as X,whichCmd as Y,buildSnapshotDisplayLines as Z,buildMobileSnapshotPresentation as Q,resolveViewportRect as ee,runCmdStreaming as et,formatRole as er,normalizeError as ea,resolveSessionIsolationMode as en,resolveUserPath as ei,readVersion as eo,getDiagnosticsMeta as es,runCmdSync as el,withDiagnosticTimer as ed,findNodeByRef as eu,successText as ec,emitDiagnostic as ep,normalizeSnapshotTree as ef,pickLargestRect as em,normalizeRef as eh,DEFAULT_BATCH_MAX_STEPS as ew,isProcessAlive as eg,readProcessStartTime as ey,withDiagnosticsScope as ev,resolveDaemonPaths as eI,flushDiagnosticsToSessionFile as eb,resolveDaemonServerMode as eA,centerOfRect as eS,resolveInstallFromSourceResultTarget as eN,attachRefs as e_,parseSessionSurface as ex}from"./995.js";var eD={};n.r(eD),n.d(eD,{ensureAndroidEmulatorBooted:()=>nd,listAndroidDevices:()=>na,waitForAndroidBoot:()=>nu});var eM={};n.r(eM),n.d(eM,{oI:()=>iC,X$:()=>iE,bV:()=>n3,NX:()=>iY,Mh:()=>aX,fK:()=>iF,w8:()=>i$,getAndroidAppState:()=>nJ,K0:()=>iX,PW:()=>ij,V0:()=>iO,inferAndroidAppName:()=>nz,installAndroidApp:()=>ii,installAndroidInstallablePathAndResolvePackageName:()=>ia,listAndroidApps:()=>nj,pw:()=>iP,vU:()=>nX,gy:()=>n2,Nd:()=>iM,hF:()=>or,$f:()=>iZ,gh:()=>iJ,reinstallAndroidApp:()=>io,resolveAndroidApp:()=>nB,Tz:()=>iL,UB:()=>on,VJ:()=>iV,m1:()=>iB,GZ:()=>i5,kt:()=>ib,sP:()=>ik,wb:()=>iR,ac:()=>iQ});var ek={};n.r(ek),n.d(ek,{prepareAndroidInstallArtifact:()=>nR});var eE={};n.r(eE),n.d(eE,{hp:()=>l1,listAppleDevices:()=>l8});var eO={};n.r(eO),n.d(eO,{TM:()=>sC,ensureBootedSimulator:()=>o_,installIosApp:()=>sR,installIosInstallablePath:()=>s$,listIosApps:()=>sB,L5:()=>sO,IJ:()=>sL,TJ:()=>sG,J7:()=>sF,reinstallIosApp:()=>sT,resolveIosApp:()=>sE,kc:()=>sh,Cm:()=>sV,ap:()=>sU});var eL={};n.r(eL),n.d(eL,{prepareIosInstallArtifact:()=>ok});let eC=eP(process.env.AGENT_DEVICE_RETRY_LOGS);function eP(e){return["1","true","yes","on"].includes((e??"").toLowerCase())}let eR=2e4,eT=12e4,e$=1e4;class eF{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new eF(t,e)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return 0>=this.remainingMs(e)}}async function eU(e,t={},r={}){let a,n={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=n.maxAttempts;t+=1){if(r.signal?.aborted)throw new W("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(r.deadline?.isExpired()&&t>1)break;try{let a=await e({attempt:t,maxAttempts:n.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),eV({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),a}catch(d){a=d;let e=r.classifyReason?.(d),i={phase:r.phase,event:"attempt_failed",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};if(r.onEvent?.(i),eV(i),t>=n.maxAttempts||n.shouldRetry&&!n.shouldRetry(d,t))break;let o=function(e,t,r,a){let n=Math.min(t,e*2**(a-1));return Math.max(0,n+n*r*(2*Math.random()-1))}(n.baseDelayMs,n.maxDelayMs,n.jitter,t),s=r.deadline?Math.min(o,r.deadline.remainingMs()):o;if(s<=0)break;let l={phase:r.phase,event:"retry_scheduled",attempt:t,maxAttempts:n.maxAttempts,delayMs:s,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};r.onEvent?.(l),eV(l),await function(e,t){return new Promise(r=>{if(t?.aborted)return void r();let a=!1,n=()=>{a||(a=!0,t&&t.removeEventListener("abort",o),r())},i=setTimeout(n,e);function o(){clearTimeout(i),n()}t&&t.addEventListener("abort",o,{once:!0})})}(s,r.signal)}}let i={phase:r.phase,event:"exhausted",attempt:n.maxAttempts,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(a)};if(r.onEvent?.(i),eV(i),a)throw a;throw new W("COMMAND_FAILED","retry failed")}async function eG(e,t={}){return eU(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function eV(e){ep({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),eC&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
2
- `)}let eB=new Set,ej=new Map,eq="request_canceled",eH="request canceled";function eW(e,t){if("string"==typeof e&&e.length>0)return e;let r=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",a=Math.random().toString(36).slice(2,10);return`req:${r}:${process.pid}:${Date.now()}:${a}`}function ez(e){if(!e)return;!function(e){if(e.size<=5e4)return;let t=0;for(let r of e.keys()){if(t>=1e4)break;e.delete(r),t++}}(ej);let t=new AbortController;ej.set(e,t),eB.has(e)&&t.abort()}function eJ(e){e&&(!function(e){if(e.size<=5e4)return;let t=0;for(let r of e){if(t>=1e4)break;e.delete(r),t++}}(eB),eB.add(e),ej.get(e)?.abort())}function eK(e){e&&(eB.delete(e),ej.delete(e))}function eX(e){return!!e&&eB.has(e)}function eY(e){if(e)return ej.get(e)?.signal}function eZ(){return new W("COMMAND_FAILED",eH,{reason:eq})}function eQ(e){return e instanceof W&&"COMMAND_FAILED"===e.code&&(e.details?.reason===eq||e.message===eH)}function e0(e,t,r){if(!e)return t;let a=Number(e);return Number.isFinite(a)?Math.max(r,Math.floor(a)):t}function e1(e){let t=e.error?j(e.error):null,r=e.context?.platform,a=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===r?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let n=t?.details??{},i="string"==typeof n.message?n.message:void 0,o="string"==typeof n.stdout?n.stdout:void 0,s="string"==typeof n.stderr?n.stderr:void 0,l=n.boot&&"object"==typeof n.boot?n.boot:null,d=n.bootstatus&&"object"==typeof n.bootstatus?n.bootstatus:null,u=[e.message,t?.message,e.stdout,e.stderr,i,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof d?.stdout?d.stdout:void 0,"string"==typeof d?.stderr?d.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===r&&(u.includes("runner did not accept connection")||"connect"===a&&(u.includes("timed out")||u.includes("timeout")||u.includes("econnrefused")||u.includes("connection refused")||u.includes("fetch failed")||u.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===r&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===r&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":u.includes("resource temporarily unavailable")||u.includes("killed: 9")||u.includes("cannot allocate memory")||u.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===r&&(u.includes("device not found")||u.includes("no devices")||u.includes("device offline")||u.includes("offline")||u.includes("unauthorized")||u.includes("not authorized")||u.includes("unable to locate device")||u.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||u.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function e2(e){switch(e){case"IOS_BOOT_TIMEOUT":return"Retry simulator boot and inspect simctl bootstatus logs; in CI consider increasing AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS.";case"IOS_RUNNER_CONNECT_TIMEOUT":return"Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.";case"ANDROID_BOOT_TIMEOUT":return"Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.";case"ADB_TRANSPORT_UNAVAILABLE":return"Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.";case"CI_RESOURCE_STARVATION_SUSPECTED":return"CI machine may be resource constrained; reduce parallel jobs or use a larger runner.";case"IOS_TOOL_MISSING":return"Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.";case"BOOT_COMMAND_FAILED":return"Inspect command stderr/stdout for the failing boot phase and retry after environment validation.";default:return"Retry once and inspect verbose logs for the failing phase."}}let e3=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],e4=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function e5(e){return e?.trim()||void 0}function e8(e,t){for(let r of e){let e=e5(t[r]);if(e)return e}}function e6(e,t=process.env){return e5(e)??e8(e3,t)}function e9(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function e7(e,t=process.env){let r=e5(e)??e8(e4,t);if(r)return e9(r)}function te(e,t={}){let r=e6(t.simulatorSetPath);return r?["simctl","--set",r,...e]:["simctl",...e]}function tt(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:te(t,{simulatorSetPath:e.simulatorSetPath})}function tr(e){return!(e instanceof W)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function ta(e){let{port:t,endpoints:r,logPath:a,lastError:n}=e,i="Runner did not accept connection";return new W("COMMAND_FAILED",i,{port:t,endpoints:r,logPath:a,lastError:n?String(n):void 0,reason:e1({error:n,message:i,context:{platform:"ios",phase:"connect"}}),hint:e2("IOS_RUNNER_CONNECT_TIMEOUT")})}async function tn(e){var t,r;let a,{session:n,port:i,logPath:o}=e,s=await n.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=e1({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new W("COMMAND_FAILED",l,{port:i,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,r=s.stderr,(a=`${l}
1
+ let e,t,r,a;import{__webpack_require__ as n}from"./1~rslib-runtime.js";import i,{createHash as o}from"node:crypto";import s,{existsSync as l,promises as d}from"node:fs";import u,{hostname as c}from"node:os";import p from"node:path";import f from"node:net";import{AsyncLocalStorage as m}from"node:async_hooks";import{URL as h,fileURLToPath as w,pathToFileURL as g}from"node:url";import{XMLParser as y}from"fast-xml-parser";import{spawn as v}from"node:child_process";import I from"node:http";import"node:https";import b from"node:dns/promises";import A from"node:fs/promises";import{TextDecoder as S}from"node:util";import{setTimeout as N}from"node:timers/promises";import{PNG as _}from"pngjs";import{whichCmd as x,runCmdDetached as D,runCmdStreaming as M,asAppError as k,normalizeError as E,AppError as O,withDiagnosticsScope as L,runCmdBackground as C,getDiagnosticsMeta as P,flushDiagnosticsToSessionFile as R,withDiagnosticTimer as T,runCmdSync as $,runCmd as F,emitDiagnostic as U}from"./818.js";import{resolveDaemonCodeSignature as G,readProcessCommand as V,isNodeVisibleInEffectiveViewport as B,isMacOsSettingSupported as j,normalizeTenantId as q,isAgentDeviceDaemonProcess as H,validateAndNormalizeBatchSteps as W,SETTINGS_INVALID_ARGS_MESSAGE as z,containsPoint as J,resolveDeployResultTarget as K,isScrollableType as X,displayLabel as Y,distanceFromSafeViewportBand as Z,expandUserHomePath as Q,withSuccessText as ee,extractReadableText as et,resolveEffectiveViewportRect as er,getUnsupportedMacOsSettingMessage as ea,buildSnapshotDisplayLines as en,buildMobileSnapshotPresentation as ei,resolveViewportRect as eo,formatRole as es,resolveSessionIsolationMode as el,resolveUserPath as ed,readVersion as eu,findNodeByRef as ec,successText as ep,pickLargestRect as ef,normalizeSnapshotTree as em,normalizeRef as eh,DEFAULT_BATCH_MAX_STEPS as ew,isProcessAlive as eg,readProcessStartTime as ey,resolveDaemonPaths as ev,parseSessionSurface as eI,resolveDaemonServerMode as eb,centerOfRect as eA,resolveInstallFromSourceResultTarget as eS,decodePng as eN,attachRefs as e_,formatSnapshotLine as ex}from"./995.js";var eD={};n.r(eD),n.d(eD,{ensureAndroidEmulatorBooted:()=>nd,listAndroidDevices:()=>na,waitForAndroidBoot:()=>nu});var eM={};n.r(eM),n.d(eM,{oI:()=>iC,X$:()=>iE,bV:()=>n3,NX:()=>iY,Mh:()=>aX,fK:()=>iF,w8:()=>i$,getAndroidAppState:()=>nJ,K0:()=>iX,PW:()=>ij,V0:()=>iO,inferAndroidAppName:()=>nz,installAndroidApp:()=>ii,installAndroidInstallablePathAndResolvePackageName:()=>ia,listAndroidApps:()=>nj,pw:()=>iP,vU:()=>nX,gy:()=>n2,Nd:()=>iM,hF:()=>or,$f:()=>iZ,gh:()=>iJ,reinstallAndroidApp:()=>io,resolveAndroidApp:()=>nB,Tz:()=>iL,UB:()=>on,VJ:()=>iV,m1:()=>iB,GZ:()=>i5,kt:()=>ib,sP:()=>ik,wb:()=>iR,ac:()=>iQ});var ek={};n.r(ek),n.d(ek,{prepareAndroidInstallArtifact:()=>nR});var eE={};n.r(eE),n.d(eE,{hp:()=>l1,listAppleDevices:()=>l8});var eO={};n.r(eO),n.d(eO,{TM:()=>sC,ensureBootedSimulator:()=>o_,installIosApp:()=>sR,installIosInstallablePath:()=>s$,listIosApps:()=>sB,L5:()=>sO,IJ:()=>sL,TJ:()=>sG,J7:()=>sF,reinstallIosApp:()=>sT,resolveIosApp:()=>sE,kc:()=>sh,Cm:()=>sV,ap:()=>sU});var eL={};n.r(eL),n.d(eL,{prepareIosInstallArtifact:()=>ok});let eC=eP(process.env.AGENT_DEVICE_RETRY_LOGS);function eP(e){return["1","true","yes","on"].includes((e??"").toLowerCase())}let eR=2e4,eT=12e4,e$=1e4;class eF{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new eF(t,e)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return 0>=this.remainingMs(e)}}async function eU(e,t={},r={}){let a,n={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=n.maxAttempts;t+=1){if(r.signal?.aborted)throw new O("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(r.deadline?.isExpired()&&t>1)break;try{let a=await e({attempt:t,maxAttempts:n.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),eV({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),a}catch(d){a=d;let e=r.classifyReason?.(d),i={phase:r.phase,event:"attempt_failed",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};if(r.onEvent?.(i),eV(i),t>=n.maxAttempts||n.shouldRetry&&!n.shouldRetry(d,t))break;let o=function(e,t,r,a){let n=Math.min(t,e*2**(a-1));return Math.max(0,n+n*r*(2*Math.random()-1))}(n.baseDelayMs,n.maxDelayMs,n.jitter,t),s=r.deadline?Math.min(o,r.deadline.remainingMs()):o;if(s<=0)break;let l={phase:r.phase,event:"retry_scheduled",attempt:t,maxAttempts:n.maxAttempts,delayMs:s,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};r.onEvent?.(l),eV(l),await function(e,t){return new Promise(r=>{if(t?.aborted)return void r();let a=!1,n=()=>{a||(a=!0,t&&t.removeEventListener("abort",o),r())},i=setTimeout(n,e);function o(){clearTimeout(i),n()}t&&t.addEventListener("abort",o,{once:!0})})}(s,r.signal)}}let i={phase:r.phase,event:"exhausted",attempt:n.maxAttempts,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(a)};if(r.onEvent?.(i),eV(i),a)throw a;throw new O("COMMAND_FAILED","retry failed")}async function eG(e,t={}){return eU(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function eV(e){U({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),eC&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
2
+ `)}let eB=new Set,ej=new Map,eq="request_canceled",eH="request canceled";function eW(e,t){if("string"==typeof e&&e.length>0)return e;let r=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",a=Math.random().toString(36).slice(2,10);return`req:${r}:${process.pid}:${Date.now()}:${a}`}function ez(e){if(!e)return;!function(e){if(e.size<=5e4)return;let t=0;for(let r of e.keys()){if(t>=1e4)break;e.delete(r),t++}}(ej);let t=new AbortController;ej.set(e,t),eB.has(e)&&t.abort()}function eJ(e){e&&(!function(e){if(e.size<=5e4)return;let t=0;for(let r of e){if(t>=1e4)break;e.delete(r),t++}}(eB),eB.add(e),ej.get(e)?.abort())}function eK(e){e&&(eB.delete(e),ej.delete(e))}function eX(e){return!!e&&eB.has(e)}function eY(e){if(e)return ej.get(e)?.signal}function eZ(){return new O("COMMAND_FAILED",eH,{reason:eq})}function eQ(e){return e instanceof O&&"COMMAND_FAILED"===e.code&&(e.details?.reason===eq||e.message===eH)}function e0(e,t,r){if(!e)return t;let a=Number(e);return Number.isFinite(a)?Math.max(r,Math.floor(a)):t}function e1(e){let t=e.error?k(e.error):null,r=e.context?.platform,a=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===r?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let n=t?.details??{},i="string"==typeof n.message?n.message:void 0,o="string"==typeof n.stdout?n.stdout:void 0,s="string"==typeof n.stderr?n.stderr:void 0,l=n.boot&&"object"==typeof n.boot?n.boot:null,d=n.bootstatus&&"object"==typeof n.bootstatus?n.bootstatus:null,u=[e.message,t?.message,e.stdout,e.stderr,i,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof d?.stdout?d.stdout:void 0,"string"==typeof d?.stderr?d.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===r&&(u.includes("runner did not accept connection")||"connect"===a&&(u.includes("timed out")||u.includes("timeout")||u.includes("econnrefused")||u.includes("connection refused")||u.includes("fetch failed")||u.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===r&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===r&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":u.includes("resource temporarily unavailable")||u.includes("killed: 9")||u.includes("cannot allocate memory")||u.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===r&&(u.includes("device not found")||u.includes("no devices")||u.includes("device offline")||u.includes("offline")||u.includes("unauthorized")||u.includes("not authorized")||u.includes("unable to locate device")||u.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||u.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function e2(e){switch(e){case"IOS_BOOT_TIMEOUT":return"Retry simulator boot and inspect simctl bootstatus logs; in CI consider increasing AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS.";case"IOS_RUNNER_CONNECT_TIMEOUT":return"Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.";case"ANDROID_BOOT_TIMEOUT":return"Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.";case"ADB_TRANSPORT_UNAVAILABLE":return"Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.";case"CI_RESOURCE_STARVATION_SUSPECTED":return"CI machine may be resource constrained; reduce parallel jobs or use a larger runner.";case"IOS_TOOL_MISSING":return"Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.";case"BOOT_COMMAND_FAILED":return"Inspect command stderr/stdout for the failing boot phase and retry after environment validation.";default:return"Retry once and inspect verbose logs for the failing phase."}}let e3=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],e4=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function e5(e){return e?.trim()||void 0}function e8(e,t){for(let r of e){let e=e5(t[r]);if(e)return e}}function e6(e,t=process.env){return e5(e)??e8(e3,t)}function e9(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function e7(e,t=process.env){let r=e5(e)??e8(e4,t);if(r)return e9(r)}function te(e,t={}){let r=e6(t.simulatorSetPath);return r?["simctl","--set",r,...e]:["simctl",...e]}function tt(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:te(t,{simulatorSetPath:e.simulatorSetPath})}function tr(e){return!(e instanceof O)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function ta(e){let{port:t,endpoints:r,logPath:a,lastError:n}=e,i="Runner did not accept connection";return new O("COMMAND_FAILED",i,{port:t,endpoints:r,logPath:a,lastError:n?String(n):void 0,reason:e1({error:n,message:i,context:{platform:"ios",phase:"connect"}}),hint:e2("IOS_RUNNER_CONNECT_TIMEOUT")})}async function tn(e){var t,r;let a,{session:n,port:i,logPath:o}=e,s=await n.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=e1({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new O("COMMAND_FAILED",l,{port:i,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,r=s.stderr,(a=`${l}
3
3
  ${t}
4
- ${r}`.toLowerCase()).includes("device is busy")&&a.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":e2("IOS_RUNNER_CONNECT_TIMEOUT"))})}function ti(e){if(eX(e))throw eZ()}let to=e0(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),ts=e0(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),tl=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),td=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),tu=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),tc=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),tp=e0(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),tf=e0(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function tm(e,t,r,a,n=to,i,o){let s=eF.fromTimeoutMs(n),l=await th(e,t,s.remainingMs()),d=null,u=Math.max(1,Math.ceil(n/tl));try{return await eU(async({deadline:s})=>{if(s?.isExpired())throw new W("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:n});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await tn({session:i,port:t,logPath:a});for(let a of("device"===e.kind&&(l=await th(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??n;if(e<=0)throw new W("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:n});return await tw(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},Math.min(tc,e),o)}catch(e){if(o?.aborted||eQ(e))throw eZ();d=e}throw new W("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:d?String(d):void 0})},{maxAttempts:u,baseDelayMs:td,maxDelayMs:tu,jitter:.2,shouldRetry:tr},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||eQ(e))throw eZ();d||(d=e)}if(o?.aborted)throw eZ();if("simulator"===e.kind){let n=s.remainingMs();if(n<=0)throw ta({port:t,endpoints:l,logPath:a,lastError:d});let i=await ty(e,t,r,n);return new Response(i.body,{status:i.status})}throw ta({port:t,endpoints:l,logPath:a,lastError:d})}async function th(e,t,r){let a=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return a;let n=await tg(e.id,r);return n&&a.unshift(`http://[${n}]:${t}/command`),a}async function tw(e,t,r,a){let n,i=new AbortController,o=setTimeout(()=>i.abort(),r);a&&(a.aborted?(clearTimeout(o),i.abort()):(n=()=>i.abort(),a.addEventListener("abort",n,{once:!0})));try{return await fetch(e,{...t,signal:i.signal})}finally{clearTimeout(o),n&&a&&a.removeEventListener("abort",n)}}async function tg(e,t){if("number"==typeof t&&t<=0)return null;let r="number"==typeof t?Math.max(1,Math.min(tp,t)):tp,a=p.join(u.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(r/1e3)),n=await $("xcrun",["devicectl","device","info","details","--device",e,"--json-output",a,"--timeout",String(t)],{allowFailure:!0,timeoutMs:r});if(0!==n.exitCode||!s.existsSync(a))return null;let i=JSON.parse(s.readFileSync(a,"utf8"));if(i.info?.outcome&&"success"!==i.info.outcome)return null;let o=(i.result?.connectionProperties?.tunnelIPAddress??i.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return o&&o.length>0?o:null}catch{return null}finally{tb(a)}}async function ty(e,t,r,a){let n=JSON.stringify(r),i=tt(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",n,`http://127.0.0.1:${t}/command`]),o=await $("xcrun",i,{allowFailure:!0,timeoutMs:a}),s=o.stdout;if(0!==o.exitCode){let e=e1({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new W("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:e2(e)})}return{status:200,body:s}}async function tv(){return await new Promise((e,t)=>{let r=f.createServer();r.listen(0,"127.0.0.1",()=>{let a=r.address();if("object"==typeof a&&a?.port){let t=a.port;r.close(()=>e(t))}else r.close(()=>t(new W("COMMAND_FAILED","Failed to allocate port")))}),r.on("error",t)})}function tI(e,t,r,a){t&&s.appendFile(t,e,()=>{}),r&&s.appendFile(r,e,()=>{}),a&&process.stderr.write(e)}function tb(e){try{s.existsSync(e)&&s.unlinkSync(e)}catch{}}let tA=new m;async function tS(e,t,r){let a=tA.getStore()??[];if(a.some(r=>r.locks===e&&r.key===t))return await r();let n=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>tA.run([...a,{locks:e,key:t}],r));return e.set(t,n),n.finally(()=>{e.get(t)===n&&e.delete(t)})}function tN(e){return"apple"===e||"ios"===e||"macos"===e}function t_(e,t){return!t||("apple"===t?tN(e):e===t)}function tx(e){let{simulatorSetPath:t,platform:r,target:a}=e;if(t&&"macos"!==r&&"desktop"!==a)return t}async function tD(e,t,r={}){let a=e,n=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(a=a.filter(e=>t_(e.platform,t.platform))),t.target&&(a=a.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=a.find(e=>e.id===t.udid&&tN(e.platform));if(!e)throw new W("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=a.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new W("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=n(t.deviceName),r=a.find(t=>n(t.name)===e);if(!r)throw new W("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return r}if(1===a.length)return a[0];if(0===a.length){var i;let e=r.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new W("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
5
- xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new W("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=a.filter(e=>"device"!==e.kind);o.length>0&&(a=o);let s=a.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??a[0]}let tM=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function tk(e,t,r){if("macos"!==e.platform)return;if(0===t.length)throw new W("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:r});let a=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of a)if(!s.existsSync(e))throw new W("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:r});for(let e of a)if(0!==el("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await $("codesign",["--remove-signature",e],{allowFailure:!0});try{await $("codesign",["--force","--sign","-",e])}catch(a){let t=a instanceof W?a:new W("COMMAND_FAILED",String(a));throw new W("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:r,error:t.message,details:t.details})}}}let tE=null;function tO(e){return function e(t){if(!Array.isArray(t))return[];let r=[];for(let a of t)if(!(!a||"object"!=typeof a||Array.isArray(a)))for(let[t,n]of Object.entries(a))":@"!==t&&"#text"!==t&&r.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[r,a]of Object.entries(e))"string"==typeof a&&(t[r]=a);return t}(a[":@"]),text:tC(n)??tC(a["#text"]),children:e(n)});return r}((tE??=new y({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function tL(e,t){for(let r of e){if("dict"===r.name)for(let e=0;e<r.children.length-1;e+=1){let a=r.children[e],n=r.children[e+1];a?.name==="key"&&a.text&&n&&t(a.text,n)}tL(r.children,t)}}function tC(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let tP="XCTestDevices",tR=".agent-device-backup",tT=".agent-device-xctestdevices-backup-",t$=p.join(u.homedir(),".agent-device","ios-runner"),tF=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),tU=new Map,tG=new Set;function tV(e){return e?.trim()??""}function tB(e=process.env){return tV(e.AGENT_DEVICE_IOS_BUNDLE_ID)||tV(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function tj(e=process.env){let t=tV(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${tB(e)}.uitests`}let tq=function(e=process.env){let t=tB(e),r=tj(e);return Array.from(new Set([tV(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${r}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function tH(e=u.homedir()){return p.join(e,"Library","Developer","XCTestDevices")}async function tW(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let r=e6(e.simulatorSetPath);if(!r)return null;let a=p.resolve(r),n=p.resolve(t.xctestDeviceSetPath??tH()),i=p.resolve(t.backupPath??function(e=tH()){return`${e}${tR}`}(n)),o=p.resolve(t.lockDirPath??function(e=u.homedir()){return p.join(e,".agent-device","xctest-device-set.lock")}()),l=t.ownerStartTime??ey(process.pid),d=await tK({lockDirPath:o,owner:{pid:t.ownerPid??process.pid,startTime:l,acquiredAtMs:t.nowMs??Date.now()}});try{if(tz({xctestDeviceSetPath:n,backupPath:i}),function(e,t){if(p.resolve(e)===p.resolve(t))return!0;try{return s.realpathSync.native(e)===s.realpathSync.native(t)}catch{return!1}}(a,n))return await d(),null;s.mkdirSync(a,{recursive:!0}),s.existsSync(n)&&s.renameSync(n,i),function(e){let{requestedSetPath:t,xctestDeviceSetPath:r}=e,a=p.dirname(r),n=p.join(a,`${tP}.agent-device-link-${process.pid}-${Date.now()}`);s.mkdirSync(a,{recursive:!0});try{s.symlinkSync(t,n,"dir"),s.renameSync(n,r)}catch(e){throw s.existsSync(n)&&tJ(n),e}}({requestedSetPath:a,xctestDeviceSetPath:n})}catch(e){throw tz({xctestDeviceSetPath:n,backupPath:i}),await d(),new W("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:a,xctestDeviceSetPath:n,backupPath:i,error:String(e)})}let c=!1;return{release:async()=>{if(!c){c=!0;try{tz({xctestDeviceSetPath:n,backupPath:i})}finally{await d()}}}}}function tz(e){let{xctestDeviceSetPath:t,backupPath:r}=e,a=[r,...function(e){let t=p.dirname(e),r=p.basename(e).replace(tR,""),a=r===tP?tT:`${r}${tT}`;try{return s.readdirSync(t).filter(e=>e.startsWith(a)).sort().map(e=>p.join(t,e))}catch{return[]}}(r)],n=a.find(e=>s.existsSync(e)),i=s.existsSync(t)&&s.lstatSync(t).isSymbolicLink();if(n){if(i&&tJ(t),s.existsSync(t))if(!i)return void ep({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:n}});else n!==r?s.rmSync(n,{recursive:!0,force:!0}):s.rmSync(r,{recursive:!0,force:!0});else s.mkdirSync(p.dirname(t),{recursive:!0}),s.renameSync(n,t);for(let e of a)e!==n&&s.existsSync(e)&&s.rmSync(e,{recursive:!0,force:!0});return}i&&(ep({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),tJ(t))}function tJ(e){!s.existsSync(e)||s.lstatSync(e).isSymbolicLink()&&s.unlinkSync(e)}async function tK(e){let{lockDirPath:t,owner:r}=e,a=p.join(t,"owner.json"),n=Date.now()+3e4;for(s.mkdirSync(p.dirname(t),{recursive:!0});Date.now()<n;)try{s.mkdirSync(t),function(e,t){let r=`${e}.${process.pid}.${Date.now()}.tmp`;s.writeFileSync(r,JSON.stringify(t),"utf8"),s.renameSync(r,e)}(a,r);let e=!1;return async()=>{e||(e=!0,s.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let r=null;try{r=s.statSync(e)}catch{return!0}let a=function(e){try{return JSON.parse(s.readFileSync(e,"utf8"))}catch{return null}}(t);if(a){var n;return!(Number.isInteger((n=a).pid)&&!(n.pid<=0)&&eg(n.pid)&&(!n.startTime||ey(n.pid)===n.startTime))&&(s.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-r.mtimeMs<5e3)&&(s.rmSync(e,{recursive:!0,force:!0}),!0)}(t,a))continue;await new Promise(e=>setTimeout(e,100))}throw new W("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function tX(e,t){var r;let a,n=(r=e,(a=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?p.resolve(a):"macos"===r.platform?p.join(t$,"derived","macos"):"simulator"===r.kind?p.join(t$,"derived"):p.join(t$,"derived",r.kind)),i=function(){let e=p.dirname(w(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=p.join(t,"package.json");if(s.existsSync(e))return t;t=p.dirname(t)}return e}();return await tS(tU,n,async()=>{eP(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(t9("clean","forced_clean",{derived:n}),t6(n),tY(n));let r=function(e){let t=e.findXctestrun(e.derived);if(!t)return{reason:"missing_xctestrun",xctestrunPath:null};let r=e.resolveExistingXctestrunProductPaths(t);return r?e.xctestrunReferencesProjectRoot(t,e.projectRoot)?{reason:"reuse_ready",xctestrunPath:t,productPaths:r}:{reason:"project_root_mismatch",xctestrunPath:t,productPaths:r}:{reason:"missing_products",xctestrunPath:t,productPaths:[]}}({derived:n,projectRoot:i,findXctestrun:t=>tQ(t,e),xctestrunReferencesProjectRoot:t1,resolveExistingXctestrunProductPaths:t7});if("reuse_ready"!==r.reason&&t9("rebuild",r.reason,{derived:n,xctestrunPath:r.xctestrunPath}),"reuse_ready"===r.reason)try{return await tk(e,r.productPaths,r.xctestrunPath),t9("reuse","reuse_ready",{derived:n,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof W))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&tM.has(t)}(e))throw e;t9("rebuild","repair_failed",{derived:n,xctestrunPath:r.xctestrunPath})}r.xctestrunPath&&(t6(n),tY(n));let a=p.join(i,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!s.existsSync(a))throw new W("COMMAND_FAILED","iOS runner project not found",{projectPath:a});await t3(e,a,n,t);let o=tQ(n,e);if(!o)throw new W("COMMAND_FAILED","Failed to locate .xctestrun after build");let l=t7(o);if(!l)throw new W("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:o});return await tk(e,l,o),t9("build","built_new",{derived:n,xctestrunPath:o}),o})}function tY(e){try{if(!s.existsSync(e))return;if("derived"!==p.basename(e))return void s.rmSync(e,{recursive:!0,force:!0});for(let r of s.readdirSync(e,{withFileTypes:!0})){var t;t=r.name,tZ.has(t)&&s.rmSync(p.join(e,r.name),{recursive:!0,force:!0})}}catch{}}let tZ=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function tQ(e,t){if(!s.existsSync(e))return null;let r=[],a=[e];for(;a.length>0;){let e=a.pop();for(let t of s.readdirSync(e,{withFileTypes:!0})){let n=p.join(e,t.name);if(t.isDirectory()){a.push(n);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=s.statSync(n);r.push({path:n,mtimeMs:e.mtimeMs})}catch{}}}return 0===r.length?null:(r.sort((e,r)=>{if(t){let a=t0(r.path,t)-t0(e.path,t);if(0!==a)return a}return r.mtimeMs-e.mtimeMs||e.path.localeCompare(r.path)}),r[0]?.path??null)}function t0(e,t){var r;let a=0,n=e.toLowerCase();p.basename(n).startsWith("agentdevicerunner.env.")&&(a-=1e3),n.includes(`${p.sep}macos${p.sep}`)&&(a-=5e3);let i="macos"===(r=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===r.target?"simulator"===r.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===r.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>n.includes(e))?a+=2e3:a-=500),i.disallowed.some(e=>n.includes(e))&&(a-=2500),a}function t1(e,t){try{let r=s.readFileSync(e,"utf8"),a=new Set([t]);try{a.add(s.realpathSync(t))}catch{}for(let e of a)if(r.includes(e))return!0;return!1}catch{return!1}}async function t2(e,t,r){let a,n=p.dirname(e),i=r.replace(/[^a-zA-Z0-9._-]/g,"_"),o=p.join(n,`AgentDeviceRunner.env.${i}.json`),l=p.join(n,`AgentDeviceRunner.env.${i}.xctestrun`),d=await $("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==d.exitCode||!d.stdout.trim())throw new W("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:d.stderr});try{a=JSON.parse(d.stdout)}catch(t){throw new W("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let u=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},c=a.TestConfigurations;if(Array.isArray(c))for(let e of c){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&u(e)}for(let[e,t]of Object.entries(a))t&&"object"==typeof t&&t.TestBundlePath&&(u(t),a[e]=t);s.writeFileSync(o,JSON.stringify(a,null,2));let f=await $("plutil",["-convert","xml1","-o",l,o],{allowFailure:!0});if(0!==f.exitCode)throw new W("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:l,stderr:f.stderr});return{xctestrunPath:l,jsonPath:o}}async function t3(e,t,r,a){let n=function(e=process.env){let t=tB(e),r=tj(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${r}`]}(process.env),i=function(e=process.env,t=!1,r="ios"){if("macos"===r)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let a=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",n=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return a&&o.push(`DEVELOPMENT_TEAM=${a}`),n&&o.push(`CODE_SIGN_IDENTITY=${n}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await tW(e);try{var l;let s;await et("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",t8(e),"1","-destination",(l=e,s=t4(l),"macOS"===s?`platform=macOS,arch=${t5()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",r,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...n,...o,...i],{detached:!0,onSpawn:e=>{tG.add(e),e.on("close",()=>{tG.delete(e)})},onStdoutChunk:e=>{tI(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{tI(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(i){let e,t,r=i instanceof W?i:new W("COMMAND_FAILED",String(i)),n=(e=r.details?JSON.stringify(r.details):"",(t=`${r.message}
6
- ${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new W("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:r.message,details:r.details,logPath:a.logPath,hint:n})}finally{await s?.release()}}function t4(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new W("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"macos"===e.platform?"macOS":"macos"===(t=e.target)||"desktop"===t?"macOS":"tv"===t?"tvOS":"iOS"}function t5(){return"arm64"===process.arch?"arm64":"x86_64"}function t8(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function t6(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return eP(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new W("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}function t9(e,t,r){ep({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...r}})}function t7(e){let t=function(e){let t=function(e){try{let t=el("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode||!t.stdout.trim())return null;return JSON.parse(t.stdout)}catch{return null}}(e);if(t){var r,a,n=t;let e=new Set,i=t=>{if(t&&"object"==typeof t)for(let r of function(e){let t=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),r=new Set;for(let[a,n]of Object.entries(e))if(t.has(a)){if("string"==typeof n){r.add(n);continue}if(Array.isArray(n))for(let e of n)"string"==typeof e&&r.add(e)}return Array.from(r)}(t))e.add(r)};i(n);let o=n.TestConfigurations;if(Array.isArray(o))for(let e of o){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)i(e)}for(let e of Object.values(n))e&&"object"==typeof e&&"TestBundlePath"in e&&i(e);return Array.from(e)}if("darwin"===process.platform)return null;try{let t;return r=s.readFileSync(e,"utf8"),a=tO(r),t=new Set,tL(a,(e,r)=>{if(tF.has(e)){if("string"===r.name&&r.text)return void t.add(r.text);if("array"===r.name)for(let e of r.children)"string"===e.name&&e.text&&t.add(e.text)}}),Array.from(t)}catch{return null}}(e);if(!t||0===t.length)return null;let r=p.dirname(e),a=new Set,n=new Set,i=[];for(let e of t){if(e.startsWith("__TESTROOT__/")){let t=e.slice(13),i=p.join(r,t);if(!s.existsSync(i))return null;a.add(i);let o=function(e){let t=/\.app(?:\/|$)/.exec(e);return t&&void 0!==t.index?e.slice(0,t.index+4):null}(t);o&&n.add(p.join(r,o));continue}e.startsWith("__TESTHOST__/")&&i.push(e.slice(13))}for(let e of i){let t=Array.from(n).find(t=>s.existsSync(p.join(t,e)));if(!t)return null;a.add(p.join(t,e))}return Array.from(a)}let re=new Map,rt=new Map;async function rr(e,t){return await tS(rt,e.id,async()=>{var r;let a,n,i=re.get(e.id);if(i){if(function(e){return!!e&&eg(e)}(i.child.pid))return i;await ri(e.id,i)}await ("simulator"!==(r=e).kind?Promise.resolve():ru(r)),await ra(e);let o=await tX(e,t),s=await tv(),{xctestrunPath:l,jsonPath:d}=await t2(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),u=await tW(e);try{let t;({child:a,wait:n}=P("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",t8(e),"1","-destination-timeout",String(tf),"-xctestrun",l,"-destination",(t=t4(e),"macOS"===t?`platform=macOS,arch=${t5()}`:"simulator"===e.kind?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0}))}catch(e){throw await u?.release(),e}a.stdout?.on("data",e=>{tI(e,t.logPath,t.traceLogPath,t.verbose)}),a.stderr?.on("data",e=>{tI(e,t.logPath,t.traceLogPath,t.verbose)});let c={sessionId:`${e.id}:${s}:${Date.now()}`,device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:d,testPromise:n,child:a,ready:!1,simulatorSetRedirect:u??void 0};return re.set(e.id,c),c})}async function ra(e){if("simulator"===e.kind)for(let t of tq){let r=await $("xcrun",tt(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==r.exitCode){let e=`${r.stdout}
7
- ${r.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}async function rn(e){await tS(rt,e.deviceId,async()=>{await ri(e.deviceId,e)})}async function ri(e,t){let r=t??re.get(e);if(r){try{await tm(r.device,r.port,{command:"shutdown"},void 0,15e3)}catch{await rd(r.child.pid,"SIGTERM")}try{await Promise.race([r.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}await rd(r.child.pid,"SIGKILL"),tb(r.xctestrunPath),tb(r.jsonPath),await r.simulatorSetRedirect?.release(),re.get(e)===r&&re.delete(e)}}async function ro(e){await tS(rt,e,async()=>{await ri(e)})}async function rs(){let e=Array.from(re.values()),t=Array.from(tG);await Promise.allSettled(e.map(async e=>{await rd(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await rd(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await rd(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await rd(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await rd(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await rd(e.pid,"SIGKILL"),tG.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function rl(){await rs();let e=Array.from(re.keys());await Promise.allSettled(e.map(async e=>{await ro(e)}));let t=Array.from(tG);await Promise.allSettled(t.map(async e=>{try{await rd(e.pid,"SIGTERM"),await rd(e.pid,"SIGKILL")}finally{tG.delete(e)}}))}async function rd(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}try{process.kill(e,t)}catch{}let r="SIGINT"===t?"INT":"SIGTERM"===t?"TERM":"KILL";try{await $("pkill",[`-${r}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function ru(e){await $("xcrun",tt(e,["bootstatus",e.id,"-b"]),{timeoutMs:to})}async function rc(e,t,r,a,n,i){let o=await tm(e,t.port,r,a,n,t,i);return await rp(o,t,a)}async function rp(e,t,r){let a=await e.text(),n={};try{n=JSON.parse(a)}catch{throw new W("COMMAND_FAILED","Invalid runner response",{text:a})}if(!n.ok)throw new W("string"==typeof n.error?.code&&n.error.code.trim().length>0?n.error.code:"COMMAND_FAILED",n.error?.message??"Runner error",{runner:n,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:r});return t.ready=!0,n.data??{}}async function rf(e,t,r={}){var a;if("ios"!==e.platform&&"macos"!==e.platform)throw new W("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new W("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(ti(r.requestId),"interactionFrame"===(a=t.command)||"snapshot"===a||"screenshot"===a||"findText"===a||"readText"===a||"alert"===a||"uptime"===a)?eG(()=>(ti(r.requestId),rm(e,t,r)),{shouldRetry:e=>{ti(r.requestId);if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}}):rm(e,t,r)}async function rm(e,t,r={}){let a;ti(r.requestId);let n=eY(r.requestId);try{let i=(a=await rr(e,r)).ready?ts:to;return await rc(e,a,t,r.logPath,i,n)}catch(o){let i=o instanceof W?o:new W("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===i.code&&"string"==typeof i.message&&i.message.includes("Runner did not accept connection")&&tr(i)&&a?.ready){ti(r.requestId),a?await rn(a):await ro(e.id),a=await rr(e,r);let i=await tm(a.device,a.port,t,r.logPath,to,void 0,n);return await rp(i,a,r.logPath)}throw o}}function rh(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function rw(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let rg=/^-?\d+(\.\d+)?$/,ry=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),rv=new Map([["--count","count"],["--pause-ms","pauseMs"]]),rI=new Map([["--delay-ms","delayMs"]]);function rb(e){return"click"===e||"press"===e}function rA(e){return"type"===e||"fill"===e}function rS(e){let t=e.trim();return t.startsWith("@")||rg.test(t)?t:JSON.stringify(t)}function rN(e){return JSON.stringify(e)}function r_(e){let t=e.trim();return/\s/.test(t)?JSON.stringify(t):t}function rx(e,t){let r=t.flags??{};if(rb(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");let t=r.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern);return}rA(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function rD(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",r_(t.metroHost)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",r_(t.bundleUrl)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",r_(t.launchUrl)))}function rM(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(r_(r)),a))e.push(rS(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),t.flags?.hideTouches&&e.push("--hide-touches")}function rk(e,t){let r=[],a={},n=rb(e)?ry:"swipe"===e?rv:rA(e)?rI:void 0;for(let i=0;i<t.length;i+=1){let o=t[i];if(rb(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(rb(e)&&"--button"===o&&i+1<t.length){let e=t[i+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),i+=1;continue}let s=n?.get(o);if(s&&i+1<t.length){let e=rO(t[i+1]);if(null!==e){a[s]=e,i+=1;continue}}if("swipe"===e&&"--pattern"===o&&i+1<t.length){let e=t[i+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),i+=1;continue}r.push(o)}return{positionals:r,flags:a}}function rE(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let n=e[a];if("--platform"===n&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===n&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===n&&a+1<e.length){let t=rO(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===n&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===n&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(n)}return{positionals:t,flags:r}}function rO(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function rL(e,t){for(let r of t.positionals??[])e.push(rS(r));t.flags?.relaunch&&e.push("--relaunch"),rD(e,t.runtime)}class rC{sessions=new Map;runtimeHints=new Map;sessionsDir;constructor(e){this.sessionsDir=e}get(e){return this.sessions.get(e)}has(e){return this.sessions.has(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){t.flags?.noRecord||(t.flags?.saveScript&&(e.recordSession=!0,"string"==typeof t.flags.saveScript&&(e.saveScriptPath=rC.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:function(e){if(!e)return{};let{platform:t,device:r,udid:a,serial:n,out:i,verbose:o,metroHost:s,metroPort:l,bundleUrl:d,launchUrl:u,snapshotInteractiveOnly:c,snapshotCompact:p,snapshotDepth:f,snapshotScope:m,snapshotRaw:h,screenshotFullscreen:w,relaunch:g,saveScript:y,noRecord:v,fps:I,hideTouches:b,count:A,intervalMs:S,delayMs:N,holdMs:_,jitterPx:x,doubleTap:D,clickButton:M,pauseMs:k,pattern:E}=e;return{platform:t,device:r,udid:a,serial:n,out:i,verbose:o,metroHost:s,metroPort:l,bundleUrl:d,launchUrl:u,snapshotInteractiveOnly:c,snapshotCompact:p,snapshotDepth:f,snapshotScope:m,snapshotRaw:h,screenshotFullscreen:w,relaunch:g,saveScript:y,noRecord:v,fps:I,hideTouches:b,count:A,intervalMs:S,delayMs:N,holdMs:_,jitterPx:x,doubleTap:D,clickButton:M,pauseMs:k,pattern:E}}(t.flags),result:t.result}),ep({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=p.dirname(t);s.existsSync(r)||s.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let n of(r.push(`context platform=${e.device.platform} device=${rN(e.device.name)}${a} theme=unknown`),t))n.flags?.noRecord||r.push(function(e){let t=[e.command];if(rb(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(rS(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(rS(a)),rx(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(rS(r)),rx(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(rS(r));let a=e.result?.refLabel,n=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(rS(a)),n&&t.push(rS(n)),rx(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(rS(r)),t.push(rS(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(rS(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",rS(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(rS(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return rL(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(r_(r)),rD(t,e.flags),t.join(" ")}if("record"===e.command)return rM(t,e),t.join(" ");for(let r of e.positionals??[])t.push(rS(r));return rx(t,e),t.join(" ")}(n));return`${r.join("\n")}
8
- `}(e,this.buildOptimizedActions(e));s.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=rC.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return p.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return p.join(this.sessionsDir,rC.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return p.join(this.sessionsDir,rC.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return ei(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return rC.expandHome(e.saveScriptPath);s.existsSync(this.sessionsDir)||s.mkdirSync(this.sessionsDir,{recursive:!0});let t=rC.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return p.join(this.sessionsDir,`${t}-${r}.ad`)}buildOptimizedActions(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let a=Array.isArray(r.result?.selectorChain)&&r.result?.selectorChain.every(e=>"string"==typeof e)?r.result.selectorChain:[];if(a.length>0&&(rb(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(rb(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=rh(r);if(a.length>0){t.push({...r,positionals:[e,a]});continue}}if("get"===r.command){let a=r.positionals?.[0];if("text"===a||"attrs"===a){t.push({...r,positionals:[a,e]});continue}}}if(rb(r.command)||"fill"===r.command||"get"===r.command){let a=r.result?.refLabel;"string"==typeof a&&a.trim().length>0&&t.push({ts:r.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:a.trim()},result:{scope:a.trim()}})}t.push(r)}return t}}let rP="app-log.pid";function rR(e){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t))return{pid:Number.parseInt(t,10)};try{let e=JSON.parse(t);if(!Number.isInteger(e.pid)||e.pid<=0)return null;return e}catch{return null}}function rT(e,t){if(!e)return;let r=p.dirname(e);s.existsSync(r)||s.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:ey(t)??void 0,command:M(t)??void 0};s.writeFileSync(e,`${JSON.stringify(a)}
4
+ ${r}`.toLowerCase()).includes("device is busy")&&a.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":e2("IOS_RUNNER_CONNECT_TIMEOUT"))})}function ti(e){if(eX(e))throw eZ()}let to=e0(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),ts=e0(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),tl=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),td=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),tu=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),tc=e0(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),tp=e0(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),tf=e0(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function tm(e,t,r,a,n=to,i,o){let s=eF.fromTimeoutMs(n),l=await th(e,t,s.remainingMs()),d=null,u=Math.max(1,Math.ceil(n/tl));try{return await eU(async({deadline:s})=>{if(s?.isExpired())throw new O("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:n});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await tn({session:i,port:t,logPath:a});for(let a of("device"===e.kind&&(l=await th(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??n;if(e<=0)throw new O("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:n});return await tw(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},Math.min(tc,e),o)}catch(e){if(o?.aborted||eQ(e))throw eZ();d=e}throw new O("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:d?String(d):void 0})},{maxAttempts:u,baseDelayMs:td,maxDelayMs:tu,jitter:.2,shouldRetry:tr},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||eQ(e))throw eZ();d||(d=e)}if(o?.aborted)throw eZ();if("simulator"===e.kind){let n=s.remainingMs();if(n<=0)throw ta({port:t,endpoints:l,logPath:a,lastError:d});let i=await ty(e,t,r,n);return new Response(i.body,{status:i.status})}throw ta({port:t,endpoints:l,logPath:a,lastError:d})}async function th(e,t,r){let a=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return a;let n=await tg(e.id,r);return n&&a.unshift(`http://[${n}]:${t}/command`),a}async function tw(e,t,r,a){let n,i=new AbortController,o=setTimeout(()=>i.abort(),r);a&&(a.aborted?(clearTimeout(o),i.abort()):(n=()=>i.abort(),a.addEventListener("abort",n,{once:!0})));try{return await fetch(e,{...t,signal:i.signal})}finally{clearTimeout(o),n&&a&&a.removeEventListener("abort",n)}}async function tg(e,t){if("number"==typeof t&&t<=0)return null;let r="number"==typeof t?Math.max(1,Math.min(tp,t)):tp,a=p.join(u.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(r/1e3)),n=await F("xcrun",["devicectl","device","info","details","--device",e,"--json-output",a,"--timeout",String(t)],{allowFailure:!0,timeoutMs:r});if(0!==n.exitCode||!s.existsSync(a))return null;let i=JSON.parse(s.readFileSync(a,"utf8"));if(i.info?.outcome&&"success"!==i.info.outcome)return null;let o=(i.result?.connectionProperties?.tunnelIPAddress??i.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return o&&o.length>0?o:null}catch{return null}finally{tb(a)}}async function ty(e,t,r,a){let n=JSON.stringify(r),i=tt(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",n,`http://127.0.0.1:${t}/command`]),o=await F("xcrun",i,{allowFailure:!0,timeoutMs:a}),s=o.stdout;if(0!==o.exitCode){let e=e1({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new O("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:e2(e)})}return{status:200,body:s}}async function tv(){return await new Promise((e,t)=>{let r=f.createServer();r.listen(0,"127.0.0.1",()=>{let a=r.address();if("object"==typeof a&&a?.port){let t=a.port;r.close(()=>e(t))}else r.close(()=>t(new O("COMMAND_FAILED","Failed to allocate port")))}),r.on("error",t)})}function tI(e,t,r,a){t&&s.appendFile(t,e,()=>{}),r&&s.appendFile(r,e,()=>{}),a&&process.stderr.write(e)}function tb(e){try{s.existsSync(e)&&s.unlinkSync(e)}catch{}}let tA=new m;async function tS(e,t,r){let a=tA.getStore()??[];if(a.some(r=>r.locks===e&&r.key===t))return await r();let n=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>tA.run([...a,{locks:e,key:t}],r));return e.set(t,n),n.finally(()=>{e.get(t)===n&&e.delete(t)})}function tN(e){return"apple"===e||"ios"===e||"macos"===e}function t_(e,t){return!t||("apple"===t?tN(e):e===t)}function tx(e){let{simulatorSetPath:t,platform:r,target:a}=e;if(t&&"macos"!==r&&"desktop"!==a)return t}async function tD(e,t,r={}){let a=e,n=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(a=a.filter(e=>t_(e.platform,t.platform))),t.target&&(a=a.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=a.find(e=>e.id===t.udid&&tN(e.platform));if(!e)throw new O("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=a.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new O("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=n(t.deviceName),r=a.find(t=>n(t.name)===e);if(!r)throw new O("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return r}if(1===a.length)return a[0];if(0===a.length){var i;let e=r.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new O("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
5
+ xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new O("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=a.filter(e=>"device"!==e.kind);o.length>0&&(a=o);let s=a.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??a[0]}let tM=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function tk(e,t,r){if("macos"!==e.platform)return;if(0===t.length)throw new O("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:r});let a=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of a)if(!s.existsSync(e))throw new O("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:r});for(let e of a)if(0!==$("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await F("codesign",["--remove-signature",e],{allowFailure:!0});try{await F("codesign",["--force","--sign","-",e])}catch(a){let t=a instanceof O?a:new O("COMMAND_FAILED",String(a));throw new O("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:r,error:t.message,details:t.details})}}}let tE=null;function tO(e){return function e(t){if(!Array.isArray(t))return[];let r=[];for(let a of t)if(!(!a||"object"!=typeof a||Array.isArray(a)))for(let[t,n]of Object.entries(a))":@"!==t&&"#text"!==t&&r.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[r,a]of Object.entries(e))"string"==typeof a&&(t[r]=a);return t}(a[":@"]),text:tC(n)??tC(a["#text"]),children:e(n)});return r}((tE??=new y({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function tL(e,t){for(let r of e){if("dict"===r.name)for(let e=0;e<r.children.length-1;e+=1){let a=r.children[e],n=r.children[e+1];a?.name==="key"&&a.text&&n&&t(a.text,n)}tL(r.children,t)}}function tC(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let tP="XCTestDevices",tR=".agent-device-backup",tT=".agent-device-xctestdevices-backup-",t$=p.join(u.homedir(),".agent-device","ios-runner"),tF=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),tU=new Map,tG=new Set;function tV(e){return e?.trim()??""}function tB(e=process.env){return tV(e.AGENT_DEVICE_IOS_BUNDLE_ID)||tV(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function tj(e=process.env){let t=tV(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${tB(e)}.uitests`}let tq=function(e=process.env){let t=tB(e),r=tj(e);return Array.from(new Set([tV(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${r}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function tH(e=u.homedir()){return p.join(e,"Library","Developer","XCTestDevices")}async function tW(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let r=e6(e.simulatorSetPath);if(!r)return null;let a=p.resolve(r),n=p.resolve(t.xctestDeviceSetPath??tH()),i=p.resolve(t.backupPath??function(e=tH()){return`${e}${tR}`}(n)),o=p.resolve(t.lockDirPath??function(e=u.homedir()){return p.join(e,".agent-device","xctest-device-set.lock")}()),l=t.ownerStartTime??ey(process.pid),d=await tK({lockDirPath:o,owner:{pid:t.ownerPid??process.pid,startTime:l,acquiredAtMs:t.nowMs??Date.now()}});try{if(tz({xctestDeviceSetPath:n,backupPath:i}),function(e,t){if(p.resolve(e)===p.resolve(t))return!0;try{return s.realpathSync.native(e)===s.realpathSync.native(t)}catch{return!1}}(a,n))return await d(),null;s.mkdirSync(a,{recursive:!0}),s.existsSync(n)&&s.renameSync(n,i),function(e){let{requestedSetPath:t,xctestDeviceSetPath:r}=e,a=p.dirname(r),n=p.join(a,`${tP}.agent-device-link-${process.pid}-${Date.now()}`);s.mkdirSync(a,{recursive:!0});try{s.symlinkSync(t,n,"dir"),s.renameSync(n,r)}catch(e){throw s.existsSync(n)&&tJ(n),e}}({requestedSetPath:a,xctestDeviceSetPath:n})}catch(e){throw tz({xctestDeviceSetPath:n,backupPath:i}),await d(),new O("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:a,xctestDeviceSetPath:n,backupPath:i,error:String(e)})}let c=!1;return{release:async()=>{if(!c){c=!0;try{tz({xctestDeviceSetPath:n,backupPath:i})}finally{await d()}}}}}function tz(e){let{xctestDeviceSetPath:t,backupPath:r}=e,a=[r,...function(e){let t=p.dirname(e),r=p.basename(e).replace(tR,""),a=r===tP?tT:`${r}${tT}`;try{return s.readdirSync(t).filter(e=>e.startsWith(a)).sort().map(e=>p.join(t,e))}catch{return[]}}(r)],n=a.find(e=>s.existsSync(e)),i=s.existsSync(t)&&s.lstatSync(t).isSymbolicLink();if(n){if(i&&tJ(t),s.existsSync(t))if(!i)return void U({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:n}});else n!==r?s.rmSync(n,{recursive:!0,force:!0}):s.rmSync(r,{recursive:!0,force:!0});else s.mkdirSync(p.dirname(t),{recursive:!0}),s.renameSync(n,t);for(let e of a)e!==n&&s.existsSync(e)&&s.rmSync(e,{recursive:!0,force:!0});return}i&&(U({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),tJ(t))}function tJ(e){!s.existsSync(e)||s.lstatSync(e).isSymbolicLink()&&s.unlinkSync(e)}async function tK(e){let{lockDirPath:t,owner:r}=e,a=p.join(t,"owner.json"),n=Date.now()+3e4;for(s.mkdirSync(p.dirname(t),{recursive:!0});Date.now()<n;)try{s.mkdirSync(t),function(e,t){let r=`${e}.${process.pid}.${Date.now()}.tmp`;s.writeFileSync(r,JSON.stringify(t),"utf8"),s.renameSync(r,e)}(a,r);let e=!1;return async()=>{e||(e=!0,s.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let r=null;try{r=s.statSync(e)}catch{return!0}let a=function(e){try{return JSON.parse(s.readFileSync(e,"utf8"))}catch{return null}}(t);if(a){var n;return!(Number.isInteger((n=a).pid)&&!(n.pid<=0)&&eg(n.pid)&&(!n.startTime||ey(n.pid)===n.startTime))&&(s.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-r.mtimeMs<5e3)&&(s.rmSync(e,{recursive:!0,force:!0}),!0)}(t,a))continue;await new Promise(e=>setTimeout(e,100))}throw new O("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function tX(e,t){var r;let a,n=(r=e,(a=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?p.resolve(a):"macos"===r.platform?p.join(t$,"derived","macos"):"simulator"===r.kind?p.join(t$,"derived"):p.join(t$,"derived",r.kind)),i=function(){let e=p.dirname(w(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=p.join(t,"package.json");if(s.existsSync(e))return t;t=p.dirname(t)}return e}();return await tS(tU,n,async()=>{eP(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(t9("clean","forced_clean",{derived:n}),t6(n),tY(n));let r=function(e){let t=e.findXctestrun(e.derived);if(!t)return{reason:"missing_xctestrun",xctestrunPath:null};let r=e.resolveExistingXctestrunProductPaths(t);return r?e.xctestrunReferencesProjectRoot(t,e.projectRoot)?{reason:"reuse_ready",xctestrunPath:t,productPaths:r}:{reason:"project_root_mismatch",xctestrunPath:t,productPaths:r}:{reason:"missing_products",xctestrunPath:t,productPaths:[]}}({derived:n,projectRoot:i,findXctestrun:t=>tQ(t,e),xctestrunReferencesProjectRoot:t1,resolveExistingXctestrunProductPaths:t7});if("reuse_ready"!==r.reason&&t9("rebuild",r.reason,{derived:n,xctestrunPath:r.xctestrunPath}),"reuse_ready"===r.reason)try{return await tk(e,r.productPaths,r.xctestrunPath),t9("reuse","reuse_ready",{derived:n,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof O))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&tM.has(t)}(e))throw e;t9("rebuild","repair_failed",{derived:n,xctestrunPath:r.xctestrunPath})}r.xctestrunPath&&(t6(n),tY(n));let a=p.join(i,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!s.existsSync(a))throw new O("COMMAND_FAILED","iOS runner project not found",{projectPath:a});await t3(e,a,n,t);let o=tQ(n,e);if(!o)throw new O("COMMAND_FAILED","Failed to locate .xctestrun after build");let l=t7(o);if(!l)throw new O("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:o});return await tk(e,l,o),t9("build","built_new",{derived:n,xctestrunPath:o}),o})}function tY(e){try{if(!s.existsSync(e))return;if("derived"!==p.basename(e))return void s.rmSync(e,{recursive:!0,force:!0});for(let r of s.readdirSync(e,{withFileTypes:!0})){var t;t=r.name,tZ.has(t)&&s.rmSync(p.join(e,r.name),{recursive:!0,force:!0})}}catch{}}let tZ=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function tQ(e,t){if(!s.existsSync(e))return null;let r=[],a=[e];for(;a.length>0;){let e=a.pop();for(let t of s.readdirSync(e,{withFileTypes:!0})){let n=p.join(e,t.name);if(t.isDirectory()){a.push(n);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=s.statSync(n);r.push({path:n,mtimeMs:e.mtimeMs})}catch{}}}return 0===r.length?null:(r.sort((e,r)=>{if(t){let a=t0(r.path,t)-t0(e.path,t);if(0!==a)return a}return r.mtimeMs-e.mtimeMs||e.path.localeCompare(r.path)}),r[0]?.path??null)}function t0(e,t){var r;let a=0,n=e.toLowerCase();p.basename(n).startsWith("agentdevicerunner.env.")&&(a-=1e3),n.includes(`${p.sep}macos${p.sep}`)&&(a-=5e3);let i="macos"===(r=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===r.target?"simulator"===r.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===r.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>n.includes(e))?a+=2e3:a-=500),i.disallowed.some(e=>n.includes(e))&&(a-=2500),a}function t1(e,t){try{let r=s.readFileSync(e,"utf8"),a=new Set([t]);try{a.add(s.realpathSync(t))}catch{}for(let e of a)if(r.includes(e))return!0;return!1}catch{return!1}}async function t2(e,t,r){let a,n=p.dirname(e),i=r.replace(/[^a-zA-Z0-9._-]/g,"_"),o=p.join(n,`AgentDeviceRunner.env.${i}.json`),l=p.join(n,`AgentDeviceRunner.env.${i}.xctestrun`),d=await F("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==d.exitCode||!d.stdout.trim())throw new O("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:d.stderr});try{a=JSON.parse(d.stdout)}catch(t){throw new O("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let u=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},c=a.TestConfigurations;if(Array.isArray(c))for(let e of c){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&u(e)}for(let[e,t]of Object.entries(a))t&&"object"==typeof t&&t.TestBundlePath&&(u(t),a[e]=t);s.writeFileSync(o,JSON.stringify(a,null,2));let f=await F("plutil",["-convert","xml1","-o",l,o],{allowFailure:!0});if(0!==f.exitCode)throw new O("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:l,stderr:f.stderr});return{xctestrunPath:l,jsonPath:o}}async function t3(e,t,r,a){let n=function(e=process.env){let t=tB(e),r=tj(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${r}`]}(process.env),i=function(e=process.env,t=!1,r="ios"){if("macos"===r)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let a=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",n=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return a&&o.push(`DEVELOPMENT_TEAM=${a}`),n&&o.push(`CODE_SIGN_IDENTITY=${n}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await tW(e);try{var l;let s;await M("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",t8(e),"1","-destination",(l=e,s=t4(l),"macOS"===s?`platform=macOS,arch=${t5()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",r,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...n,...o,...i],{detached:!0,onSpawn:e=>{tG.add(e),e.on("close",()=>{tG.delete(e)})},onStdoutChunk:e=>{tI(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{tI(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(i){let e,t,r=i instanceof O?i:new O("COMMAND_FAILED",String(i)),n=(e=r.details?JSON.stringify(r.details):"",(t=`${r.message}
6
+ ${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new O("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:r.message,details:r.details,logPath:a.logPath,hint:n})}finally{await s?.release()}}function t4(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new O("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"macos"===e.platform?"macOS":"macos"===(t=e.target)||"desktop"===t?"macOS":"tv"===t?"tvOS":"iOS"}function t5(){return"arm64"===process.arch?"arm64":"x86_64"}function t8(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function t6(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return eP(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new O("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}function t9(e,t,r){U({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...r}})}function t7(e){let t=function(e){let t=function(e){try{let t=$("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode||!t.stdout.trim())return null;return JSON.parse(t.stdout)}catch{return null}}(e);if(t){var r,a,n=t;let e=new Set,i=t=>{if(t&&"object"==typeof t)for(let r of function(e){let t=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),r=new Set;for(let[a,n]of Object.entries(e))if(t.has(a)){if("string"==typeof n){r.add(n);continue}if(Array.isArray(n))for(let e of n)"string"==typeof e&&r.add(e)}return Array.from(r)}(t))e.add(r)};i(n);let o=n.TestConfigurations;if(Array.isArray(o))for(let e of o){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)i(e)}for(let e of Object.values(n))e&&"object"==typeof e&&"TestBundlePath"in e&&i(e);return Array.from(e)}if("darwin"===process.platform)return null;try{let t;return r=s.readFileSync(e,"utf8"),a=tO(r),t=new Set,tL(a,(e,r)=>{if(tF.has(e)){if("string"===r.name&&r.text)return void t.add(r.text);if("array"===r.name)for(let e of r.children)"string"===e.name&&e.text&&t.add(e.text)}}),Array.from(t)}catch{return null}}(e);if(!t||0===t.length)return null;let r=p.dirname(e),a=new Set,n=new Set,i=[];for(let e of t){if(e.startsWith("__TESTROOT__/")){let t=e.slice(13),i=p.join(r,t);if(!s.existsSync(i))return null;a.add(i);let o=function(e){let t=/\.app(?:\/|$)/.exec(e);return t&&void 0!==t.index?e.slice(0,t.index+4):null}(t);o&&n.add(p.join(r,o));continue}e.startsWith("__TESTHOST__/")&&i.push(e.slice(13))}for(let e of i){let t=Array.from(n).find(t=>s.existsSync(p.join(t,e)));if(!t)return null;a.add(p.join(t,e))}return Array.from(a)}let re=new Map,rt=new Map;async function rr(e,t){return await tS(rt,e.id,async()=>{var r;let a,n,i=re.get(e.id);if(i){if(function(e){return!!e&&eg(e)}(i.child.pid))return i;await ri(e.id,i)}await ("simulator"!==(r=e).kind?Promise.resolve():ru(r)),await ra(e);let o=await tX(e,t),s=await tv(),{xctestrunPath:l,jsonPath:d}=await t2(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),u=await tW(e);try{let t;({child:a,wait:n}=C("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",t8(e),"1","-destination-timeout",String(tf),"-xctestrun",l,"-destination",(t=t4(e),"macOS"===t?`platform=macOS,arch=${t5()}`:"simulator"===e.kind?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0}))}catch(e){throw await u?.release(),e}a.stdout?.on("data",e=>{tI(e,t.logPath,t.traceLogPath,t.verbose)}),a.stderr?.on("data",e=>{tI(e,t.logPath,t.traceLogPath,t.verbose)});let c={sessionId:`${e.id}:${s}:${Date.now()}`,device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:d,testPromise:n,child:a,ready:!1,simulatorSetRedirect:u??void 0};return re.set(e.id,c),c})}async function ra(e){if("simulator"===e.kind)for(let t of tq){let r=await F("xcrun",tt(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==r.exitCode){let e=`${r.stdout}
7
+ ${r.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}async function rn(e){await tS(rt,e.deviceId,async()=>{await ri(e.deviceId,e)})}async function ri(e,t){let r=t??re.get(e);if(r){try{await tm(r.device,r.port,{command:"shutdown"},void 0,15e3)}catch{await rd(r.child.pid,"SIGTERM")}try{await Promise.race([r.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}await rd(r.child.pid,"SIGKILL"),tb(r.xctestrunPath),tb(r.jsonPath),await r.simulatorSetRedirect?.release(),re.get(e)===r&&re.delete(e)}}async function ro(e){await tS(rt,e,async()=>{await ri(e)})}async function rs(){let e=Array.from(re.values()),t=Array.from(tG);await Promise.allSettled(e.map(async e=>{await rd(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await rd(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await rd(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await rd(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await rd(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await rd(e.pid,"SIGKILL"),tG.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function rl(){await rs();let e=Array.from(re.keys());await Promise.allSettled(e.map(async e=>{await ro(e)}));let t=Array.from(tG);await Promise.allSettled(t.map(async e=>{try{await rd(e.pid,"SIGTERM"),await rd(e.pid,"SIGKILL")}finally{tG.delete(e)}}))}async function rd(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}try{process.kill(e,t)}catch{}let r="SIGINT"===t?"INT":"SIGTERM"===t?"TERM":"KILL";try{await F("pkill",[`-${r}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function ru(e){await F("xcrun",tt(e,["bootstatus",e.id,"-b"]),{timeoutMs:to})}async function rc(e,t,r,a,n,i){let o=await tm(e,t.port,r,a,n,t,i);return await rp(o,t,a)}async function rp(e,t,r){let a=await e.text(),n={};try{n=JSON.parse(a)}catch{throw new O("COMMAND_FAILED","Invalid runner response",{text:a})}if(!n.ok)throw new O("string"==typeof n.error?.code&&n.error.code.trim().length>0?n.error.code:"COMMAND_FAILED",n.error?.message??"Runner error",{runner:n,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:r});return t.ready=!0,n.data??{}}async function rf(e,t,r={}){var a;if("ios"!==e.platform&&"macos"!==e.platform)throw new O("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new O("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(ti(r.requestId),"interactionFrame"===(a=t.command)||"snapshot"===a||"screenshot"===a||"findText"===a||"readText"===a||"alert"===a||"uptime"===a)?eG(()=>(ti(r.requestId),rm(e,t,r)),{shouldRetry:e=>{ti(r.requestId);if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}}):rm(e,t,r)}async function rm(e,t,r={}){let a;ti(r.requestId);let n=eY(r.requestId);try{let i=(a=await rr(e,r)).ready?ts:to;return await rc(e,a,t,r.logPath,i,n)}catch(o){let i=o instanceof O?o:new O("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===i.code&&"string"==typeof i.message&&i.message.includes("Runner did not accept connection")&&tr(i)&&a?.ready){ti(r.requestId),a?await rn(a):await ro(e.id),a=await rr(e,r);let i=await tm(a.device,a.port,t,r.logPath,to,void 0,n);return await rp(i,a,r.logPath)}throw o}}function rh(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function rw(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let rg=/^-?\d+(\.\d+)?$/,ry=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),rv=new Map([["--count","count"],["--pause-ms","pauseMs"]]),rI=new Map([["--delay-ms","delayMs"]]);function rb(e){return"click"===e||"press"===e}function rA(e){return"type"===e||"fill"===e}function rS(e){let t=e.trim();return t.startsWith("@")||rg.test(t)?t:JSON.stringify(t)}function rN(e){return JSON.stringify(e)}function r_(e){let t=e.trim();return/\s/.test(t)?JSON.stringify(t):t}function rx(e,t){let r=t.flags??{};if(rb(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");let t=r.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern);return}rA(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function rD(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",r_(t.metroHost)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",r_(t.bundleUrl)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",r_(t.launchUrl)))}function rM(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(r_(r)),a))e.push(rS(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),t.flags?.hideTouches&&e.push("--hide-touches")}function rk(e,t){let r=[],a={},n=rb(e)?ry:"swipe"===e?rv:rA(e)?rI:void 0;for(let i=0;i<t.length;i+=1){let o=t[i];if(rb(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(rb(e)&&"--button"===o&&i+1<t.length){let e=t[i+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),i+=1;continue}let s=n?.get(o);if(s&&i+1<t.length){let e=rO(t[i+1]);if(null!==e){a[s]=e,i+=1;continue}}if("swipe"===e&&"--pattern"===o&&i+1<t.length){let e=t[i+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),i+=1;continue}r.push(o)}return{positionals:r,flags:a}}function rE(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let n=e[a];if("--platform"===n&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===n&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===n&&a+1<e.length){let t=rO(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===n&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===n&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(n)}return{positionals:t,flags:r}}function rO(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function rL(e,t){for(let r of t.positionals??[])e.push(rS(r));t.flags?.relaunch&&e.push("--relaunch"),rD(e,t.runtime)}class rC{sessions=new Map;runtimeHints=new Map;sessionsDir;constructor(e){this.sessionsDir=e}get(e){return this.sessions.get(e)}has(e){return this.sessions.has(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){t.flags?.noRecord||(t.flags?.saveScript&&(e.recordSession=!0,"string"==typeof t.flags.saveScript&&(e.saveScriptPath=rC.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:function(e){if(!e)return{};let{platform:t,device:r,udid:a,serial:n,out:i,verbose:o,metroHost:s,metroPort:l,bundleUrl:d,launchUrl:u,snapshotInteractiveOnly:c,snapshotCompact:p,snapshotDepth:f,snapshotScope:m,snapshotRaw:h,screenshotFullscreen:w,relaunch:g,saveScript:y,noRecord:v,fps:I,hideTouches:b,count:A,intervalMs:S,delayMs:N,holdMs:_,jitterPx:x,doubleTap:D,clickButton:M,pauseMs:k,pattern:E}=e;return{platform:t,device:r,udid:a,serial:n,out:i,verbose:o,metroHost:s,metroPort:l,bundleUrl:d,launchUrl:u,snapshotInteractiveOnly:c,snapshotCompact:p,snapshotDepth:f,snapshotScope:m,snapshotRaw:h,screenshotFullscreen:w,relaunch:g,saveScript:y,noRecord:v,fps:I,hideTouches:b,count:A,intervalMs:S,delayMs:N,holdMs:_,jitterPx:x,doubleTap:D,clickButton:M,pauseMs:k,pattern:E}}(t.flags),result:t.result}),U({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=p.dirname(t);s.existsSync(r)||s.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let n of(r.push(`context platform=${e.device.platform} device=${rN(e.device.name)}${a} theme=unknown`),t))n.flags?.noRecord||r.push(function(e){let t=[e.command];if(rb(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(rS(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(rS(a)),rx(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(rS(r)),rx(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(rS(r));let a=e.result?.refLabel,n=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(rS(a)),n&&t.push(rS(n)),rx(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(rS(r)),t.push(rS(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(rS(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",rS(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(rS(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return rL(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(r_(r)),rD(t,e.flags),t.join(" ")}if("record"===e.command)return rM(t,e),t.join(" ");for(let r of e.positionals??[])t.push(rS(r));return rx(t,e),t.join(" ")}(n));return`${r.join("\n")}
8
+ `}(e,this.buildOptimizedActions(e));s.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=rC.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return p.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return p.join(this.sessionsDir,rC.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return p.join(this.sessionsDir,rC.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return ed(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return rC.expandHome(e.saveScriptPath);s.existsSync(this.sessionsDir)||s.mkdirSync(this.sessionsDir,{recursive:!0});let t=rC.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return p.join(this.sessionsDir,`${t}-${r}.ad`)}buildOptimizedActions(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let a=Array.isArray(r.result?.selectorChain)&&r.result?.selectorChain.every(e=>"string"==typeof e)?r.result.selectorChain:[];if(a.length>0&&(rb(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(rb(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=rh(r);if(a.length>0){t.push({...r,positionals:[e,a]});continue}}if("get"===r.command){let a=r.positionals?.[0];if("text"===a||"attrs"===a){t.push({...r,positionals:[a,e]});continue}}}if(rb(r.command)||"fill"===r.command||"get"===r.command){let a=r.result?.refLabel;"string"==typeof a&&a.trim().length>0&&t.push({ts:r.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:a.trim()},result:{scope:a.trim()}})}t.push(r)}return t}}let rP="app-log.pid";function rR(e){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t))return{pid:Number.parseInt(t,10)};try{let e=JSON.parse(t);if(!Number.isInteger(e.pid)||e.pid<=0)return null;return e}catch{return null}}function rT(e,t){if(!e)return;let r=p.dirname(e);s.existsSync(r)||s.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:ey(t)??void 0,command:V(t)??void 0};s.writeFileSync(e,`${JSON.stringify(a)}
9
9
  `)}function r$(e){if(e&&s.existsSync(e))try{s.unlinkSync(e)}catch{}}async function rF(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}async function rU(e){await new Promise(t=>setTimeout(t,e))}function rG(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],a="",n=a=>{(!(r.length>0)||r.some(e=>a.includes(e)))&&e.write(function(e,t){if(0===t.length)return e;let r=e;for(let e of t)r=r.replace(e,"[REDACTED]");return r}(a,t.redactionPatterns))};return{onChunk:e=>{let t=`${a}${e}`.split("\n");for(let e of(a=t.pop()??"",t))n(`${e}
10
- `)},flush:()=>{a&&(n(a),a="")}}}function rV(e,t,r){let a=e.stdout,n=e.stderr;return a&&n?(a.setEncoding("utf8"),n.setEncoding("utf8"),a.on("data",r.writer.onChunk),n.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(a=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),a({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}function rB(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new W("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function rj(e,t){let r=(await $("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function rq(e,t){var r,a;let n;rB(t);let i=await rj(e,t),o=await $("adb",["-s",e,"logcat","-d","-v","time","-t","4000"],{allowFailure:!0,timeoutMs:3e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=function(e,t,r){let a=new Set;for(let n of(r&&a.add(r),e.split("\n")))if(n.includes(t))for(let e of function(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=[RegExp(`\\bStart proc\\s+(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`\\b(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`${r}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,"i"),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${r}`,"i")],n=[];for(let t of a){let r=t.exec(e),a=r?.[1];a&&/^\d+$/.test(a)&&n.push(a)}return n}(n,t))a.add(e);return[...a]}(o.stdout,t,i);if(0===s.length)return null;let l=(r=o.stdout,a=t,n=new Set(s),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(a))return!0;let i=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!i&&n.has(i)}).join("\n"));return 0===l.trim().length?null:{pid:i,text:l,recoveredPids:s}}async function rH(e,t,r,a,n){let i,o,s="recovering",l=!1,d=(async()=>{try{for(;!l;){let d=await rj(e,t);if(!d){s="recovering",await rU(1e3);continue}let u=v("adb",["-s",e,"logcat","-v","time","--pid",d],{stdio:["ignore","pipe","pipe"]});i=u;let c=rG(r,{redactionPatterns:a});if(o=rV(u,r,{endStreamOnClose:!1,writer:c}),"number"==typeof u.pid&&(rT(n,u.pid),s="active"),await o,r$(n),i=void 0,o=void 0,l)break;s="recovering",await rU(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),r$(n)}})();return{backend:"android",getState:()=>s,startedAt:Date.now(),wait:d,stop:async()=>{l=!0,i&&!i.killed&&i.kill("SIGINT"),o&&await rF(o),i&&!i.killed&&i.kill("SIGKILL"),await rF(d),r$(n)}}}function rW(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function rz(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:n}=e,i=te(["spawn",t,"log","show","--style","compact","--info","--predicate",rW(r)],{simulatorSetPath:n});"number"==typeof a&&Number.isFinite(a)&&a>0?i.push("--start",`@${Math.floor(a/1e3)}`):i.push("--last","5m");let o=await $("xcrun",i,{allowFailure:!0,timeoutMs:4e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=o.stdout.split("\n").map(e=>e.trimEnd()).filter(e=>{let t=e.trim();return t.length>0&&!t.startsWith("Timestamp Ty Process[PID:TID]")});return 0===s.length?null:{text:`${s.join("\n")}
11
- `,recoveredLineCount:s.length}}async function rJ(e,t,r,a,n,i){let o="active",s=v("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return te(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",rW(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:n}),{stdio:["ignore","pipe","pipe"]}),l=rG(r,{redactionPatterns:a});"number"==typeof s.pid&&rT(i,s.pid);let d=rV(s,r,{endStreamOnClose:!0,writer:l}).then(e=>(0!==e.exitCode&&(o="failed"),r$(i),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:d,stop:async()=>{s.killed||s.kill("SIGINT"),await rF(d),s.killed||s.kill("SIGKILL"),await rF(d),r$(i)}}}async function rK(e,t,r,a){let n="active",i=v("log",["stream","--style","compact","--predicate",rW(e)],{stdio:["ignore","pipe","pipe"]}),o=rG(t,{redactionPatterns:r});"number"==typeof i.pid&&rT(a,i.pid);let s=rV(i,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(n="failed"),r$(a),e));return{backend:"macos",getState:()=>n,startedAt:Date.now(),wait:s,stop:async()=>{i.killed||i.kill("SIGINT"),await rF(s),i.killed||i.kill("SIGKILL"),await rF(s),r$(a)}}}async function rX(e,t,r,a){let n="active",i=v("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=rG(t,{redactionPatterns:r});"number"==typeof i.pid&&rT(a,i.pid);let s=rV(i,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(n="failed"),r$(a),e));return{backend:"ios-device",getState:()=>n,startedAt:Date.now(),wait:s,stop:async()=>{i.killed||i.kill("SIGINT"),await rF(s),i.killed||i.kill("SIGKILL"),await rF(s),r$(a)}}}let rY=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),rZ=/https?:\/\/[^\s"'<>\])]+/i,rQ=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function r0(e,t,r=e.limits.maxEntries){let a=[...e.entries],n=new Set(a.map(e=>r2(e)));for(let e of t.entries){let t=r2(e);if(!n.has(t)&&(n.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function r1(e,t){let r=ar(t?.maxEntries,25,1,200),a=t?.backend,n=t?.include??"summary",i=ar(t?.maxPayloadChars,2048,64,16384),o=ar(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),d=s.slice(l),u=[];for(let e=d.length-1;e>=0&&u.length<r;e-=1){let t=d[e];if(!t?.trim())continue;let r=function(e,t,r,a,n,i){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=r9(s,["method","httpMethod"]),d=r9(s,["url","requestUrl"]),u=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(s,["status","statusCode","responseCode"]),c=rY.exec(o),p=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),f=(l??p?.[1]??c?.[1])?.toUpperCase(),m=rZ.exec(o),h=d??m?.[0];if(!h)return null;let w=u??r4(o)??void 0;if(!(l||p?.[1]||c?.[1]||void 0!==w||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let g={method:f,url:h,status:w,timestamp:r5(o),packetId:r8(o)??void 0,durationMs:r6(o)??void 0,raw:at(o,i),line:r};if("android"===a&&function(e,t,r){let a=r3(t,r,5),n=e.packetId??a.map(e=>r8(e)).find(e=>"string"==typeof e&&e.length>0);n&&(e.packetId=n);let i=n?r3(t,r,12).filter(e=>r8(e)===n):a;e.timestamp||(e.timestamp=i.map(e=>r5(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=i.map(e=>r4(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=i.map(e=>r6(e)).find(e=>"number"==typeof e))}(g,e,t),"headers"===n||"all"===n){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return ae(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(g.headers=at(e,i))}if("body"===n||"all"===n){let e=r7(o,s,["requestBody","body","payload","request"]),t=r7(o,s,["responseBody","response"]);e&&(g.requestBody=at(e,i)),t&&(g.responseBody=at(t,i))}return g}(d,e,l+e+1,a,n,i);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:n,limits:{maxEntries:r,maxPayloadChars:i,maxScanLines:o}}}function r2(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function r3(e,t,r){let a=[],n=Math.max(0,t-r),i=Math.min(e.length-1,t+r);for(let t=n;t<=i;t+=1){let r=e[t]?.trim();r&&a.push(r)}return a}function r4(e){for(let t of rQ){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function r5(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);if(t)return t[0];let r=/\b\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\b/.exec(e);return r?.[0]}function r8(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function r6(e){let t=/\b(?:duration|elapsed request\/response time, ms)[:= ]+(\d+)\b/i.exec(e);if(!t)return null;let r=Number.parseInt(t[1]??"",10);return Number.isInteger(r)?r:null}function r9(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function r7(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return ae(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(a?.[1])return a[1].trim()}}function ae(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function at(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function ar(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function aa(e,t){let r=process.env[e];if(!r)return t;let a=Number.parseInt(r,10);return Number.isInteger(a)&&a>0?a:t}function an(e){let t=p.dirname(e);s.existsSync(t)||s.mkdirSync(t,{recursive:!0}),function(e,t){if(s.existsSync(e)&&!(s.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;s.existsSync(t)&&(s.existsSync(a)&&s.unlinkSync(a),s.renameSync(t,a))}}(e,{maxBytes:aa("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:aa("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function ai(e){var t,r,a,n;let i,o,l,d,{device:u,appBundleId:c,appLogState:p,appLogStartedAt:f,appLogPath:m,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:v,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y},i=ar(t?.maxEntries,25,1,200),o=t?.include??"summary",l=ar(t?.maxPayloadChars,2048,64,16384),d=ar(t?.maxScanLines,4e3,100,2e4),s.existsSync(m)?r1(s.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:o,limits:{maxEntries:i,maxPayloadChars:l,maxScanLines:d}}),b=[],A=await ao({device:u,appBundleId:c,appLogPath:m,appLogState:p});if(A){let e=await rq(u.id,c);if(e){let t=r1(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y});t.entries.length>0&&(I=r0(t,I,h),b.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await al({deviceId:u.id,appBundleId:c,startedAt:f,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y});e&&(e.dump.entries.length>0?(I=r0(e.dump,I,h),b.push(`Recovered ${e.dump.entries.length} iOS simulator HTTP entr${1===e.dump.entries.length?"y":"ies"} from simctl log show (${e.recoveredLineCount} app log lines scanned).`)):e.recoveredLineCount>0&&b.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===p?b.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==p&&0===b.length&&("ios"===u.platform&&"simulator"===u.kind?b.push("Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop."):b.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&b.push("ios"===(n=u).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:I,notes:b}}async function ao(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let i=function(e){let t=function(e){if(!e||!s.existsSync(e))return null;try{return rR(s.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(p.join(p.dirname(a),rP));if(!i)return null;let o=await rj(t.id,r);return o&&o!==i?{reason:"stale-active",trackedPid:i}:null}async function as(e,t,r,a){an(r);let n=s.createWriteStream(r,{flags:"a"}),i=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await rX(e.id,n,i,a):await rJ(e.id,t,n,i,e.simulatorSetPath,a);if("android"===e.platform)return rB(t),await rH(e.id,t,n,i,a);if("macos"===e.platform)return await rK(t,n,i,a);throw n.end(),new W("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function al(e){let t=await rz({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:r1(t.text,{path:`${e.appLogPath} (simctl log show recovery)`,backend:"ios-simulator",maxEntries:e.maxEntries,include:e.include,maxPayloadChars:e.maxPayloadChars,maxScanLines:e.maxScanLines}),recoveredLineCount:t.recoveredLineCount}:null}async function ad(e){await e.stop(),await rF(e.wait)}async function au(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await $("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await $("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await $("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await $("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await $("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function ac(e){let t=p.dirname(e),r=p.basename(e);s.existsSync(t)||s.mkdirSync(t,{recursive:!0}),s.existsSync(e)?s.truncateSync(e,0):s.writeFileSync(e,"","utf8");let a=0;for(let e of s.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{s.unlinkSync(p.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let ap=new Map;function af(e){let t=ap.get(e);if(t&&(clearTimeout(t.timer),ap.delete(e),t.deleteAfterDownload))try{s.rmSync(t.artifactPath,{force:!0})}catch{}}let am=new Map;function ah(e,t){let r=am.get(e);if(!r)throw new W("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new W("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function aw(e){let t=am.get(e);t&&(clearTimeout(t.timer),am.delete(e),s.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function ag(e){let t=await ay(e);await $("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=p.join(e.tempDir,t);if(!s.existsSync(r))throw new W("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function ay(e){let t=await $("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new W("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new W("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(av),n=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new W("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new W("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new W("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===n||e.startsWith(`${n}/`)))throw new W("INVALID_ARGS",`Uploaded archive must contain a top-level "${n}" bundle`);for(let e of a){var i=e,o=n;if(i!==o&&!i.startsWith(`${o}/`))throw new W("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${i}`)}for(let t of(await $("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new W("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return n}function av(e){if(e.includes("\0"))throw new W("INVALID_ARGS",`Invalid archive entry: ${e}`);if(p.posix.isAbsolute(e))throw new W("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=p.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new W("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let aI=e0(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function ab(e,t){return new Promise((r,a)=>{let n,i=s.createWriteStream(t),o=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},l=!1,d=0,u=e=>{if(!l){if(l=!0,n&&clearTimeout(n),e){i.destroy(),s.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new W("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:aI});o(e),i.destroy(e),u(e)},aI)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new W("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");o(e),i.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new W("COMMAND_FAILED","Artifact transfer was interrupted"))}),i.on("error",u),i.on("finish",()=>u()),c(),e.pipe(i)})}async function aA(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new W("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new W("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new W("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=p.basename(t);if(!r||"."===r||".."===r)throw new W("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),i=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),s.mkdtempSync(p.join(u.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=p.join(i,n);return await ab(e,t),{artifactPath:t,tempDir:i}}let t=p.join(i,"artifact.tar");await ab(e,t);let a=await ag({archivePath:t,tempDir:i,platform:"ios",expectedRootName:n});return s.rmSync(t,{force:!0}),{artifactPath:a,tempDir:i}}catch(e){throw s.rmSync(i,{recursive:!0,force:!0}),e}}let aS=new Set(["agent_device.command","agent-device.command"]),aN=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),a_=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),ax={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},aD=new Set([...aS,...aN,...a_,...Object.keys(ax)]);function aM(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function ak(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function aE(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function aO(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,n="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??n??a??""}function aL(e,t){let r=e[t];return"string"==typeof r?r:void 0}function aC(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function aP(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=ea(new W("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:aM(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=ea(new W(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:aM(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=O(r.tenantId);if(!e){let e=ea(new W("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:aM(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function aR(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=p.isAbsolute(t)?t:p.resolve(t);try{e=await import(g(a).href)}catch(e){throw new W("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let n=e[r];if("function"!=typeof n)throw new W("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return n}async function aT(e){let t=await aR(),{handleRequest:r,token:a}=e;return I.createServer((e,n)=>{if("GET"===e.method&&"/health"===e.url){n.statusCode=200,n.setHeader("content-type","application/json"),n.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void a$(e,n,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void aF(e,n,t,a);if("POST"!==e.method||"/rpc"!==e.url){n.statusCode=404,n.end("Not found");return}let i="";e.setEncoding("utf8"),e.on("data",t=>{(i+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{n.headersSent||ak(n,aM(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(i)}catch{ak(n,aM(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void ak(n,aM(a.id??null,-32600,"Invalid Request"),400);if(!aD.has(a.method))return void ak(n,aM(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void ak(n,aM(a.id??null,-32602,"Invalid params"),400);try{var s;let i=a.params,l=function(e,t,r){if(aS.has(e))return{token:aO(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(aN.has(e)){let e,a=aL(t,"platform");if("ios"!==a&&"android"!==a)throw new W("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:aO(t,r),session:aL(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:aL(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new W("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new W("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new W("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new W("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new W("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new W("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:aC(t,"retentionMs")}}}if(a_.has(e)){let e=aL(t,"materializationId")?.trim();if(!e)throw new W("INVALID_ARGS","Invalid params: materializationId is required");return{token:aO(t,r),session:aL(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:aL(t,"requestId"),materializationId:e}}}let a=ax[e];if(a)return{token:aO(t,r),session:aL(t,"session")??"default",command:a,positionals:[],meta:{tenantId:aL(t,"tenantId")??aL(t,"tenant"),runId:aL(t,"runId"),leaseId:aL(t,"leaseId"),leaseTtlMs:aC(t,"ttlMs"),leaseBackend:aL(t,"backend")}};throw new W("INVALID_ARGS",`Method not found: ${e}`)}(a.method,i,e.headers);if(s=a.method,aS.has(s)&&("string"!=typeof l.command||0===l.command.length))return void ak(n,aM(a.id??null,-32602,"Invalid params: command is required"),400);o=eW(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},ez(o);let d=()=>{n.writableFinished||eJ(o)};e.on("aborted",d),n.on("close",d);let u=await aP(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void ak(n,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void ak(n,{jsonrpc:"2.0",id:a.id??null,result:c});ak(n,aM(a.id??null,-32e3,c.error.message,c.error),aE(c.error.code))}catch(t){let e=ea(t);ak(n,aM(a.id??null,-32e3,e.message,e),aE(e.code))}finally{eK(o)}})})}async function a$(e,t,r,a){try{var n;let o,s,l=aO({},e.headers),d=aU(l,a);if(d){t.statusCode=aE(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await aP(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await aA(e),p=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=i.randomUUID(),(s=setTimeout(()=>{aw(o)},3e5)).unref(),am.set(o,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:p}))}catch(r){let e=ea(r);t.statusCode=aE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function aF(e,t,r,a){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let i=aO({},e.headers),o=aU(i,a);if(o){t.statusCode=aE(o.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:o.message,code:o.code}));return}let l=await aP(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:i,session:"default",command:"download_artifact",positionals:[n]}});if(!l.ok){t.statusCode=l.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.response.error?.data?.message??l.response.error?.message??"Unauthorized"}));return}let d=function(e,t){let r=ap.get(e);if(!r)throw new W("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new W("UNAUTHORIZED","Artifact belongs to a different tenant");if(!s.existsSync(r.artifactPath))throw af(e),new W("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=s.createReadStream(d.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),d.fileName&&t.setHeader("content-disposition",`attachment; filename="${d.fileName.replace(/"/g,"")}"`),u.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=ea(e);t.statusCode=aE(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&af(n)}),u.pipe(t)}catch(r){let e=ea(r);t.statusCode=aE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function aU(e,t){return t&&e!==t?ea(new W("UNAUTHORIZED","Invalid token")):null}function aG(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function aV(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function aB(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";throw new W("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class aj{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=aB(e.backend),r=O(e.tenantId);if(!r)throw new W("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let a=aG(e.runId);if(!a)throw new W("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,a,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),d={leaseId:i.randomBytes(16).toString("hex"),tenantId:r,runId:a,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(d.leaseId,d),this.runBindings.set(o,d.leaseId),{...d}}heartbeatLease(e){let t=aV(e.leaseId);if(!t)throw new W("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new W("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=aV(e.leaseId);if(!t)throw new W("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=aB(e.backend),r=O(e.tenantId);if(!r)throw new W("INVALID_ARGS","tenant isolation requires tenant id.");let a=aG(e.runId);if(!a)throw new W("INVALID_ARGS","tenant isolation requires run id.");let n=aV(e.leaseId);if(!n)throw new W("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let i=this.leases.get(n);if(!i)throw new W("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(i.backend!==t||i.tenantId!==r||i.runId!==a)throw new W("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new W("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new W("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=O(t),n=aG(r);if(t&&!a)throw new W("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!n)throw new W("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||n&&e.runId!==n)throw new W("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let aq=["emulator","platform-tools",p.join("cmdline-tools","latest","bin"),p.join("cmdline-tools","tools","bin")];function aH(e){let t=new Set,r=[];for(let a of e){let e=a.trim();!e||t.has(e)||(t.add(e),r.push(e))}return r}function aW(e=process.env){let t=e.ANDROID_SDK_ROOT?.trim(),r=e.ANDROID_HOME?.trim(),a=e.HOME?.trim()||u.homedir();return aH([t??"",r??"",a?p.join(a,"Android","Sdk"):""])}async function az(e){try{return await d.access(e,d.constants.X_OK),!0}catch{return!1}}async function aJ(e=process.env){let t,r=[];for(let a of aW(e)){let e=[];for(let t of aq){let r=p.join(a,t);await az(r)&&e.push(r)}0!==e.length&&(t||(t=a),r.push(...e))}if(t&&(e.ANDROID_SDK_ROOT=e.ANDROID_SDK_ROOT?.trim()||t,e.ANDROID_HOME=e.ANDROID_HOME?.trim()||t),0===r.length)return;let a=(e.PATH??"").split(p.delimiter).map(e=>e.trim()).filter(e=>e.length>0);e.PATH=aH([...r,...a]).join(p.delimiter)}function aK(e,t){return["-s",e.id,...t]}async function aX(){if(await aJ(),!await Y("adb"))throw new W("TOOL_MISSING","adb not found in PATH")}function aY(e,t){let r=`${e}
10
+ `)},flush:()=>{a&&(n(a),a="")}}}function rV(e,t,r){let a=e.stdout,n=e.stderr;return a&&n?(a.setEncoding("utf8"),n.setEncoding("utf8"),a.on("data",r.writer.onChunk),n.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(a=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),a({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}function rB(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new O("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function rj(e,t){let r=(await F("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function rq(e,t){var r,a;let n;rB(t);let i=await rj(e,t),o=await F("adb",["-s",e,"logcat","-d","-v","time","-t","4000"],{allowFailure:!0,timeoutMs:3e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=function(e,t,r){let a=new Set;for(let n of(r&&a.add(r),e.split("\n")))if(n.includes(t))for(let e of function(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=[RegExp(`\\bStart proc\\s+(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`\\b(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`${r}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,"i"),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${r}`,"i")],n=[];for(let t of a){let r=t.exec(e),a=r?.[1];a&&/^\d+$/.test(a)&&n.push(a)}return n}(n,t))a.add(e);return[...a]}(o.stdout,t,i);if(0===s.length)return null;let l=(r=o.stdout,a=t,n=new Set(s),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(a))return!0;let i=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!i&&n.has(i)}).join("\n"));return 0===l.trim().length?null:{pid:i,text:l,recoveredPids:s}}async function rH(e,t,r,a,n){let i,o,s="recovering",l=!1,d=(async()=>{try{for(;!l;){let d=await rj(e,t);if(!d){s="recovering",await rU(1e3);continue}let u=v("adb",["-s",e,"logcat","-v","time","--pid",d],{stdio:["ignore","pipe","pipe"]});i=u;let c=rG(r,{redactionPatterns:a});if(o=rV(u,r,{endStreamOnClose:!1,writer:c}),"number"==typeof u.pid&&(rT(n,u.pid),s="active"),await o,r$(n),i=void 0,o=void 0,l)break;s="recovering",await rU(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),r$(n)}})();return{backend:"android",getState:()=>s,startedAt:Date.now(),wait:d,stop:async()=>{l=!0,i&&!i.killed&&i.kill("SIGINT"),o&&await rF(o),i&&!i.killed&&i.kill("SIGKILL"),await rF(d),r$(n)}}}function rW(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function rz(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:n}=e,i=te(["spawn",t,"log","show","--style","compact","--info","--predicate",rW(r)],{simulatorSetPath:n});"number"==typeof a&&Number.isFinite(a)&&a>0?i.push("--start",`@${Math.floor(a/1e3)}`):i.push("--last","5m");let o=await F("xcrun",i,{allowFailure:!0,timeoutMs:4e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=o.stdout.split("\n").map(e=>e.trimEnd()).filter(e=>{let t=e.trim();return t.length>0&&!t.startsWith("Timestamp Ty Process[PID:TID]")});return 0===s.length?null:{text:`${s.join("\n")}
11
+ `,recoveredLineCount:s.length}}async function rJ(e,t,r,a,n,i){let o="active",s=v("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return te(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",rW(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:n}),{stdio:["ignore","pipe","pipe"]}),l=rG(r,{redactionPatterns:a});"number"==typeof s.pid&&rT(i,s.pid);let d=rV(s,r,{endStreamOnClose:!0,writer:l}).then(e=>(0!==e.exitCode&&(o="failed"),r$(i),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:d,stop:async()=>{s.killed||s.kill("SIGINT"),await rF(d),s.killed||s.kill("SIGKILL"),await rF(d),r$(i)}}}async function rK(e,t,r,a){let n="active",i=v("log",["stream","--style","compact","--predicate",rW(e)],{stdio:["ignore","pipe","pipe"]}),o=rG(t,{redactionPatterns:r});"number"==typeof i.pid&&rT(a,i.pid);let s=rV(i,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(n="failed"),r$(a),e));return{backend:"macos",getState:()=>n,startedAt:Date.now(),wait:s,stop:async()=>{i.killed||i.kill("SIGINT"),await rF(s),i.killed||i.kill("SIGKILL"),await rF(s),r$(a)}}}async function rX(e,t,r,a){let n="active",i=v("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=rG(t,{redactionPatterns:r});"number"==typeof i.pid&&rT(a,i.pid);let s=rV(i,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(n="failed"),r$(a),e));return{backend:"ios-device",getState:()=>n,startedAt:Date.now(),wait:s,stop:async()=>{i.killed||i.kill("SIGINT"),await rF(s),i.killed||i.kill("SIGKILL"),await rF(s),r$(a)}}}let rY=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),rZ=/https?:\/\/[^\s"'<>\])]+/i,rQ=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function r0(e,t,r=e.limits.maxEntries){let a=[...e.entries],n=new Set(a.map(e=>r2(e)));for(let e of t.entries){let t=r2(e);if(!n.has(t)&&(n.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function r1(e,t){let r=ar(t?.maxEntries,25,1,200),a=t?.backend,n=t?.include??"summary",i=ar(t?.maxPayloadChars,2048,64,16384),o=ar(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),d=s.slice(l),u=[];for(let e=d.length-1;e>=0&&u.length<r;e-=1){let t=d[e];if(!t?.trim())continue;let r=function(e,t,r,a,n,i){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=r9(s,["method","httpMethod"]),d=r9(s,["url","requestUrl"]),u=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(s,["status","statusCode","responseCode"]),c=rY.exec(o),p=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),f=(l??p?.[1]??c?.[1])?.toUpperCase(),m=rZ.exec(o),h=d??m?.[0];if(!h)return null;let w=u??r4(o)??void 0;if(!(l||p?.[1]||c?.[1]||void 0!==w||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let g={method:f,url:h,status:w,timestamp:r5(o),packetId:r8(o)??void 0,durationMs:r6(o)??void 0,raw:at(o,i),line:r};if("android"===a&&function(e,t,r){let a=r3(t,r,5),n=e.packetId??a.map(e=>r8(e)).find(e=>"string"==typeof e&&e.length>0);n&&(e.packetId=n);let i=n?r3(t,r,12).filter(e=>r8(e)===n):a;e.timestamp||(e.timestamp=i.map(e=>r5(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=i.map(e=>r4(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=i.map(e=>r6(e)).find(e=>"number"==typeof e))}(g,e,t),"headers"===n||"all"===n){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return ae(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(g.headers=at(e,i))}if("body"===n||"all"===n){let e=r7(o,s,["requestBody","body","payload","request"]),t=r7(o,s,["responseBody","response"]);e&&(g.requestBody=at(e,i)),t&&(g.responseBody=at(t,i))}return g}(d,e,l+e+1,a,n,i);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:n,limits:{maxEntries:r,maxPayloadChars:i,maxScanLines:o}}}function r2(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function r3(e,t,r){let a=[],n=Math.max(0,t-r),i=Math.min(e.length-1,t+r);for(let t=n;t<=i;t+=1){let r=e[t]?.trim();r&&a.push(r)}return a}function r4(e){for(let t of rQ){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function r5(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);if(t)return t[0];let r=/\b\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\b/.exec(e);return r?.[0]}function r8(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function r6(e){let t=/\b(?:duration|elapsed request\/response time, ms)[:= ]+(\d+)\b/i.exec(e);if(!t)return null;let r=Number.parseInt(t[1]??"",10);return Number.isInteger(r)?r:null}function r9(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function r7(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return ae(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(a?.[1])return a[1].trim()}}function ae(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function at(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function ar(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function aa(e,t){let r=process.env[e];if(!r)return t;let a=Number.parseInt(r,10);return Number.isInteger(a)&&a>0?a:t}function an(e){let t=p.dirname(e);s.existsSync(t)||s.mkdirSync(t,{recursive:!0}),function(e,t){if(s.existsSync(e)&&!(s.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;s.existsSync(t)&&(s.existsSync(a)&&s.unlinkSync(a),s.renameSync(t,a))}}(e,{maxBytes:aa("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:aa("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function ai(e){var t,r,a,n;let i,o,l,d,{device:u,appBundleId:c,appLogState:p,appLogStartedAt:f,appLogPath:m,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:v,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y},i=ar(t?.maxEntries,25,1,200),o=t?.include??"summary",l=ar(t?.maxPayloadChars,2048,64,16384),d=ar(t?.maxScanLines,4e3,100,2e4),s.existsSync(m)?r1(s.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:o,limits:{maxEntries:i,maxPayloadChars:l,maxScanLines:d}}),b=[],A=await ao({device:u,appBundleId:c,appLogPath:m,appLogState:p});if(A){let e=await rq(u.id,c);if(e){let t=r1(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y});t.entries.length>0&&(I=r0(t,I,h),b.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await al({deviceId:u.id,appBundleId:c,startedAt:f,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y});e&&(e.dump.entries.length>0?(I=r0(e.dump,I,h),b.push(`Recovered ${e.dump.entries.length} iOS simulator HTTP entr${1===e.dump.entries.length?"y":"ies"} from simctl log show (${e.recoveredLineCount} app log lines scanned).`)):e.recoveredLineCount>0&&b.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===p?b.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==p&&0===b.length&&("ios"===u.platform&&"simulator"===u.kind?b.push("Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop."):b.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&b.push("ios"===(n=u).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:I,notes:b}}async function ao(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let i=function(e){let t=function(e){if(!e||!s.existsSync(e))return null;try{return rR(s.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(p.join(p.dirname(a),rP));if(!i)return null;let o=await rj(t.id,r);return o&&o!==i?{reason:"stale-active",trackedPid:i}:null}async function as(e,t,r,a){an(r);let n=s.createWriteStream(r,{flags:"a"}),i=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await rX(e.id,n,i,a):await rJ(e.id,t,n,i,e.simulatorSetPath,a);if("android"===e.platform)return rB(t),await rH(e.id,t,n,i,a);if("macos"===e.platform)return await rK(t,n,i,a);throw n.end(),new O("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function al(e){let t=await rz({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:r1(t.text,{path:`${e.appLogPath} (simctl log show recovery)`,backend:"ios-simulator",maxEntries:e.maxEntries,include:e.include,maxPayloadChars:e.maxPayloadChars,maxScanLines:e.maxScanLines}),recoveredLineCount:t.recoveredLineCount}:null}async function ad(e){await e.stop(),await rF(e.wait)}async function au(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await F("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await F("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await F("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await F("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await F("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function ac(e){let t=p.dirname(e),r=p.basename(e);s.existsSync(t)||s.mkdirSync(t,{recursive:!0}),s.existsSync(e)?s.truncateSync(e,0):s.writeFileSync(e,"","utf8");let a=0;for(let e of s.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{s.unlinkSync(p.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let ap=new Map;function af(e){let t=ap.get(e);if(t&&(clearTimeout(t.timer),ap.delete(e),t.deleteAfterDownload))try{s.rmSync(t.artifactPath,{force:!0})}catch{}}let am=new Map;function ah(e,t){let r=am.get(e);if(!r)throw new O("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new O("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function aw(e){let t=am.get(e);t&&(clearTimeout(t.timer),am.delete(e),s.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function ag(e){let t=await ay(e);await F("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=p.join(e.tempDir,t);if(!s.existsSync(r))throw new O("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function ay(e){let t=await F("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new O("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new O("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(av),n=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new O("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new O("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new O("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===n||e.startsWith(`${n}/`)))throw new O("INVALID_ARGS",`Uploaded archive must contain a top-level "${n}" bundle`);for(let e of a){var i=e,o=n;if(i!==o&&!i.startsWith(`${o}/`))throw new O("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${i}`)}for(let t of(await F("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new O("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return n}function av(e){if(e.includes("\0"))throw new O("INVALID_ARGS",`Invalid archive entry: ${e}`);if(p.posix.isAbsolute(e))throw new O("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=p.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new O("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let aI=e0(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function ab(e,t){return new Promise((r,a)=>{let n,i=s.createWriteStream(t),o=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},l=!1,d=0,u=e=>{if(!l){if(l=!0,n&&clearTimeout(n),e){i.destroy(),s.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new O("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:aI});o(e),i.destroy(e),u(e)},aI)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new O("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");o(e),i.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new O("COMMAND_FAILED","Artifact transfer was interrupted"))}),i.on("error",u),i.on("finish",()=>u()),c(),e.pipe(i)})}async function aA(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new O("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new O("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new O("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=p.basename(t);if(!r||"."===r||".."===r)throw new O("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),i=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),s.mkdtempSync(p.join(u.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=p.join(i,n);return await ab(e,t),{artifactPath:t,tempDir:i}}let t=p.join(i,"artifact.tar");await ab(e,t);let a=await ag({archivePath:t,tempDir:i,platform:"ios",expectedRootName:n});return s.rmSync(t,{force:!0}),{artifactPath:a,tempDir:i}}catch(e){throw s.rmSync(i,{recursive:!0,force:!0}),e}}let aS=new Set(["agent_device.command","agent-device.command"]),aN=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),a_=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),ax={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},aD=new Set([...aS,...aN,...a_,...Object.keys(ax)]);function aM(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function ak(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function aE(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function aO(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,n="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??n??a??""}function aL(e,t){let r=e[t];return"string"==typeof r?r:void 0}function aC(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function aP(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=E(new O("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:aM(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=E(new O(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:aM(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=q(r.tenantId);if(!e){let e=E(new O("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:aM(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function aR(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=p.isAbsolute(t)?t:p.resolve(t);try{e=await import(g(a).href)}catch(e){throw new O("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let n=e[r];if("function"!=typeof n)throw new O("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return n}async function aT(e){let t=await aR(),{handleRequest:r,token:a}=e;return I.createServer((e,n)=>{if("GET"===e.method&&"/health"===e.url){n.statusCode=200,n.setHeader("content-type","application/json"),n.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void a$(e,n,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void aF(e,n,t,a);if("POST"!==e.method||"/rpc"!==e.url){n.statusCode=404,n.end("Not found");return}let i="";e.setEncoding("utf8"),e.on("data",t=>{(i+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{n.headersSent||ak(n,aM(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(i)}catch{ak(n,aM(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void ak(n,aM(a.id??null,-32600,"Invalid Request"),400);if(!aD.has(a.method))return void ak(n,aM(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void ak(n,aM(a.id??null,-32602,"Invalid params"),400);try{var s;let i=a.params,l=function(e,t,r){if(aS.has(e))return{token:aO(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(aN.has(e)){let e,a=aL(t,"platform");if("ios"!==a&&"android"!==a)throw new O("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:aO(t,r),session:aL(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:aL(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new O("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new O("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new O("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new O("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new O("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new O("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:aC(t,"retentionMs")}}}if(a_.has(e)){let e=aL(t,"materializationId")?.trim();if(!e)throw new O("INVALID_ARGS","Invalid params: materializationId is required");return{token:aO(t,r),session:aL(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:aL(t,"requestId"),materializationId:e}}}let a=ax[e];if(a)return{token:aO(t,r),session:aL(t,"session")??"default",command:a,positionals:[],meta:{tenantId:aL(t,"tenantId")??aL(t,"tenant"),runId:aL(t,"runId"),leaseId:aL(t,"leaseId"),leaseTtlMs:aC(t,"ttlMs"),leaseBackend:aL(t,"backend")}};throw new O("INVALID_ARGS",`Method not found: ${e}`)}(a.method,i,e.headers);if(s=a.method,aS.has(s)&&("string"!=typeof l.command||0===l.command.length))return void ak(n,aM(a.id??null,-32602,"Invalid params: command is required"),400);o=eW(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},ez(o);let d=()=>{n.writableFinished||eJ(o)};e.on("aborted",d),n.on("close",d);let u=await aP(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void ak(n,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void ak(n,{jsonrpc:"2.0",id:a.id??null,result:c});ak(n,aM(a.id??null,-32e3,c.error.message,c.error),aE(c.error.code))}catch(t){let e=E(t);ak(n,aM(a.id??null,-32e3,e.message,e),aE(e.code))}finally{eK(o)}})})}async function a$(e,t,r,a){try{var n;let o,s,l=aO({},e.headers),d=aU(l,a);if(d){t.statusCode=aE(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await aP(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await aA(e),p=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=i.randomUUID(),(s=setTimeout(()=>{aw(o)},3e5)).unref(),am.set(o,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:p}))}catch(r){let e=E(r);t.statusCode=aE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function aF(e,t,r,a){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let i=aO({},e.headers),o=aU(i,a);if(o){t.statusCode=aE(o.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:o.message,code:o.code}));return}let l=await aP(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:i,session:"default",command:"download_artifact",positionals:[n]}});if(!l.ok){t.statusCode=l.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.response.error?.data?.message??l.response.error?.message??"Unauthorized"}));return}let d=function(e,t){let r=ap.get(e);if(!r)throw new O("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new O("UNAUTHORIZED","Artifact belongs to a different tenant");if(!s.existsSync(r.artifactPath))throw af(e),new O("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=s.createReadStream(d.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),d.fileName&&t.setHeader("content-disposition",`attachment; filename="${d.fileName.replace(/"/g,"")}"`),u.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=E(e);t.statusCode=aE(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&af(n)}),u.pipe(t)}catch(r){let e=E(r);t.statusCode=aE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function aU(e,t){return t&&e!==t?E(new O("UNAUTHORIZED","Invalid token")):null}function aG(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function aV(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function aB(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";throw new O("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class aj{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=aB(e.backend),r=q(e.tenantId);if(!r)throw new O("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let a=aG(e.runId);if(!a)throw new O("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,a,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),d={leaseId:i.randomBytes(16).toString("hex"),tenantId:r,runId:a,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(d.leaseId,d),this.runBindings.set(o,d.leaseId),{...d}}heartbeatLease(e){let t=aV(e.leaseId);if(!t)throw new O("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new O("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=aV(e.leaseId);if(!t)throw new O("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=aB(e.backend),r=q(e.tenantId);if(!r)throw new O("INVALID_ARGS","tenant isolation requires tenant id.");let a=aG(e.runId);if(!a)throw new O("INVALID_ARGS","tenant isolation requires run id.");let n=aV(e.leaseId);if(!n)throw new O("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let i=this.leases.get(n);if(!i)throw new O("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(i.backend!==t||i.tenantId!==r||i.runId!==a)throw new O("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new O("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new O("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=q(t),n=aG(r);if(t&&!a)throw new O("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!n)throw new O("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||n&&e.runId!==n)throw new O("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let aq=["emulator","platform-tools",p.join("cmdline-tools","latest","bin"),p.join("cmdline-tools","tools","bin")];function aH(e){let t=new Set,r=[];for(let a of e){let e=a.trim();!e||t.has(e)||(t.add(e),r.push(e))}return r}function aW(e=process.env){let t=e.ANDROID_SDK_ROOT?.trim(),r=e.ANDROID_HOME?.trim(),a=e.HOME?.trim()||u.homedir();return aH([t??"",r??"",a?p.join(a,"Android","Sdk"):""])}async function az(e){try{return await d.access(e,d.constants.X_OK),!0}catch{return!1}}async function aJ(e=process.env){let t,r=[];for(let a of aW(e)){let e=[];for(let t of aq){let r=p.join(a,t);await az(r)&&e.push(r)}0!==e.length&&(t||(t=a),r.push(...e))}if(t&&(e.ANDROID_SDK_ROOT=e.ANDROID_SDK_ROOT?.trim()||t,e.ANDROID_HOME=e.ANDROID_HOME?.trim()||t),0===r.length)return;let a=(e.PATH??"").split(p.delimiter).map(e=>e.trim()).filter(e=>e.length>0);e.PATH=aH([...r,...a]).join(p.delimiter)}function aK(e,t){return["-s",e.id,...t]}async function aX(){if(await aJ(),!await x("adb"))throw new O("TOOL_MISSING","adb not found in PATH")}function aY(e,t){let r=`${e}
12
12
  ${t}`.toLowerCase();return r.includes("no shell command implementation")||r.includes("unknown command")}async function aZ(e){await new Promise(t=>setTimeout(t,e))}function aQ(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let r=/^([A-Za-z][A-Za-z0-9+.-]*):(.+)$/.exec(t);if(!r)return!1;let a=r[1]?.toLowerCase(),n=r[2]??"";return"http"!==a&&"https"!==a&&"ws"!==a&&"wss"!==a&&"ftp"!==a&&"ftps"!==a||n.startsWith("//")}function a0(e,t){let r,a=e?.trim();return a?a:"http"===(r=t.trim().split(":")[0]?.toLowerCase())||"https"===r?"com.apple.mobilesafari":void 0}let a1=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];function a2(e){return`${e.stdout}
13
- ${e.stderr}`}function a3(e,t){return["-s",e,...t]}function a4(e){return e.startsWith("emulator-")}function a5(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function a8(e,t=e$){return $("adb",a3(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function a6(e,t){let r=t.replace(/_/g," ").trim();if(!a4(e))return r||e;let a=await a7(e);return a?a.replace(/_/g," "):r||e}async function a9(e,t,r){try{return await r("adb",a3(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var a;if("COMMAND_FAILED"===(a=j(e)).code&&"number"==typeof a.details?.timeoutMs)return;throw e}}async function a7(e,t=$){for(let r of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let a=await a9(e,["shell","getprop",r],t);if(!a)continue;let n=a.stdout.trim();if(0===a.exitCode&&n.length>0)return n}let r=await a9(e,["emu","avd","name"],t);if(!r)return;let a=function(e){let t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0);if(0!==t.length)return"OK"===t.at(-1)&&t.pop(),t.join("\n").trim()||void 0}(r.stdout);if(0===r.exitCode&&a)return a}async function ne(e,t){let r=a2(await $("adb",a3(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:e$})).toLowerCase();return!!r.includes("true")||!r.includes("false")&&null}async function nt(e){return(await Promise.all(a1.map(async t=>await ne(e,t)))).some(e=>!0===e)}async function nr(e){var t;let r;return"tv"===((r=a2(await $("adb",a3(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:e$})).toLowerCase()).includes("tv")||r.includes("leanback")?"tv":null)||await nt(e)?"tv":(t=a2(await $("adb",a3(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:e$})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function na(e={}){if(await aJ(),!await Y("adb"))throw new W("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??e7(void 0),r=(await nn()).filter(e=>!t||t.has(e.serial));return await Promise.all(r.map(async({serial:e,rawModel:t})=>{let[r,a,n]=await Promise.all([a6(e,t),nl(e),nr(e)]);return{platform:"android",id:e,name:r,kind:a4(e)?"emulator":"device",target:n,booted:a}}))}async function nn(){return(await $("adb",["devices","-l"],{timeoutMs:e$})).stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith("List of devices")).map(e=>e.split(/\s+/)).filter(e=>"device"===e[1]).map(e=>({serial:e[0],rawModel:(e.find(e=>e.startsWith("model:"))??"").replace("model:","")}))}async function ni(){let e=await $("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:e$});if(0!==e.exitCode)throw new W("COMMAND_FAILED","Failed to list Android emulator AVDs",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,hint:"Verify Android emulator tooling is installed and available in PATH."});return e.stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}async function no(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await ns(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await new Promise(e=>setTimeout(e,1e3))}throw new W("COMMAND_FAILED","Android emulator did not appear in time",{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:"Check emulator logs and verify the AVD can start from command line."})}async function ns(e,t){let r=a5(e);for(let e of(await nn()).filter(e=>(!t||e.serial===t)&&a4(e.serial)))if(a5(e.rawModel)===r||a5(await a6(e.serial,e.rawModel))===r)return e.serial}async function nl(e){try{let t=await a8(e);return"1"===t.stdout.trim()}catch{return!1}}async function nd(e){var t,r;let a;await aJ();let n=e.avdName.trim();if(!n)throw new W("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let i=e.timeoutMs??12e4;if(!await Y("adb"))throw new W("TOOL_MISSING","adb not found in PATH");if(!await Y("emulator"))throw new W("TOOL_MISSING","emulator not found in PATH");let o=await ni(),s=function(e,t){let r=e.find(e=>e===t);if(r)return r;let a=a5(t);return e.find(e=>a5(e)===a)}(o,n);if(!s)throw new W("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:n,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let l=Date.now(),d=(t=await na(),r=e.serial,a=a5(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!r||e.id===r)&&a5(e.name)===a));if(!d){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),C("emulator",t)}let u=d??await no({avdName:s,serial:e.serial,timeoutMs:i}),c=Math.max(1e3,i-(Date.now()-l));await nu(u.id,c);let p=(await na()).find(e=>e.id===u.id);return p?{...p,name:s,booted:!0}:{...u,name:s,booted:!0}}async function nu(e,t=6e4){let r,a=eF.fromTimeoutMs(t),n=Math.max(1,Math.ceil(t/1e3)),i=!1;try{await eU(async({deadline:n})=>{if(n?.isExpired())throw i=!0,new W("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),message:"timeout"});let o=Math.max(1e3,n?.remainingMs()??t),s=await a8(e,Math.min(o,e$));if(r=s,"1"!==s.stdout.trim())throw new W("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:n,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=e1({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:a,phase:"boot",classifyReason:e=>e1({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let n=j(c),o=r?.stdout,s=r?.stderr,l=r?.exitCode,d=e1({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===n.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),reason:d,hint:e2(d),stdout:o,stderr:s,exitCode:l};if(i||"ANDROID_BOOT_TIMEOUT"===d)throw new W("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===n.code)throw new W("TOOL_MISSING",n.message,{...u,...n.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new W("COMMAND_FAILED",n.message,{...u,...n.details??{}});throw new W(n.code,n.message,{...u,...n.details??{}},n.cause)}}let nc=/\.(?:apk|aab)$/i,np=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function nf(e){var t,r;let a=e.trim();return 0===a.length?"other":nc.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!np.test(t))?"binary":"package":(r=a,np.test(r))?"package":"other"}function nm(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}let nh=[".zip",".tar",".tar.gz",".tgz"],nw=e0(process.env.AGENT_DEVICE_SOURCE_DOWNLOAD_TIMEOUT_MS,12e4,1e3),ng=["1","true","yes","on"];async function ny(e){let t=[];try{let r=await nv(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(r.cleanup);let a=await nN(r.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,allowArchiveExtraction:!1!==e.allowArchiveExtraction,registerCleanup:e=>{t.push(e)}});return{archivePath:a.archivePath,installablePath:a.installablePath,cleanup:async()=>{await nM(t)}}}catch(e){throw await nM(t),e}}async function nv(e,t){if("path"===e.kind)return{localPath:q(e.path),cleanup:async()=>{}};let r=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-source-"));try{return{localPath:await nI(r,e.url,e.headers,t),cleanup:async()=>{await d.rm(r,{recursive:!0,force:!0})}}}catch(e){throw await d.rm(r,{recursive:!0,force:!0}),e}}async function nI(e,t,r,a){let n;try{n=new URL(t)}catch{throw new W("INVALID_ARGS",`Invalid source URL: ${t}`)}await nb(n);let i=a?.signal;if(i?.aborted)throw new W("COMMAND_FAILED","request canceled",{reason:"request_canceled"});let o=new AbortController,s=()=>{o.abort(i?.reason)};i?.addEventListener("abort",s,{once:!0});let l=a?.downloadTimeoutMs??nw,u=setTimeout(()=>{o.abort(Error("download timeout"))},l);try{let t=await fetch(n,{headers:r,redirect:"follow",signal:o.signal});if(!t.ok)throw new W("COMMAND_FAILED",`Failed to download app source: ${t.status} ${t.statusText}`,{status:t.status,statusText:t.statusText,url:n.toString()});let a=function(e,t){let r=e.headers.get("content-disposition"),a=r?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i),n=a?.[1]?.trim();if(n)return p.basename(n);let i=p.basename(t.pathname);return i||"downloaded-artifact.bin"}(t,n),i=p.join(e,a),s=t.body;if(!s)throw new W("COMMAND_FAILED","Download response body was empty",{url:n.toString()});let l=await d.open(i,"w");try{for await(let e of s)await l.write(e)}finally{await l.close()}return i}catch(e){if(i?.aborted)throw new W("COMMAND_FAILED","request canceled",{reason:"request_canceled"},e);if(o.signal.aborted)throw new W("COMMAND_FAILED",`App source download timed out after ${l}ms`,{timeoutMs:l,url:n.toString()},e);throw e}finally{i?.removeEventListener("abort",s),clearTimeout(u)}}async function nb(e){if("http:"!==e.protocol&&"https:"!==e.protocol)throw new W("INVALID_ARGS",`Unsupported source URL protocol: ${e.protocol}`);if(!ng.includes((process.env.AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS??"").toLowerCase())){var t;if(!(t=e.hostname.toLowerCase())||"localhost"===t||t.endsWith(".localhost")||nS(t))throw new W("INVALID_ARGS",`Source URL host is not allowed: ${e.hostname}`,{hint:"Use a public artifact URL, or set AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS=1 for trusted private-network daemons."});if((await b.lookup(e.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>nS(e.address)))throw new W("INVALID_ARGS",`Source URL host resolved to a private or loopback address: ${e.hostname}`,{hint:"Use a public artifact URL, or set AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS=1 for trusted private-network daemons."})}}function nA(e){var t,r,a,n;let i=e instanceof URL?e:new URL(e),o=i.hostname.toLowerCase();if(!o)return!1;let s=i.pathname;return t=o,r=s,("api.github.com"===t?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(r):"github.com"===t&&/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(r))||(a=o,n=s,("expo.dev"===a||!!a.endsWith(".expo.dev"))&&/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(n))}function nS(e){let t,r=f.isIP(e);return 4===r?function(e){let t=e.split(".").map(e=>Number.parseInt(e,10));if(4!==t.length||t.some(e=>Number.isNaN(e)||e<0||e>255))return!1;let[r,a]=t;return 10===r||127===r||169===r&&254===a||172===r&&!!(a>=16)&&!!(a<=31)||192===r&&168===a}(e):6===r&&!!("::1"===(t=e.toLowerCase())||t.startsWith("fc")||t.startsWith("fd")||t.startsWith("fe80:"))}async function nN(e,t){let r=await d.stat(e).catch(()=>null);if(!r)throw new W("INVALID_ARGS",`App source not found: ${e}`);if(t.isInstallablePath(e,r))return{archivePath:t.archivePath,installablePath:e};if(r.isFile()&&nD(e)){if(!t.allowArchiveExtraction)throw new W("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; archive extraction is not allowed`,{path:e});let r=await nx(e);return t.registerCleanup(r.cleanup),await nN(r.outputPath,{...t,archivePath:t.archivePath??e})}if(r.isDirectory()){let r=await n_(e,t.isInstallablePath);if(1===r.length)return{archivePath:t.archivePath,installablePath:r[0]};if(r.length>1)throw new W("INVALID_ARGS",`Found multiple ${t.installableLabel} candidates under ${e}`,{matches:r});let a=await n_(e,(e,t)=>t.isFile()&&nD(e));if(1===a.length){if(!t.allowArchiveExtraction)throw new W("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; nested archives are not allowed`,{path:a[0]});let e=await nx(a[0]);return t.registerCleanup(e.cleanup),await nN(e.outputPath,{...t,archivePath:t.archivePath??a[0]})}if(a.length>1)throw new W("INVALID_ARGS",`Found multiple nested archives under ${e}; expected one ${t.installableLabel} source`,{matches:a})}throw new W("INVALID_ARGS",`Expected ${t.installableLabel} source, but got ${e}`)}async function n_(e,t){let r=[],a=[{path:e,depth:0}];for(;a.length>0;){let e=a.shift();if(!e)continue;let n=await d.readdir(e.path,{withFileTypes:!0});for(let i of(n.sort((e,t)=>e.name.localeCompare(t.name)),n)){let n=p.join(e.path,i.name);if(t(n,i)){r.push(n);continue}i.isDirectory()&&e.depth<5&&a.push({path:n,depth:e.depth+1})}}return r}async function nx(e){let t=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-archive-"));try{return e.toLowerCase().endsWith(".zip")?await $("ditto",["-x","-k",e,t]):e.toLowerCase().endsWith(".tar.gz")||e.toLowerCase().endsWith(".tgz")?await $("tar",["-xzf",e,"-C",t]):await $("tar",["-xf",e,"-C",t]),{outputPath:t,cleanup:async()=>{await d.rm(t,{recursive:!0,force:!0})}}}catch(e){throw await d.rm(t,{recursive:!0,force:!0}),e}}function nD(e){let t=e.toLowerCase();return nh.some(e=>t.endsWith(e))}async function nM(e){for(let t=e.length-1;t>=0;t-=1)await e[t]()}let nk=new S("utf-16le");async function nE(e){for(let r of["AndroidManifest.xml","base/manifest/AndroidManifest.xml"]){var t;let a=await nO(e,r);if(!a)continue;let n=(t=a).subarray(0,Math.min(t.length,128)).toString("utf8").trimStart().startsWith("<")?function(e){let t=e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i);return t?.[1]}(t.toString("utf8")):function(e){let t;if(!(e.length<8)&&3===e.readUInt16LE(0))for(let r=e.readUInt16LE(2);r+8<=e.length;){let a=e.readUInt16LE(r),n=e.readUInt16LE(r+2),i=e.readUInt32LE(r+4);if(i<=0||r+i>e.length)break;if(1===a)t=function(e){if(e.length<28)return[];let t=e.readUInt32LE(8),r=e.readUInt32LE(16),a=e.readUInt32LE(20),n=(256&r)!=0,i=[];for(let r=0;r<t;r+=1){let t=28+4*r;if(t+4>e.length)break;let o=a+e.readUInt32LE(t);i.push(n?function(e,t){let[,r]=nL(e,t),[a,n]=nL(e,t+r),i=t+r+n;return e.subarray(i,i+a).toString("utf8")}(e,o):function(e,t){let[r,a]=function(e,t){let r=e.readUInt16LE(t);return(32768&r)==0?[r,2]:[(32767&r)<<16|e.readUInt16LE(t+2),4]}(e,t),n=t+a;return nk.decode(e.subarray(n,n+2*r))}(e,o))}return i}(e.subarray(r,r+i));else if(258===a&&t){let a=function(e,t,r,a){if(r<36||t+r>e.length||"manifest"!==a[e.readUInt32LE(t+20)])return;let n=e.readUInt16LE(t+24),i=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+n;for(let t=0;t<o;t+=1){let r=s+t*i;if(r+20>e.length)break;if("package"!==a[e.readUInt32LE(r+4)])continue;let n=e.readUInt32LE(r+8);if(0xffffffff!==n)return a[n];let o=e.readUInt8(r+15),l=e.readUInt32LE(r+16);if(3===o)return a[l];break}}(e,r,n,t);if(a)return a}r+=i}}(t);if(n)return n}return await nC(e)}async function nO(e,t){try{let r=await $("unzip",["-p",e,t],{allowFailure:!0,binaryStdout:!0});if(0!==r.exitCode||!r.stdoutBuffer||0===r.stdoutBuffer.length)return;return r.stdoutBuffer}catch{return}}function nL(e,t){let r=e.readUInt8(t);return(128&r)==0?[r,1]:[(127&r)<<8|e.readUInt8(t+1),2]}async function nC(e){let t=await nP();if(!t)return;let r=await $(t,["dump","badging",e],{allowFailure:!0});if(0!==r.exitCode)return;let a=r.stdout.match(/package:\s+name='([^']+)'/);return a?.[1]}async function nP(){if(void 0!==e)return e??void 0;try{for(let t of aW()){let r=p.join(t,"build-tools");try{for(let t of(await A.readdir(r)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}))){let a=p.join(r,t,"aapt");try{return await A.access(a),e=a,a}catch{}}}catch{}}}catch{}e=null}async function nR(e,t){let r="url"===e.kind&&nA(e.url),a=await ny({source:e,isInstallablePath:(e,t)=>{var r;let a;return t.isFile()&&(r=e,".apk"===(a=p.extname(r).toLowerCase())||".aab"===a)},installableLabel:"Android installable (.apk or .aab)",allowArchiveExtraction:"url"!==e.kind||r,signal:t?.signal}),n=t?.resolveIdentity===!1?{}:await nT(a.installablePath);return{archivePath:a.archivePath,installablePath:a.installablePath,packageName:n.packageName,cleanup:a.cleanup}}async function nT(e){let t=p.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await nE(e)}}let n$={settings:{type:"intent",value:"android.settings.SETTINGS"}},nF="android.intent.category.LAUNCHER",nU="android.intent.category.LEANBACK_LAUNCHER",nG="android.intent.category.DEFAULT",nV="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.";async function nB(e,t){let r=t.trim();if("package"===nf(r))return{type:"package",value:r};let a=n$[r.toLowerCase()];if(a)return a;let n=(await $("adb",aK(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase()));if(1===n.length)return{type:"package",value:n[0]};if(n.length>1)throw new W("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:n,hint:"Run agent-device apps --platform android to see the exact installed package names before retrying open."});throw new W("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:nV})}async function nj(e,t="all"){let r=await nq(e);return("user-installed"===t?(await nW(e)).filter(e=>r.has(e)):Array.from(r)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:nz(e)}))}async function nq(e){let t=new Set;for(let r of nH(e,{includeFallbackWhenUnknown:!0})){let a=await $("adb",aK(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",r]),{allowFailure:!0});if(0===a.exitCode&&0!==a.stdout.trim().length)for(let e of a.stdout.split("\n")){let r=e.trim();if(!r)continue;let a=r.split(/\s+/)[0],n=a.includes("/")?a.split("/")[0]:a;n&&t.add(n)}}return t}function nH(e,t={}){return"tv"===e.target?[nU]:"mobile"===e.target?[nF]:t.includeFallbackWhenUnknown?[nF,nU]:[nF]}async function nW(e){return(await $("adb",aK(e,["shell","pm","list","packages","-3"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean)}function nz(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),r=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),a=r[r.length-1]??e;for(let e=r.length-1;e>=0;e-=1){let n=r[e];if(!t.has(n)){a=n;break}}return a.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function nJ(e){let t=await nK(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let r=await nK(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return r||{}}async function nK(e,t){for(let r of t){let t=function(e){for(let t of[/mCurrentFocus=Window\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mFocusedApp=AppWindowToken\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/,/ResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/]){let r=t.exec(e);if(r)return{package:r[1],activity:r[2]}}return null}((await $("adb",aK(e,r),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function nX(e,t,r){var a,n;let i;e.booted||await nu(e.id);let o=t.trim();if(aQ(o)){if(r)throw new W("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await $("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await nB(e,t),l=nH(e)[0]??nF;if("intent"===s.type){if(r)throw new W("INVALID_ARGS","Activity override requires a package name, not an intent");await $("adb",aK(e,["shell","am","start","-W","-a",s.value]));return}if(r){let t=r.includes("/")?r:`${s.value}/${r.startsWith(".")?r:`.${r}`}`;try{await $("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",nG,"-c",l,"-n",t]))}catch(t){throw await nQ(e,s.value,t),t}return}let d=await $("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",nG,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,n=d.stderr,i=`${a}
14
- ${n}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(i)))return;let u=await n1(e,s.value);if(!u){if(!await nZ(e,s.value))throw nY(s.value);throw new W("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:d.stdout,stderr:d.stderr})}await $("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",nG,"-c",l,"-n",u]))}function nY(e){return new W("APP_NOT_INSTALLED",`No package found matching "${e}"`,{package:e,hint:nV})}async function nZ(e,t){let r=await $("adb",aK(e,["shell","pm","path",t]),{allowFailure:!0}),a=`${r.stdout}
15
- ${r.stderr}`;return!!(0===r.exitCode&&/\bpackage:/i.test(a))||(n0(a),!1)}async function nQ(e,t,r){if(n0(r instanceof W?`${String(r.details?.stdout??"")}
16
- ${String(r.details?.stderr??"")}`:"")||!await nZ(e,t))throw nY(t)}function n0(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function n1(e,t){for(let r of Array.from(new Set(nH(e,{includeFallbackWhenUnknown:!0})))){let a=await $("adb",aK(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",r,t]),{allowFailure:!0});if(0!==a.exitCode)continue;let n=function(e){let t=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e-=1){let r=t[e];if(r.includes("/"))return r.split(/\s+/)[0]}return null}(a.stdout);if(n)return n}return null}async function n2(e){e.booted||await nu(e.id)}async function n3(e,t){if("settings"===t.trim().toLowerCase())return void await $("adb",aK(e,["shell","am","force-stop","com.android.settings"]));let r=await nB(e,t);if("intent"===r.type)throw new W("INVALID_ARGS","Close requires a package name, not an intent");await $("adb",aK(e,["shell","am","force-stop",r.value]))}async function n4(e,t){let r=await nB(e,t);if("intent"===r.type)throw new W("INVALID_ARGS","App uninstall requires a package name, not an intent");let a=await $("adb",aK(e,["uninstall",r.value]),{allowFailure:!0});if(0!==a.exitCode){let e=`${a.stdout}
17
- ${a.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new W("COMMAND_FAILED",`adb uninstall failed for ${r.value}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return{package:r.value}}let n5=null;async function n8(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(n5?.key===e)return n5.invocation;if(await Y("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return n5={key:e,invocation:t},t}let t=process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim();if(!t)throw new W("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");try{await d.access(t)}catch{throw new W("TOOL_MISSING",`AGENT_DEVICE_BUNDLETOOL_JAR points to a missing file: ${t}`)}let r={cmd:"java",prefixArgs:["-jar",t]};return n5={key:e,invocation:r},r}async function n6(e){let t=await n8();await $(t.cmd,[...t.prefixArgs,...e])}async function n9(e,t){let r,a=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-aab-")),n=p.join(a,"bundle.apks"),i=(r=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&r.length>0?r:"universal";try{await n6(["build-apks","--bundle",t,"--output",n,"--mode",i]),await n6(["install-apks","--apks",n,"--device-id",e.id])}finally{await d.rm(a,{recursive:!0,force:!0})}}async function n7(e,t){".aab"===p.extname(t).toLowerCase()?await n9(e,t):await $("adb",aK(e,["install","-r",t]))}async function ie(e){return new Set((await $("adb",aK(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function it(e,t){let r=Array.from(await ie(e)).filter(e=>!t.has(e));if(1===r.length)return r[0]}async function ir(e,t){e.booted||await nu(e.id),await n7(e,t)}async function ia(e,t,r){let a=r?void 0:await ie(e);return await ir(e,t),r??(a?await it(e,a):void 0)}async function ii(e,t){e.booted||await nu(e.id);let r=await nR({kind:"path",path:t});try{let t=await ia(e,r.installablePath,r.packageName),a=t?nz(t):void 0;return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:t,appName:a,launchTarget:t}}finally{await r.cleanup()}}async function io(e,t,r){e.booted||await nu(e.id);let{package:a}=await n4(e,t),n=await nR({kind:"path",path:r},{resolveIdentity:!1});try{return await ir(e,n.installablePath),{package:a}}finally{await n.cleanup()}}function is(e){let t=e.direction,r="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,a=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new W("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),n=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new W("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(r*a),i=Math.max(1,Math.round(.05*r)),o=Math.max(1,Math.min(n,Math.max(1,r-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),d=Math.round(e.referenceHeight/2),u=(r,a,n,i)=>({direction:t,x1:r,y1:a,x2:n,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return u(l,d-s,l,d+s);case"down":return u(l,d+s,l,d-s);case"left":return u(l-s,d,l+s,d);case"right":return u(l+s,d,l-s,d)}}function il(e,t){let r=t.toLowerCase(),a=/<node[^>]+>/g,n=a.exec(e);for(;n;){let t=ic(n[0]),i=(ip(t,"text")??"").toLowerCase(),o=(ip(t,"content-desc")??"").toLowerCase();if(i.includes(r)||o.includes(r)){let e=im(ip(t,"bounds"));if(e)return{x:Math.floor(e.x+e.width/2),y:Math.floor(e.y+e.height/2)};return{x:0,y:0}}n=a.exec(e)}return null}function id(e,t,r){let a=function(e){let t=0,r=0,a=[...e.children];for(;a.length>0;){let e=a.pop();t+=1,r=Math.max(r,e.depth),a.push(...e.children)}return{rawNodeCount:t,maxDepth:r}}(e),n=[],i=[],o=!1,s=r.depth??1/0,l=r.scope?function(e,t){let r=t.toLowerCase(),a=[...e.children],n=0;for(;n<a.length;){let e=a[n++],t=e.label?.toLowerCase()??"",i=e.value?.toLowerCase()??"",o=e.identifier?.toLowerCase()??"";if(t.includes(r)||i.includes(r)||o.includes(r))return e;a.push(...e.children)}return null}(e,r.scope):null,d=l?[l]:e.children,u=new Map,c=e=>{let t=u.get(e);if(void 0!==t)return t;for(let t of e.children)if(t.hittable||c(t))return u.set(e,!0),!0;return u.set(e,!1),!1},p=(e,a,l,d=!1,u=!1)=>{if(n.length>=t){o=!0;return}if(a>s)return;let f=!!r.raw||function(e,t,r,a,n){var i;let o,s=iw(e.type),l=!!(e.label&&e.label.trim().length>0),d=!!(e.identifier&&e.identifier.trim().length>0),u=l&&!ig(e.label??""),c=d&&!ig(e.identifier??""),p=(o=(i=s).split(".").pop()??i).includes("layout")||"viewgroup"===o||"view"===o,f="imageview"===s||"imagebutton"===s;if(t.interactiveOnly)return!!(e.hittable||G(s)&&a)||!!(u||c)&&!f&&(!p||!!n)&&(r||a||n);return t.compact?u||c||!!e.hittable:!p&&!f||!!e.hittable||!!u||!!c&&!!a||a}(e,r,d,c(e),u),m=l;f&&(m=n.length,i.push(e),n.push({index:m,type:e.type??void 0,label:e.label??void 0,value:e.value??void 0,identifier:e.identifier??void 0,rect:e.rect,enabled:e.enabled,hittable:e.hittable,depth:a,parentIndex:l,...e.hiddenContentAbove?{hiddenContentAbove:!0}:{},...e.hiddenContentBelow?{hiddenContentBelow:!0}:{}}));let h=d||!!e.hittable,w=u||function(e){if(!e)return!1;let t=iw(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(e.type);for(let t of e.children)if(p(t,a+1,m,h,w),o)return};for(let e of d)if(p(e,0,void 0,!1,!1),o)break;return o?{nodes:n,sourceNodes:i,truncated:o,analysis:a}:{nodes:n,sourceNodes:i,analysis:a}}function iu(e){let t=ic(e),r=e=>{let r=ip(t,e);if(null!==r)return"true"===r};return{text:ip(t,"text"),desc:ip(t,"content-desc"),resourceId:ip(t,"resource-id"),className:ip(t,"class"),bounds:ip(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused")}}function ic(e){let t=new Map,r=e.indexOf(" "),a=e.lastIndexOf(">");if(r<0||a<=r)return t;let n=/([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/y,i=r;for(;i<a;){for(;i<a;){let t=e[i];if(" "!==t&&"\n"!==t&&"\r"!==t&&" "!==t)break;i+=1}if(i>=a)break;let r=e[i];if("/"===r||">"===r)break;n.lastIndex=i;let o=n.exec(e);if(!o)break;t.set(o[1],o[3]),i=n.lastIndex}return t}function ip(e,t){return e.get(t)??null}function im(e){if(!e)return;let t=/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),a=Number(t[2]);return{x:r,y:a,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-a)}}function ih(e){let t={type:null,label:null,value:null,identifier:null,depth:-1,children:[]},r=[t],a=/<node\b[^>]*>|<\/node>/g,n=a.exec(e);for(;n;){let t=n[0];if(t.startsWith("</node")){r.length>1&&r.pop(),n=a.exec(e);continue}let i=iu(t),o=im(i.bounds),s=r[r.length-1],l={type:i.className,label:i.text||i.desc,value:i.text,identifier:i.resourceId,rect:o,enabled:i.enabled,hittable:i.clickable??i.focusable,depth:s.depth+1,parentIndex:void 0,children:[]};s.children.push(l),t.endsWith("/>")||r.push(l),n=a.exec(e)}return t}function iw(e){return e?e.toLowerCase():""}function ig(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}function iy(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function iv(e,t){let r=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),a=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=r&&Math.abs(e.crossSize-t.crossSize)<=a}function iI(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function ib(e,t={}){let r=await iS(e);if(!t.interactiveOnly){let a=function(e,t){let{sourceNodes:r,...a}=id(ih(e),800,t);return a}(r,t);return await iA(e,a.nodes),a}let a=ih(r),n=id(a,800,{...t,interactiveOnly:!1});await iA(e,n.nodes),function(e){if(0===e.length||e.some(e=>e.hiddenContentAbove||e.hiddenContentBelow))return;let t=new Map(Q(e_(e)).nodes.filter(e=>e.hiddenContentAbove||e.hiddenContentBelow).map(e=>[e.index,e]));for(let r of e){let e=t.get(r.index);e&&(e.hiddenContentAbove&&(r.hiddenContentAbove=!0),e.hiddenContentBelow&&(r.hiddenContentBelow=!0))}}(n.nodes),function(e){for(let[t,r]of e.sourceNodes.entries()){let a=e.nodes[t];a&&(a.hiddenContentAbove&&(r.hiddenContentAbove=!0),a.hiddenContentBelow&&(r.hiddenContentBelow=!0))}}(n);let{sourceNodes:i,...o}=id(a,800,t);return o}async function iA(e,t){if(!t.some(e=>G(e.type)))return;let r=await iD(e);r&&function(e,t){let r=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},r=[{indent:-1,node:t}],a=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=a.exec(t);if(!e)continue;let n=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),d={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;r.length>1&&n<=r[r.length-1].indent;)r.pop();r[r.length-1].node.children.push(d),r.push({indent:n,node:d})}return t.children.length>0?t:null}(t);if(!r)return;let a=function(e){let t=[],r=[e];for(;r.length>0;){let e=r.pop();if(G(e.className)){let r=function(e){let t=e.children[0];if(!t)return null;let r=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),a=t.children.filter(e=>e.rect.height>0).map(t=>iI(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===a.length?null:{rect:e.rect,contentExtent:r,contentBlocks:a}}(e);r&&t.push(r)}r.push(...e.children)}return t}(r);if(0!==a.length)for(let t of e){if(!t.rect||!G(t.type))continue;let r=function(e,t){let r=null,a=1/0;for(let n of t){let t=Math.abs(n.rect.width-e.width)+Math.abs(n.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(n.rect.x-e.x)+Math.abs(n.rect.y-e.y));i<a&&(r=n,a=i)}return r}(t.rect,a);if(!r)continue;let n=function(e,t){let r=function(e,t){let r=t,a=new Set;for(;!a.has(r.index);){var n,i;a.add(r.index);let o=e.filter(e=>e.parentIndex===r.index&&e.rect);if(1!==o.length)return r;let s=o[0];if(n=s.rect,i=t.rect,n.x!==i.x||n.y!==i.y||n.width!==i.width||n.height!==i.height)return r;r=s}return t}(e,t);return e.filter(e=>e.parentIndex===r.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>iI(e,t.rect))}(e,t),i=function(e){let{viewportRect:t,visibleBlocks:r,nativeScrollView:a}=e;if(0===r.length||0===a.contentBlocks.length)return null;let n=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],r=e.contentBlocks[e.contentBlocks.length-1];if(!t||!r)return null;let a=iy(e.contentBlocks.map(e=>e.size))??e.rect.height,n=Math.max(48,Math.round(.5*a)),i=Math.max(24,Math.round(.25*a)),o=t.start>=n,s=e.contentExtent-(r.start+r.size)>=i;return o||s?{above:o,below:s}:null}(a),i=function(e,t){let r=new Map;for(let a of e)for(let e of t){if(!iv(a,e))continue;let t=a.start-e.start,n=8*Math.round(t/8),i=r.get(n)??[];i.push(t),r.set(n,i)}let a=null;for(let e of r.values())(!a||e.length>a.length)&&(a=e);if(!a||a.length<2)return null;let n=[...a].sort((e,t)=>e-t);return n[Math.floor(n.length/2)]??null}(a.contentBlocks,r)??function(e){let{nativeBlocks:t,visibleBlocks:r,viewportExtent:a,contentExtent:n}=e,i=[],o=[];for(let e of t)for(let t of r){if(!iv(e,t))continue;let r=e.start-t.start;16>=Math.abs(r)&&i.push(r),16>=Math.abs(r+a-n)&&o.push(r)}return o.length>0?iy(o):i.length>0?iy(i):null}({nativeBlocks:a.contentBlocks,visibleBlocks:r,viewportExtent:t.height,contentExtent:a.contentExtent});if(null===i)return n;let o=t.height;return{above:(n?.above??!1)||i>16,below:(n?.below??!1)||i+o<a.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:n,nativeScrollView:r});i&&(i.above&&(t.hiddenContentAbove=!0),i.below&&(t.hiddenContentBelow=!0))}}(t,r)}async function iS(e){return eG(()=>iN(e),{shouldRetry:ix})}async function iN(e){var t,r,a;let n,i,o=await $("adb",aK(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0}),s=i_(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await $("adb",aK(e,["shell","uiautomator","dump",l]),{allowFailure:!0}),u=(t=l,r=d.stdout,a=d.stderr,n=`${r}
18
- ${a}`,i=/dumped to:\s*(\S+)/i.exec(n),i?.[1]??t),c=await $("adb",aK(e,["shell","cat",u])),p=i_(c.stdout,c.stderr);if(!p)throw new W("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function i_(e,t){let r=`${e}
19
- ${t}`,a=r.indexOf("<?xml"),n=a>=0?a:r.indexOf("<hierarchy");if(n<0)return null;let i=r.lastIndexOf("</hierarchy>");if(i<0||i<n)return null;let o=r.slice(n,i+12).trim();return o.length>0?o:null}function ix(e){if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.details?.stderr??""}`.toLowerCase();return!!(t.includes("device offline")||t.includes("device not found")||t.includes("transport error")||t.includes("connection reset")||t.includes("broken pipe")||t.includes("timed out")||t.includes("no such file or directory"))}async function iD(e){try{let t=await $("adb",aK(e,["shell","dumpsys","activity","top"]),{allowFailure:!0,timeoutMs:8e3}),r=`${t.stdout}
20
- ${t.stderr}`.trim();return r.length>0?r:null}catch{return null}}async function iM(e,t,r){await $("adb",aK(e,["shell","input","tap",String(t),String(r)]))}async function ik(e,t,r,a,n,i=250){await $("adb",aK(e,["shell","input","swipe",String(t),String(r),String(a),String(n),String(i)]))}async function iE(e){await $("adb",aK(e,["shell","input","keyevent","4"]))}async function iO(e){await $("adb",aK(e,["shell","input","keyevent","3"]))}async function iL(e,t){let r=function(e){switch(e){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new W("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await $("adb",aK(e,["shell","settings","put","system","accelerometer_rotation","0"])),await $("adb",aK(e,["shell","settings","put","system","user_rotation",r]))}async function iC(e){await $("adb",aK(e,["shell","input","keyevent","187"]))}async function iP(e,t,r,a=800){await $("adb",aK(e,["shell","input","swipe",String(t),String(r),String(t),String(r),String(a)]))}async function iR(e,t,r=0){r>0&&Array.from(t).length>1?await iq(e,t,1,r):await iT(e,t)}async function iT(e,t){let r=iH(t);if(!r||"ok"!==await iW(e,t))try{let r=t.replace(/ /g,"%s");await $("adb",aK(e,["shell","input","text",r]))}catch(e){if(r&&function(e){if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return!!(t.includes("exception occurred while executing 'text'")||t.includes("nullpointerexception")&&t.includes("inputshellcommand.sendtext"))}(e))throw new W("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function i$(e,t,r){await iM(e,t,r)}async function iF(e,t,r,a,n=0){let i=Array.from(a).length,o=iH(a),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&n<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||n>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var d,u;await i$(e,t,r);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await iz(e,s),"input_text"===o.strategy)await iR(e,a,n);else if("clipboard_paste"===o.strategy){if("ok"!==await iW(e,a))continue}else await iq(e,a,1,n>0?n:15);let c=await iU(e,t,r,a);if(l=c.actual,c.ok)return}throw new W("COMMAND_FAILED","Android fill verification failed",{expected:a,actual:l??null})}async function iU(e,t,r,a){let n=null;for(let i of[0,150,350])if(i>0&&await aZ(i),function(e,t){if(e===t)return!0;let r=iG(e),a=iG(t);return!!r&&!!a&&(!!(r===a||r.includes(a))||a.includes(r)&&r.length>=Math.max(4,Math.floor(.8*a.length)))}(n=await iJ(e,t,r),a))return{ok:!0,actual:n};return{ok:!1,actual:n}}function iG(e){return(e??"").replace(/\s+/g," ").trim()}async function iV(e,t,r){let a=await ij(e),n=is({direction:t,amount:r?.amount,pixels:r?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await $("adb",aK(e,["shell","input","swipe",String(n.x1),String(n.y1),String(n.x2),String(n.y2),"300"])),n}async function iB(e,t,r){let a=r?.maxScrolls??8,n="";try{n=await iS(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new W("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(il(n,t))return{attempts:0};for(let r=1;r<=a;r+=1){await iV(e,"down",{amount:.5});let a="";try{a=await iS(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new W("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(il(a,t))return{attempts:r};if(a===n)throw new W("COMMAND_FAILED",`scrollintoview could not find text: ${t}`,{reason:"not_found",attempts:r,stalled:!0});n=a}throw new W("COMMAND_FAILED",`scrollintoview could not find text: ${t}`,{reason:"not_found",attempts:a})}async function ij(e){let t=(await $("adb",aK(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new W("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function iq(e,t,r,a){let n=Math.max(1,Math.floor(r)),i=Array.from(t);for(let t=0;t<i.length;t+=n){let r=i.slice(t,t+n).join("");await iT(e,r),a>0&&t+n<i.length&&await aZ(a)}}function iH(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&(e<32||e>126))return!0}return!1}async function iW(e,t){let r=await $("adb",aK(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==r.exitCode?"failed":aY(r.stdout,r.stderr)?"unsupported":0===(await $("adb",aK(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await $("adb",aK(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function iz(e,t){let r=Math.max(0,t);await $("adb",aK(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<r;t+=24){let a=Math.min(24,r-t);await $("adb",aK(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function iJ(e,t,r){let a,n=await iS(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=i.exec(n));){let e=iu(a[0]),n=im(e.bounds);if(!n)continue;let i=e.className??"",d=(e.text??"").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,n.width*n.height),p=t>=n.x&&t<=n.x+n.width&&r>=n.y&&r<=n.y+n.height;if(u&&iK(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&iK(i)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function iK(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function iX(e){let t=await $("adb",aK(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new W("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let r of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=r[1],a=r[2]?.toLowerCase();e&&("true"===a||"false"===a)&&t.set(e,"true"===a)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),r=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(r=(1&e)!=0)}}let a=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),n=a.length>0?a[a.length-1]?.[1]:void 0,i=n?`0x${n.toLowerCase()}`:void 0;return{visible:r,inputType:i,type:i?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let r=15&t;if(2===r)return"number";if(3===r)return"phone";if(4===r)return"datetime";if(1!==r)return"unknown";let a=4080&t;return 32===a||208===a?"email":128===a||224===a||144===a?"password":"text"}(i):void 0}}(t.stdout)}async function iY(e){let t=await iX(e),r=t,a=0;for(;r.visible&&a<2;)await $("adb",aK(e,["shell","input","keyevent","111"])),a+=1,await aZ(120),r=await iX(e);if(t.visible&&r.visible)throw new W("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:a,inputType:r.inputType,type:r.type});return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type}}async function iZ(e){let t,r;return(r=(t=(await i0(e,["shell","cmd","clipboard","get","text"],"read")).replace(/\r\n/g,"\n").replace(/\n$/,"")).match(/^clipboard text:\s*(.*)$/i))?r[1]??"":"null"===t.trim().toLowerCase()?"":t}async function iQ(e,t){await i0(e,["shell","cmd","clipboard","set","text",t],"write")}async function i0(e,t,r){let a=await $("adb",aK(e,t),{allowFailure:!0});if(aY(a.stdout,a.stderr))throw new W("UNSUPPORTED_OPERATION",`Android shell clipboard ${r} is not supported on this device.`);if(0!==a.exitCode)throw new W("COMMAND_FAILED",`Failed to ${r} Android clipboard text`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return a.stdout}let i1=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function i2(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new W("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function i3(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new W("INVALID_ARGS",`permission setting requires a target: ${i1.join("|")}`)}function i4(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new W("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}async function i5(e,t,r,a,n){switch(t.toLowerCase()){case"wifi":{let t=i6(r);await $("adb",aK(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=i6(r);await $("adb",aK(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await $("adb",aK(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=i6(r);await $("adb",aK(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"appearance":{let t=await i9(e,r);await $("adb",aK(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]));return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new W("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await i8(e,t);return}case"permission":{if(!a)throw new W("INVALID_ARGS","permission setting requires an active app in session");let t=i2(r),i=function(e,t){let r=i3(e);if(t?.trim())throw new W("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===r)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===r)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===r)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===r)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new W("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(n?.permissionTarget,n?.permissionMode);if("notifications"===i.kind)return void await oe(e,a,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await i7(e,a,o);await $("adb",aK(e,["shell","pm",o,a,i.value]));return}default:throw new W("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function i8(e,t){var r;let a,n,i=(r=e,n=[["shell","cmd","fingerprint","touch",a="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",a]],"emulator"===r.kind&&n.push(["emu","finger","touch",a]),n),o=[];for(let t of i){let r=await $("adb",aK(e,t),{allowFailure:!0});if(0===r.exitCode)return;o.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,r;let a;return t=e.stdout,r=e.stderr,(a=`${t}
21
- ${r}`.toLowerCase()).includes("unknown command")||a.includes("can't find service: fingerprint")||a.includes("service fingerprint was not found")||a.includes("fingerprint cmd unavailable")||a.includes("emu command is not supported")||a.includes("emulator console is not running")||a.includes("fingerprint")&&a.includes("not found")}))throw new W("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new W("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function i6(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new W("INVALID_ARGS",`Invalid setting state: ${e}`)}async function i9(e,t){let r=i4(t);if("toggle"!==r)return r;let a=await $("adb",aK(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==a.exitCode)throw new W("COMMAND_FAILED","Failed to read current Android appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let n=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
22
- ${t}`);if(!r)return null;let a=r[1].toLowerCase();return"yes"===a?"dark":"no"===a?"light":"auto"===a?"auto":null}(a.stdout,a.stderr);if(!n)throw new W("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"auto"===n?"dark":"dark"===n?"light":"dark"}async function i7(e,t,r){let a=await ot(e),n=[];for(let i of null!==a&&a>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let a=await $("adb",aK(e,["shell","pm",r,t,i]),{allowFailure:!0});if(0===a.exitCode)return;n.push({permission:i,stderr:a.stderr,exitCode:a.exitCode})}throw new W("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:a,attempts:n})}async function oe(e,t,r,a){"grant"===r?await $("adb",aK(e,["shell","pm","grant",t,a.permission]),{allowFailure:!0}):(await $("adb",aK(e,["shell","pm","revoke",t,a.permission]),{allowFailure:!0}),"reset"===r&&(await $("adb",aK(e,["shell","pm","clear-permission-flags",t,a.permission,"user-set"]),{allowFailure:!0}),await $("adb",aK(e,["shell","pm","clear-permission-flags",t,a.permission,"user-fixed"]),{allowFailure:!0}))),await $("adb",aK(e,["shell","appops","set",t,a.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"]))}async function ot(e){let t=await $("adb",aK(e,["shell","getprop","ro.build.version.sdk"]),{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}async function or(e,t,r){let a="string"==typeof r.action&&r.action.trim()?r.action.trim():`${t}.TEST_PUSH`,n=["shell","am","broadcast","-a",a,"-p",t],i="string"==typeof r.receiver?r.receiver.trim():"";i&&n.push("-n",i);let o=r.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new W("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,r){if("string"==typeof r)return e.push("--es",t,r);if("boolean"==typeof r)return e.push("--ez",t,r?"true":"false");if("number"==typeof r&&Number.isFinite(r))return Number.isInteger(r)?e.push("--ei",t,String(r)):e.push("--ef",t,String(r));throw new W("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(n,e,t),s+=1);return await $("adb",aK(e,n)),{action:a,extrasCount:s}}let oa=Buffer.from([137,80,78,71,13,10,26,10]);async function on(e,t){await oi(e);try{await aZ(1e3),await os(e,t)}finally{await oo(e).catch(()=>{})}}async function oi(e){let t=t=>$("adb",aK(e,["shell",t]),{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let r=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await r("clock -e hhmm 0941"),await r("notifications -e visible false")}async function oo(e){await $("adb",aK(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function os(e,t){let r=await $("adb",aK(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!r.stdoutBuffer)throw new W("COMMAND_FAILED","Failed to capture screenshot");let a=r.stdoutBuffer.indexOf(oa);if(a<0)throw new W("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let n=function(e,t){let r=t+oa.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),a=r+4,n=e.toString("ascii",a,a+4),i=r+12+t;if(i>e.length)break;if("IEND"===n)return i;r=i}return null}(r.stdoutBuffer,a);if(!n)throw new W("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await d.writeFile(t,r.stdoutBuffer.subarray(a,n))}let ol=e0(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,eT,5e3),od=e0(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,eR,1e3),ou=e0(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),oc=e0(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),op=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),of=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),om=e0(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),oh=eP(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function ow(e,t){let r=["devicectl",...e],a=await $("xcrun",r,{allowFailure:!0,timeoutMs:oc});if(0===a.exitCode)return;let n=String(a.stdout??""),i=String(a.stderr??"");throw new W("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:r,exitCode:a.exitCode,stdout:n,stderr:i,deviceId:t.deviceId,hint:oI(n,i)??ov})}async function og(e,t){let r=p.join(u.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",r],n=await $("xcrun",a,{allowFailure:!0,timeoutMs:oc});try{var i,o;if(0!==n.exitCode){let t=String(n.stdout??""),r=String(n.stderr??"");throw new W("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:a,exitCode:n.exitCode,stdout:t,stderr:r,deviceId:e.id,hint:oI(t,r)??ov})}let s=await d.readFile(r,"utf8");return i=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let a="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,n="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;r.push({bundleId:t,name:a,url:n})}return r}(JSON.parse(s)),o=t,"user-installed"===o?i.filter(e=>!e.bundleId.startsWith("com.apple.")):i}catch(t){if(t instanceof W)throw t;throw new W("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await d.unlink(r).catch(()=>{})}}async function oy(e){let t=p.join(u.tmpdir(),`agent-device-ios-processes-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=["devicectl","device","info","processes","--device",e.id,"--json-output",t],a=await $("xcrun",r,{allowFailure:!0,timeoutMs:oc});try{if(0!==a.exitCode){let t=String(a.stdout??""),n=String(a.stderr??"");throw new W("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:r,exitCode:a.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:oI(t,n)??ov})}let n=await d.readFile(t,"utf8");return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",a="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(a)&&r.push({executable:t,pid:a})}return r}(JSON.parse(n))}catch(t){if(t instanceof W)throw t;throw new W("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await d.unlink(t).catch(()=>{})}}let ov="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function oI(e,t){let r=`${e}
23
- ${t}`.toLowerCase();return r.includes("device is busy")&&r.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":r.includes("coredeviceservice")&&r.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function ob(e){if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let r=String(t.stderr??"").toLowerCase();return r.includes("fbsopenapplicationserviceerrordomain")&&r.includes("the request to open")}async function oA(e,t){let r=await $("xcrun",tt(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==r.exitCode)return{installed:!1};let a=r.stdout.trim();if(!a)return{installed:!1};let n=await $("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==n.exitCode||!n.stdout.trim())return{installed:!0};let i=n.stdout.trim(),o=`${a}/${i}`,s=await $("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function oS(e,t){if("simulator"!==e.kind)throw new W("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function oN(){await $("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:op})}async function o_(e){let t,r;if("simulator"!==e.kind||"Booted"===await oD(e))return;let a=eF.fromTimeoutMs(ol);try{await eU(async({deadline:a})=>{if(a?.isExpired())throw new W("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:ol});let n=Math.max(1e3,a?.remainingMs()??ol),i=await $("xcrun",tt(e,["boot",e.id]),{allowFailure:!0,timeoutMs:n});t={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let o=`${t.stdout}
24
- ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new W("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await $("xcrun",tt(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:n});if(r={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==r.exitCode)throw new W("COMMAND_FAILED","simctl bootstatus failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let d=await oD(e);if("Booted"!==d)throw new W("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let a=e1({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==a&&"CI_RESOURCE_STARVATION_SUSPECTED"!==a}},{deadline:a,phase:"boot",classifyReason:e=>e1({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let n=e1({error:i,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new W("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:ol,elapsedMs:a.elapsedMs(),reason:n,hint:e2(n),boot:t,bootstatus:r})}await oN()}async function ox(e){let t=tt(e,["shutdown",e.id]),r=await $("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===r.exitCode,exitCode:r.exitCode,stdout:String(r.stdout??""),stderr:String(r.stderr??"")}}async function oD(e){let t="string"==typeof e?e:e.id,r="string"==typeof e?te(["list","devices","-j"]):tt(e,["list","devices","-j"]),a=await $("xcrun",r,{allowFailure:!0,timeoutMs:od});if(0!==a.exitCode)return null;try{let e=JSON.parse(String(a.stdout??""));for(let r of Object.values(e.devices??{})){let e=r.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function oM(e,t){try{let r=await $("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===r.exitCode){let e=String(r.stdout??"").trim();if(e.length>0)return e}}catch{}try{var r,a;let n;return r=await d.readFile(e,"utf8"),a=t,tL(tO(r),(e,t)=>{void 0===n&&e===a&&"string"===t.name&&(n=t.text??void 0)}),n}catch{return}}async function ok(e,t){if("url"===e.kind&&!nA(e.url))throw new W("INVALID_ARGS","iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.");let r=await ny({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||nA(e.url),signal:t?.signal}),a=await oO(r.installablePath,t),n=await oE(a.installPath);return{archivePath:r.archivePath??(r.installablePath.toLowerCase().endsWith(".ipa")?r.installablePath:void 0),installablePath:a.installPath,bundleId:n.bundleId,appName:n.appName,cleanup:async()=>{await a.cleanup(),await r.cleanup()}}}async function oE(e){let t=p.join(e,"Info.plist"),[r,a,n]=await Promise.all([oM(t,"CFBundleIdentifier"),oM(t,"CFBundleDisplayName"),oM(t,"CFBundleName")]);return{bundleId:r,appName:a??n}}async function oO(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let r=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-ios-ipa-")),a=async()=>{await d.rm(r,{recursive:!0,force:!0})};try{await $("ditto",["-x","-k",e,r]);let n=p.join(r,"Payload"),i=(await d.readdir(n,{withFileTypes:!0}).catch(()=>{throw new W("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:p.join(n,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===i.length)return{installPath:i[0].installPath,cleanup:a};if(0===i.length)throw new W("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await oL(i);let o=t?.appIdentifierHint?.trim();if(o){let e=function(e,t){let r=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===r);if(1===a.length)return a[0];if(a.length>1)throw new W("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===r);if(1===t.length)return t[0]}}(i,o);if(e)return{installPath:e.installPath,cleanup:a};throw new W("INVALID_ARGS",`Invalid IPA: found ${i.length} .app bundles under Payload and none matched "${o}". Available bundles: ${i.map(oC).join(", ")}`)}throw new W("INVALID_ARGS",`Invalid IPA: found ${i.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${i.map(oC).join(", ")}`)}catch(e){throw await a(),e}}async function oL(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await oE(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function oC(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function oP(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let oR="agent-device-macos-helper",oT="AGENT_DEVICE_MACOS_HELPER_BIN",o$=p.join(u.homedir(),".agent-device","macos-helper","current"),oF=p.join(o$,"manifest.json"),oU=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function oG(e){let t=e.trim();if(!oU.test(t))throw new W("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function oV(){return function(e){let t=p.dirname(e);for(;;){let e=p.join(t,"macos-helper");if(l(p.join(e,"Package.swift")))return e;let r=p.dirname(t);if(r===t)break;t=r}throw new W("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(w(import.meta.url))}async function oB(e){let t=await d.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let r=p.join(e,t.name);return t.isDirectory()?".build"===t.name?[]:await oB(r):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[r]:[]}))).flat().sort()}async function oj(e){let t=await oB(e),r=o("sha256");for(let a of t)r.update(p.relative(e,a)),r.update("\0"),r.update(await d.readFile(a)),r.update("\0");let a=await $("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return r.update("swift-version"),r.update("\0"),r.update(a.stdout||a.stderr||`exit:${a.exitCode}`),r.update("\0"),r.digest("hex")}async function oq(){try{let e=JSON.parse(await d.readFile(oF,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function oH(){let e=process.env[oT]?.trim();if(e)return e;let t=oV(),r=await oj(t),a=p.join(o$,oR);try{if(await oq()===r)return await d.access(a),a}catch{}let n=p.join(oV(),".build","release",oR);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await $("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await d.mkdir(o$,{recursive:!0});let i=`${a}.tmp`;return await d.copyFile(n,i),await d.rename(i,a),await d.chmod(a,493),await d.writeFile(oF,`${JSON.stringify({fingerprint:r},null,2)}
25
- `,"utf8"),a}async function oW(e){let t=process.env[oT]?.trim();if("darwin"!==process.platform&&!t)throw new W("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");let r=await oH(),a=await $(r,e,{allowFailure:!0,timeoutMs:3e4}),n=a.stdout.trim(),i=null;if(n)try{i=JSON.parse(n)}catch{i=null}if(0===a.exitCode&&i?.ok)return i.data;throw new W("COMMAND_FAILED",i&&!i.ok?i.error?.message??`macOS helper exited with code ${a.exitCode}`:n||a.stderr.trim()||`macOS helper exited with code ${a.exitCode}`,{helperPath:r,args:e,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,...i&&!i.ok?i.error?.details:{}})}async function oz(){return await oW(["app","frontmost"])}async function oJ(e){return await oW(["app","quit","--bundle-id",oG(e)])}async function oK(e,t){return await oW(["permission",e,t])}async function oX(e,t={}){let r=["alert",e];return t.bundleId&&r.push("--bundle-id",oG(t.bundleId)),t.surface&&r.push("--surface",t.surface),await oW(r)}async function oY(e,t={}){let r=["snapshot","--surface",e];return t.bundleId&&r.push("--bundle-id",oG(t.bundleId)),await oW(r)}async function oZ(e,t,r={}){let a=["read","--x",String(e),"--y",String(t)];return r.bundleId&&a.push("--bundle-id",oG(r.bundleId)),r.surface&&a.push("--surface",r.surface),await oW(a)}async function oQ(e,t,r={}){let a=["press","--x",String(e),"--y",String(t)];return r.bundleId&&a.push("--bundle-id",oG(r.bundleId)),r.surface&&a.push("--surface",r.surface),await oW(a)}async function o0(e,t={}){let r=["screenshot","--out",e];return t.surface&&r.push("--surface",t.surface),t.fullscreen&&r.push("--fullscreen"),await oW(r)}let o1={settings:"com.apple.systempreferences"},o2=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;function o3(e,t){let r=["-b",e];return t&&r.push(t),r}async function o4(e){for(let t of[p.join(e,"Contents","Info.plist"),p.join(e,"Info.plist")]){let[e,r,a]=await Promise.all([oM(t,"CFBundleIdentifier"),oM(t,"CFBundleDisplayName"),oM(t,"CFBundleName")]);if(e||r||a)return{bundleId:e,appName:r??a}}return{}}async function o5(e){let t=e.trim(),r=o1[t.toLowerCase()];if(r)return r;if(o2.test(t))return t;let a=(await sr("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===a.length)return a[0].bundleId;if(a.length>1)throw new W("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:a});throw new W("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function o8(e,t,r){let a=r?.url?.trim();if(a){if(!aQ(a))throw new W("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=r?.appBundleId??await o5(t);await $("open",o3(e,a));return}let n=t.trim();if(aQ(n))return void await $("open",[n]);let i=r?.appBundleId??await o5(n);await $("open",o3(i))}async function o6(e,t){let r=await o5(t),a=await oJ(r);if(a.running&&!a.terminated&&!a.forceTerminated)throw new W("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:r,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function o9(){let e=await $("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new W("COMMAND_FAILED","Failed to read macOS clipboard",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});return e.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function o7(e){let t=await $("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new W("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function se(){let e=await $("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new W("COMMAND_FAILED","Failed to read macOS appearance",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});let t=e.stdout.trim().toLowerCase();if("true"===t)return!0;if("false"===t)return!1;throw new W("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function st(e){let t=i4(e),r="toggle"===t?!await se():"dark"===t,a=`tell application "System Events" to tell appearance preferences to set dark mode to ${r?"true":"false"}`,n=await $("osascript",["-e",a],{allowFailure:!0});if(0!==n.exitCode)throw new W("COMMAND_FAILED","Failed to set macOS appearance",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}async function sr(e="all"){let t=["/Applications","/System/Applications",p.join(u.homedir(),"Applications")],r=new Set;for(let e of t){let t=await d.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let a=await $("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===a.exitCode)for(let e of a.stdout.split("\n")){let t=e.trim();t&&r.add(t)}}return oP((await Promise.all(Array.from(r).map(async e=>{let t=await o4(e).catch(()=>({})),r=t.bundleId;return r?{bundleId:r,name:t.appName??p.basename(e,".app")}:null}))).filter(e=>null!==e).sort((e,t)=>e.name.localeCompare(t.name)),e)}let sa=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],sn={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},si={1:"searching",2:"failed",3:"active"},so={0:"notSupported",1:"searching",2:"failed",3:"active"};function ss(e,t,r){return $("xcrun",tt(e,t),r)}async function sl(e,t){var r,a;let n;await su(e),t&&await sc(e,(n=[],(r=t).dataNetwork&&n.push("--dataNetwork",r.dataNetwork),r.wifiMode&&n.push("--wifiMode",r.wifiMode),void 0!==r.wifiBars&&("wifi"===r.dataNetwork||r.wifiMode)&&n.push("--wifiBars",r.wifiBars),r.cellularMode&&n.push("--cellularMode",r.cellularMode),void 0!==r.cellularBars&&(r.cellularMode||(a=r.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==r.operatorName)&&n.push("--cellularBars",r.cellularBars),void 0!==r.operatorName&&n.push("--operatorName",r.operatorName),n))}async function sd(e){let t=await ss(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new W("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let r of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(r);if(e){let r=Number(e[1]),a=sn[r];if(!a)throw new W("COMMAND_FAILED",`Unsupported simulator data network type: ${r}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(r);if(a){let e=si[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let n=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(r);if(n){let e=Number(n[1]),r=so[e];if(!r)throw new W("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=r,t.cellularBars=n[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(r);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function su(e){await ss(e,["status_bar",e.id,"clear"])}async function sc(e,t){0!==t.length&&await ss(e,["status_bar",e.id,"override",...t])}function sp(e,t,r){ep({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof W))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:r}}(r)}})}function sf(e,t,r){return $("xcrun",tt(e,t),r)}let sm={ensureBooted:o_,prepareStatusBarForScreenshot:async function e(e){let t=null,r=!1;try{t=await sd(e),r=!0}catch(t){sp(e,"snapshot_failed",t)}try{await su(e),await sc(e,sa)}catch(t){sp(e,"prepare_failed",t)}return async()=>{await sl(e,r?t:null)}},captureWithRetry:sg,runnerFallbackEnabled:oh,captureWithRunner:sy,shouldFallbackToRunner:s_};async function sh(e,t,r,a){if("macos"===e.platform)return void await sy(e,t,r,a);if("simulator"===e.kind)return void await sw(e,t,r,a);try{await ow(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",n=`${e.message}
13
+ ${e.stderr}`}function a3(e,t){return["-s",e,...t]}function a4(e){return e.startsWith("emulator-")}function a5(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function a8(e,t=e$){return F("adb",a3(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function a6(e,t){let r=t.replace(/_/g," ").trim();if(!a4(e))return r||e;let a=await a7(e);return a?a.replace(/_/g," "):r||e}async function a9(e,t,r){try{return await r("adb",a3(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var a;if("COMMAND_FAILED"===(a=k(e)).code&&"number"==typeof a.details?.timeoutMs)return;throw e}}async function a7(e,t=F){for(let r of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let a=await a9(e,["shell","getprop",r],t);if(!a)continue;let n=a.stdout.trim();if(0===a.exitCode&&n.length>0)return n}let r=await a9(e,["emu","avd","name"],t);if(!r)return;let a=function(e){let t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0);if(0!==t.length)return"OK"===t.at(-1)&&t.pop(),t.join("\n").trim()||void 0}(r.stdout);if(0===r.exitCode&&a)return a}async function ne(e,t){let r=a2(await F("adb",a3(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:e$})).toLowerCase();return!!r.includes("true")||!r.includes("false")&&null}async function nt(e){return(await Promise.all(a1.map(async t=>await ne(e,t)))).some(e=>!0===e)}async function nr(e){var t;let r;return"tv"===((r=a2(await F("adb",a3(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:e$})).toLowerCase()).includes("tv")||r.includes("leanback")?"tv":null)||await nt(e)?"tv":(t=a2(await F("adb",a3(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:e$})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function na(e={}){if(await aJ(),!await x("adb"))throw new O("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??e7(void 0),r=(await nn()).filter(e=>!t||t.has(e.serial));return await Promise.all(r.map(async({serial:e,rawModel:t})=>{let[r,a,n]=await Promise.all([a6(e,t),nl(e),nr(e)]);return{platform:"android",id:e,name:r,kind:a4(e)?"emulator":"device",target:n,booted:a}}))}async function nn(){return(await F("adb",["devices","-l"],{timeoutMs:e$})).stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith("List of devices")).map(e=>e.split(/\s+/)).filter(e=>"device"===e[1]).map(e=>({serial:e[0],rawModel:(e.find(e=>e.startsWith("model:"))??"").replace("model:","")}))}async function ni(){let e=await F("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:e$});if(0!==e.exitCode)throw new O("COMMAND_FAILED","Failed to list Android emulator AVDs",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,hint:"Verify Android emulator tooling is installed and available in PATH."});return e.stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}async function no(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await ns(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await new Promise(e=>setTimeout(e,1e3))}throw new O("COMMAND_FAILED","Android emulator did not appear in time",{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:"Check emulator logs and verify the AVD can start from command line."})}async function ns(e,t){let r=a5(e);for(let e of(await nn()).filter(e=>(!t||e.serial===t)&&a4(e.serial)))if(a5(e.rawModel)===r||a5(await a6(e.serial,e.rawModel))===r)return e.serial}async function nl(e){try{let t=await a8(e);return"1"===t.stdout.trim()}catch{return!1}}async function nd(e){var t,r;let a;await aJ();let n=e.avdName.trim();if(!n)throw new O("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let i=e.timeoutMs??12e4;if(!await x("adb"))throw new O("TOOL_MISSING","adb not found in PATH");if(!await x("emulator"))throw new O("TOOL_MISSING","emulator not found in PATH");let o=await ni(),s=function(e,t){let r=e.find(e=>e===t);if(r)return r;let a=a5(t);return e.find(e=>a5(e)===a)}(o,n);if(!s)throw new O("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:n,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let l=Date.now(),d=(t=await na(),r=e.serial,a=a5(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!r||e.id===r)&&a5(e.name)===a));if(!d){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),D("emulator",t)}let u=d??await no({avdName:s,serial:e.serial,timeoutMs:i}),c=Math.max(1e3,i-(Date.now()-l));await nu(u.id,c);let p=(await na()).find(e=>e.id===u.id);return p?{...p,name:s,booted:!0}:{...u,name:s,booted:!0}}async function nu(e,t=6e4){let r,a=eF.fromTimeoutMs(t),n=Math.max(1,Math.ceil(t/1e3)),i=!1;try{await eU(async({deadline:n})=>{if(n?.isExpired())throw i=!0,new O("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),message:"timeout"});let o=Math.max(1e3,n?.remainingMs()??t),s=await a8(e,Math.min(o,e$));if(r=s,"1"!==s.stdout.trim())throw new O("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:n,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=e1({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:a,phase:"boot",classifyReason:e=>e1({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let n=k(c),o=r?.stdout,s=r?.stderr,l=r?.exitCode,d=e1({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===n.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),reason:d,hint:e2(d),stdout:o,stderr:s,exitCode:l};if(i||"ANDROID_BOOT_TIMEOUT"===d)throw new O("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===n.code)throw new O("TOOL_MISSING",n.message,{...u,...n.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new O("COMMAND_FAILED",n.message,{...u,...n.details??{}});throw new O(n.code,n.message,{...u,...n.details??{}},n.cause)}}let nc=/\.(?:apk|aab)$/i,np=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function nf(e){var t,r;let a=e.trim();return 0===a.length?"other":nc.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!np.test(t))?"binary":"package":(r=a,np.test(r))?"package":"other"}function nm(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}let nh=[".zip",".tar",".tar.gz",".tgz"],nw=e0(process.env.AGENT_DEVICE_SOURCE_DOWNLOAD_TIMEOUT_MS,12e4,1e3),ng=["1","true","yes","on"];async function ny(e){let t=[];try{let r=await nv(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(r.cleanup);let a=await nN(r.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,allowArchiveExtraction:!1!==e.allowArchiveExtraction,registerCleanup:e=>{t.push(e)}});return{archivePath:a.archivePath,installablePath:a.installablePath,cleanup:async()=>{await nM(t)}}}catch(e){throw await nM(t),e}}async function nv(e,t){if("path"===e.kind)return{localPath:Q(e.path),cleanup:async()=>{}};let r=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-source-"));try{return{localPath:await nI(r,e.url,e.headers,t),cleanup:async()=>{await d.rm(r,{recursive:!0,force:!0})}}}catch(e){throw await d.rm(r,{recursive:!0,force:!0}),e}}async function nI(e,t,r,a){let n;try{n=new URL(t)}catch{throw new O("INVALID_ARGS",`Invalid source URL: ${t}`)}await nb(n);let i=a?.signal;if(i?.aborted)throw new O("COMMAND_FAILED","request canceled",{reason:"request_canceled"});let o=new AbortController,s=()=>{o.abort(i?.reason)};i?.addEventListener("abort",s,{once:!0});let l=a?.downloadTimeoutMs??nw,u=setTimeout(()=>{o.abort(Error("download timeout"))},l);try{let t=await fetch(n,{headers:r,redirect:"follow",signal:o.signal});if(!t.ok)throw new O("COMMAND_FAILED",`Failed to download app source: ${t.status} ${t.statusText}`,{status:t.status,statusText:t.statusText,url:n.toString()});let a=function(e,t){let r=e.headers.get("content-disposition"),a=r?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i),n=a?.[1]?.trim();if(n)return p.basename(n);let i=p.basename(t.pathname);return i||"downloaded-artifact.bin"}(t,n),i=p.join(e,a),s=t.body;if(!s)throw new O("COMMAND_FAILED","Download response body was empty",{url:n.toString()});let l=await d.open(i,"w");try{for await(let e of s)await l.write(e)}finally{await l.close()}return i}catch(e){if(i?.aborted)throw new O("COMMAND_FAILED","request canceled",{reason:"request_canceled"},e);if(o.signal.aborted)throw new O("COMMAND_FAILED",`App source download timed out after ${l}ms`,{timeoutMs:l,url:n.toString()},e);throw e}finally{i?.removeEventListener("abort",s),clearTimeout(u)}}async function nb(e){if("http:"!==e.protocol&&"https:"!==e.protocol)throw new O("INVALID_ARGS",`Unsupported source URL protocol: ${e.protocol}`);if(!ng.includes((process.env.AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS??"").toLowerCase())){var t;if(!(t=e.hostname.toLowerCase())||"localhost"===t||t.endsWith(".localhost")||nS(t))throw new O("INVALID_ARGS",`Source URL host is not allowed: ${e.hostname}`,{hint:"Use a public artifact URL, or set AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS=1 for trusted private-network daemons."});if((await b.lookup(e.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>nS(e.address)))throw new O("INVALID_ARGS",`Source URL host resolved to a private or loopback address: ${e.hostname}`,{hint:"Use a public artifact URL, or set AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS=1 for trusted private-network daemons."})}}function nA(e){var t,r,a,n;let i=e instanceof URL?e:new URL(e),o=i.hostname.toLowerCase();if(!o)return!1;let s=i.pathname;return t=o,r=s,("api.github.com"===t?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(r):"github.com"===t&&/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(r))||(a=o,n=s,("expo.dev"===a||!!a.endsWith(".expo.dev"))&&/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(n))}function nS(e){let t,r=f.isIP(e);return 4===r?function(e){let t=e.split(".").map(e=>Number.parseInt(e,10));if(4!==t.length||t.some(e=>Number.isNaN(e)||e<0||e>255))return!1;let[r,a]=t;return 10===r||127===r||169===r&&254===a||172===r&&!!(a>=16)&&!!(a<=31)||192===r&&168===a}(e):6===r&&!!("::1"===(t=e.toLowerCase())||t.startsWith("fc")||t.startsWith("fd")||t.startsWith("fe80:"))}async function nN(e,t){let r=await d.stat(e).catch(()=>null);if(!r)throw new O("INVALID_ARGS",`App source not found: ${e}`);if(t.isInstallablePath(e,r))return{archivePath:t.archivePath,installablePath:e};if(r.isFile()&&nD(e)){if(!t.allowArchiveExtraction)throw new O("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; archive extraction is not allowed`,{path:e});let r=await nx(e);return t.registerCleanup(r.cleanup),await nN(r.outputPath,{...t,archivePath:t.archivePath??e})}if(r.isDirectory()){let r=await n_(e,t.isInstallablePath);if(1===r.length)return{archivePath:t.archivePath,installablePath:r[0]};if(r.length>1)throw new O("INVALID_ARGS",`Found multiple ${t.installableLabel} candidates under ${e}`,{matches:r});let a=await n_(e,(e,t)=>t.isFile()&&nD(e));if(1===a.length){if(!t.allowArchiveExtraction)throw new O("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; nested archives are not allowed`,{path:a[0]});let e=await nx(a[0]);return t.registerCleanup(e.cleanup),await nN(e.outputPath,{...t,archivePath:t.archivePath??a[0]})}if(a.length>1)throw new O("INVALID_ARGS",`Found multiple nested archives under ${e}; expected one ${t.installableLabel} source`,{matches:a})}throw new O("INVALID_ARGS",`Expected ${t.installableLabel} source, but got ${e}`)}async function n_(e,t){let r=[],a=[{path:e,depth:0}];for(;a.length>0;){let e=a.shift();if(!e)continue;let n=await d.readdir(e.path,{withFileTypes:!0});for(let i of(n.sort((e,t)=>e.name.localeCompare(t.name)),n)){let n=p.join(e.path,i.name);if(t(n,i)){r.push(n);continue}i.isDirectory()&&e.depth<5&&a.push({path:n,depth:e.depth+1})}}return r}async function nx(e){let t=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-archive-"));try{return e.toLowerCase().endsWith(".zip")?await F("ditto",["-x","-k",e,t]):e.toLowerCase().endsWith(".tar.gz")||e.toLowerCase().endsWith(".tgz")?await F("tar",["-xzf",e,"-C",t]):await F("tar",["-xf",e,"-C",t]),{outputPath:t,cleanup:async()=>{await d.rm(t,{recursive:!0,force:!0})}}}catch(e){throw await d.rm(t,{recursive:!0,force:!0}),e}}function nD(e){let t=e.toLowerCase();return nh.some(e=>t.endsWith(e))}async function nM(e){for(let t=e.length-1;t>=0;t-=1)await e[t]()}let nk=new S("utf-16le");async function nE(e){for(let r of["AndroidManifest.xml","base/manifest/AndroidManifest.xml"]){var t;let a=await nO(e,r);if(!a)continue;let n=(t=a).subarray(0,Math.min(t.length,128)).toString("utf8").trimStart().startsWith("<")?function(e){let t=e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i);return t?.[1]}(t.toString("utf8")):function(e){let t;if(!(e.length<8)&&3===e.readUInt16LE(0))for(let r=e.readUInt16LE(2);r+8<=e.length;){let a=e.readUInt16LE(r),n=e.readUInt16LE(r+2),i=e.readUInt32LE(r+4);if(i<=0||r+i>e.length)break;if(1===a)t=function(e){if(e.length<28)return[];let t=e.readUInt32LE(8),r=e.readUInt32LE(16),a=e.readUInt32LE(20),n=(256&r)!=0,i=[];for(let r=0;r<t;r+=1){let t=28+4*r;if(t+4>e.length)break;let o=a+e.readUInt32LE(t);i.push(n?function(e,t){let[,r]=nL(e,t),[a,n]=nL(e,t+r),i=t+r+n;return e.subarray(i,i+a).toString("utf8")}(e,o):function(e,t){let[r,a]=function(e,t){let r=e.readUInt16LE(t);return(32768&r)==0?[r,2]:[(32767&r)<<16|e.readUInt16LE(t+2),4]}(e,t),n=t+a;return nk.decode(e.subarray(n,n+2*r))}(e,o))}return i}(e.subarray(r,r+i));else if(258===a&&t){let a=function(e,t,r,a){if(r<36||t+r>e.length||"manifest"!==a[e.readUInt32LE(t+20)])return;let n=e.readUInt16LE(t+24),i=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+n;for(let t=0;t<o;t+=1){let r=s+t*i;if(r+20>e.length)break;if("package"!==a[e.readUInt32LE(r+4)])continue;let n=e.readUInt32LE(r+8);if(0xffffffff!==n)return a[n];let o=e.readUInt8(r+15),l=e.readUInt32LE(r+16);if(3===o)return a[l];break}}(e,r,n,t);if(a)return a}r+=i}}(t);if(n)return n}return await nC(e)}async function nO(e,t){try{let r=await F("unzip",["-p",e,t],{allowFailure:!0,binaryStdout:!0});if(0!==r.exitCode||!r.stdoutBuffer||0===r.stdoutBuffer.length)return;return r.stdoutBuffer}catch{return}}function nL(e,t){let r=e.readUInt8(t);return(128&r)==0?[r,1]:[(127&r)<<8|e.readUInt8(t+1),2]}async function nC(e){let t=await nP();if(!t)return;let r=await F(t,["dump","badging",e],{allowFailure:!0});if(0!==r.exitCode)return;let a=r.stdout.match(/package:\s+name='([^']+)'/);return a?.[1]}async function nP(){if(void 0!==e)return e??void 0;try{for(let t of aW()){let r=p.join(t,"build-tools");try{for(let t of(await A.readdir(r)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}))){let a=p.join(r,t,"aapt");try{return await A.access(a),e=a,a}catch{}}}catch{}}}catch{}e=null}async function nR(e,t){let r="url"===e.kind&&nA(e.url),a=await ny({source:e,isInstallablePath:(e,t)=>{var r;let a;return t.isFile()&&(r=e,".apk"===(a=p.extname(r).toLowerCase())||".aab"===a)},installableLabel:"Android installable (.apk or .aab)",allowArchiveExtraction:"url"!==e.kind||r,signal:t?.signal}),n=t?.resolveIdentity===!1?{}:await nT(a.installablePath);return{archivePath:a.archivePath,installablePath:a.installablePath,packageName:n.packageName,cleanup:a.cleanup}}async function nT(e){let t=p.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await nE(e)}}let n$={settings:{type:"intent",value:"android.settings.SETTINGS"}},nF="android.intent.category.LAUNCHER",nU="android.intent.category.LEANBACK_LAUNCHER",nG="android.intent.category.DEFAULT",nV="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.";async function nB(e,t){let r=t.trim();if("package"===nf(r))return{type:"package",value:r};let a=n$[r.toLowerCase()];if(a)return a;let n=(await F("adb",aK(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase()));if(1===n.length)return{type:"package",value:n[0]};if(n.length>1)throw new O("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:n,hint:"Run agent-device apps --platform android to see the exact installed package names before retrying open."});throw new O("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:nV})}async function nj(e,t="all"){let r=await nq(e);return("user-installed"===t?(await nW(e)).filter(e=>r.has(e)):Array.from(r)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:nz(e)}))}async function nq(e){let t=new Set;for(let r of nH(e,{includeFallbackWhenUnknown:!0})){let a=await F("adb",aK(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",r]),{allowFailure:!0});if(0===a.exitCode&&0!==a.stdout.trim().length)for(let e of a.stdout.split("\n")){let r=e.trim();if(!r)continue;let a=r.split(/\s+/)[0],n=a.includes("/")?a.split("/")[0]:a;n&&t.add(n)}}return t}function nH(e,t={}){return"tv"===e.target?[nU]:"mobile"===e.target?[nF]:t.includeFallbackWhenUnknown?[nF,nU]:[nF]}async function nW(e){return(await F("adb",aK(e,["shell","pm","list","packages","-3"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean)}function nz(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),r=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),a=r[r.length-1]??e;for(let e=r.length-1;e>=0;e-=1){let n=r[e];if(!t.has(n)){a=n;break}}return a.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function nJ(e){let t=await nK(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let r=await nK(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return r||{}}async function nK(e,t){for(let r of t){let t=function(e){for(let t of[/mCurrentFocus=Window\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mFocusedApp=AppWindowToken\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/,/ResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/]){let r=t.exec(e);if(r)return{package:r[1],activity:r[2]}}return null}((await F("adb",aK(e,r),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function nX(e,t,r){var a,n;let i;e.booted||await nu(e.id);let o=t.trim();if(aQ(o)){if(r)throw new O("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await F("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await nB(e,t),l=nH(e)[0]??nF;if("intent"===s.type){if(r)throw new O("INVALID_ARGS","Activity override requires a package name, not an intent");await F("adb",aK(e,["shell","am","start","-W","-a",s.value]));return}if(r){let t=r.includes("/")?r:`${s.value}/${r.startsWith(".")?r:`.${r}`}`;try{await F("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",nG,"-c",l,"-n",t]))}catch(t){throw await nQ(e,s.value,t),t}return}let d=await F("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",nG,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,n=d.stderr,i=`${a}
14
+ ${n}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(i)))return;let u=await n1(e,s.value);if(!u){if(!await nZ(e,s.value))throw nY(s.value);throw new O("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:d.stdout,stderr:d.stderr})}await F("adb",aK(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",nG,"-c",l,"-n",u]))}function nY(e){return new O("APP_NOT_INSTALLED",`No package found matching "${e}"`,{package:e,hint:nV})}async function nZ(e,t){let r=await F("adb",aK(e,["shell","pm","path",t]),{allowFailure:!0}),a=`${r.stdout}
15
+ ${r.stderr}`;return!!(0===r.exitCode&&/\bpackage:/i.test(a))||(n0(a),!1)}async function nQ(e,t,r){if(n0(r instanceof O?`${String(r.details?.stdout??"")}
16
+ ${String(r.details?.stderr??"")}`:"")||!await nZ(e,t))throw nY(t)}function n0(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function n1(e,t){for(let r of Array.from(new Set(nH(e,{includeFallbackWhenUnknown:!0})))){let a=await F("adb",aK(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",r,t]),{allowFailure:!0});if(0!==a.exitCode)continue;let n=function(e){let t=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e-=1){let r=t[e];if(r.includes("/"))return r.split(/\s+/)[0]}return null}(a.stdout);if(n)return n}return null}async function n2(e){e.booted||await nu(e.id)}async function n3(e,t){if("settings"===t.trim().toLowerCase())return void await F("adb",aK(e,["shell","am","force-stop","com.android.settings"]));let r=await nB(e,t);if("intent"===r.type)throw new O("INVALID_ARGS","Close requires a package name, not an intent");await F("adb",aK(e,["shell","am","force-stop",r.value]))}async function n4(e,t){let r=await nB(e,t);if("intent"===r.type)throw new O("INVALID_ARGS","App uninstall requires a package name, not an intent");let a=await F("adb",aK(e,["uninstall",r.value]),{allowFailure:!0});if(0!==a.exitCode){let e=`${a.stdout}
17
+ ${a.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new O("COMMAND_FAILED",`adb uninstall failed for ${r.value}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return{package:r.value}}let n5=null;async function n8(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(n5?.key===e)return n5.invocation;if(await x("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return n5={key:e,invocation:t},t}let t=process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim();if(!t)throw new O("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");try{await d.access(t)}catch{throw new O("TOOL_MISSING",`AGENT_DEVICE_BUNDLETOOL_JAR points to a missing file: ${t}`)}let r={cmd:"java",prefixArgs:["-jar",t]};return n5={key:e,invocation:r},r}async function n6(e){let t=await n8();await F(t.cmd,[...t.prefixArgs,...e])}async function n9(e,t){let r,a=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-aab-")),n=p.join(a,"bundle.apks"),i=(r=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&r.length>0?r:"universal";try{await n6(["build-apks","--bundle",t,"--output",n,"--mode",i]),await n6(["install-apks","--apks",n,"--device-id",e.id])}finally{await d.rm(a,{recursive:!0,force:!0})}}async function n7(e,t){".aab"===p.extname(t).toLowerCase()?await n9(e,t):await F("adb",aK(e,["install","-r",t]))}async function ie(e){return new Set((await F("adb",aK(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function it(e,t){let r=Array.from(await ie(e)).filter(e=>!t.has(e));if(1===r.length)return r[0]}async function ir(e,t){e.booted||await nu(e.id),await n7(e,t)}async function ia(e,t,r){let a=r?void 0:await ie(e);return await ir(e,t),r??(a?await it(e,a):void 0)}async function ii(e,t){e.booted||await nu(e.id);let r=await nR({kind:"path",path:t});try{let t=await ia(e,r.installablePath,r.packageName),a=t?nz(t):void 0;return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:t,appName:a,launchTarget:t}}finally{await r.cleanup()}}async function io(e,t,r){e.booted||await nu(e.id);let{package:a}=await n4(e,t),n=await nR({kind:"path",path:r},{resolveIdentity:!1});try{return await ir(e,n.installablePath),{package:a}}finally{await n.cleanup()}}function is(e){let t=e.direction,r="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,a=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new O("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),n=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new O("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(r*a),i=Math.max(1,Math.round(.05*r)),o=Math.max(1,Math.min(n,Math.max(1,r-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),d=Math.round(e.referenceHeight/2),u=(r,a,n,i)=>({direction:t,x1:r,y1:a,x2:n,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return u(l,d-s,l,d+s);case"down":return u(l,d+s,l,d-s);case"left":return u(l-s,d,l+s,d);case"right":return u(l+s,d,l-s,d)}}function il(e,t){let r=t.toLowerCase(),a=/<node[^>]+>/g,n=a.exec(e);for(;n;){let t=ic(n[0]),i=(ip(t,"text")??"").toLowerCase(),o=(ip(t,"content-desc")??"").toLowerCase();if(i.includes(r)||o.includes(r)){let e=im(ip(t,"bounds"));if(e)return{x:Math.floor(e.x+e.width/2),y:Math.floor(e.y+e.height/2)};return{x:0,y:0}}n=a.exec(e)}return null}function id(e,t,r){let a=function(e){let t=0,r=0,a=[...e.children];for(;a.length>0;){let e=a.pop();t+=1,r=Math.max(r,e.depth),a.push(...e.children)}return{rawNodeCount:t,maxDepth:r}}(e),n=[],i=[],o=!1,s=r.depth??1/0,l=r.scope?function(e,t){let r=t.toLowerCase(),a=[...e.children],n=0;for(;n<a.length;){let e=a[n++],t=e.label?.toLowerCase()??"",i=e.value?.toLowerCase()??"",o=e.identifier?.toLowerCase()??"";if(t.includes(r)||i.includes(r)||o.includes(r))return e;a.push(...e.children)}return null}(e,r.scope):null,d=l?[l]:e.children,u=new Map,c=e=>{let t=u.get(e);if(void 0!==t)return t;for(let t of e.children)if(t.hittable||c(t))return u.set(e,!0),!0;return u.set(e,!1),!1},p=(e,a,l,d=!1,u=!1)=>{if(n.length>=t){o=!0;return}if(a>s)return;let f=!!r.raw||function(e,t,r,a,n){var i;let o,s=iw(e.type),l=!!(e.label&&e.label.trim().length>0),d=!!(e.identifier&&e.identifier.trim().length>0),u=l&&!ig(e.label??""),c=d&&!ig(e.identifier??""),p=(o=(i=s).split(".").pop()??i).includes("layout")||"viewgroup"===o||"view"===o,f="imageview"===s||"imagebutton"===s;if(t.interactiveOnly)return!!(e.hittable||X(s)&&a)||!!(u||c)&&!f&&(!p||!!n)&&(r||a||n);return t.compact?u||c||!!e.hittable:!p&&!f||!!e.hittable||!!u||!!c&&!!a||a}(e,r,d,c(e),u),m=l;f&&(m=n.length,i.push(e),n.push({index:m,type:e.type??void 0,label:e.label??void 0,value:e.value??void 0,identifier:e.identifier??void 0,rect:e.rect,enabled:e.enabled,hittable:e.hittable,depth:a,parentIndex:l,...e.hiddenContentAbove?{hiddenContentAbove:!0}:{},...e.hiddenContentBelow?{hiddenContentBelow:!0}:{}}));let h=d||!!e.hittable,w=u||function(e){if(!e)return!1;let t=iw(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(e.type);for(let t of e.children)if(p(t,a+1,m,h,w),o)return};for(let e of d)if(p(e,0,void 0,!1,!1),o)break;return o?{nodes:n,sourceNodes:i,truncated:o,analysis:a}:{nodes:n,sourceNodes:i,analysis:a}}function iu(e){let t=ic(e),r=e=>{let r=ip(t,e);if(null!==r)return"true"===r};return{text:ip(t,"text"),desc:ip(t,"content-desc"),resourceId:ip(t,"resource-id"),className:ip(t,"class"),bounds:ip(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused")}}function ic(e){let t=new Map,r=e.indexOf(" "),a=e.lastIndexOf(">");if(r<0||a<=r)return t;let n=/([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/y,i=r;for(;i<a;){for(;i<a;){let t=e[i];if(" "!==t&&"\n"!==t&&"\r"!==t&&" "!==t)break;i+=1}if(i>=a)break;let r=e[i];if("/"===r||">"===r)break;n.lastIndex=i;let o=n.exec(e);if(!o)break;t.set(o[1],o[3]),i=n.lastIndex}return t}function ip(e,t){return e.get(t)??null}function im(e){if(!e)return;let t=/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),a=Number(t[2]);return{x:r,y:a,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-a)}}function ih(e){let t={type:null,label:null,value:null,identifier:null,depth:-1,children:[]},r=[t],a=/<node\b[^>]*>|<\/node>/g,n=a.exec(e);for(;n;){let t=n[0];if(t.startsWith("</node")){r.length>1&&r.pop(),n=a.exec(e);continue}let i=iu(t),o=im(i.bounds),s=r[r.length-1],l={type:i.className,label:i.text||i.desc,value:i.text,identifier:i.resourceId,rect:o,enabled:i.enabled,hittable:i.clickable??i.focusable,depth:s.depth+1,parentIndex:void 0,children:[]};s.children.push(l),t.endsWith("/>")||r.push(l),n=a.exec(e)}return t}function iw(e){return e?e.toLowerCase():""}function ig(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}function iy(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function iv(e,t){let r=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),a=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=r&&Math.abs(e.crossSize-t.crossSize)<=a}function iI(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function ib(e,t={}){let r=await iS(e);if(!t.interactiveOnly){let a=function(e,t){let{sourceNodes:r,...a}=id(ih(e),800,t);return a}(r,t);return await iA(e,a.nodes),a}let a=ih(r),n=id(a,800,{...t,interactiveOnly:!1});await iA(e,n.nodes),function(e){if(0===e.length||e.some(e=>e.hiddenContentAbove||e.hiddenContentBelow))return;let t=new Map(ei(e_(e)).nodes.filter(e=>e.hiddenContentAbove||e.hiddenContentBelow).map(e=>[e.index,e]));for(let r of e){let e=t.get(r.index);e&&(e.hiddenContentAbove&&(r.hiddenContentAbove=!0),e.hiddenContentBelow&&(r.hiddenContentBelow=!0))}}(n.nodes),function(e){for(let[t,r]of e.sourceNodes.entries()){let a=e.nodes[t];a&&(a.hiddenContentAbove&&(r.hiddenContentAbove=!0),a.hiddenContentBelow&&(r.hiddenContentBelow=!0))}}(n);let{sourceNodes:i,...o}=id(a,800,t);return o}async function iA(e,t){if(!t.some(e=>X(e.type)))return;let r=await iD(e);r&&function(e,t){let r=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},r=[{indent:-1,node:t}],a=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=a.exec(t);if(!e)continue;let n=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),d={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;r.length>1&&n<=r[r.length-1].indent;)r.pop();r[r.length-1].node.children.push(d),r.push({indent:n,node:d})}return t.children.length>0?t:null}(t);if(!r)return;let a=function(e){let t=[],r=[e];for(;r.length>0;){let e=r.pop();if(X(e.className)){let r=function(e){let t=e.children[0];if(!t)return null;let r=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),a=t.children.filter(e=>e.rect.height>0).map(t=>iI(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===a.length?null:{rect:e.rect,contentExtent:r,contentBlocks:a}}(e);r&&t.push(r)}r.push(...e.children)}return t}(r);if(0!==a.length)for(let t of e){if(!t.rect||!X(t.type))continue;let r=function(e,t){let r=null,a=1/0;for(let n of t){let t=Math.abs(n.rect.width-e.width)+Math.abs(n.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(n.rect.x-e.x)+Math.abs(n.rect.y-e.y));i<a&&(r=n,a=i)}return r}(t.rect,a);if(!r)continue;let n=function(e,t){let r=function(e,t){let r=t,a=new Set;for(;!a.has(r.index);){var n,i;a.add(r.index);let o=e.filter(e=>e.parentIndex===r.index&&e.rect);if(1!==o.length)return r;let s=o[0];if(n=s.rect,i=t.rect,n.x!==i.x||n.y!==i.y||n.width!==i.width||n.height!==i.height)return r;r=s}return t}(e,t);return e.filter(e=>e.parentIndex===r.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>iI(e,t.rect))}(e,t),i=function(e){let{viewportRect:t,visibleBlocks:r,nativeScrollView:a}=e;if(0===r.length||0===a.contentBlocks.length)return null;let n=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],r=e.contentBlocks[e.contentBlocks.length-1];if(!t||!r)return null;let a=iy(e.contentBlocks.map(e=>e.size))??e.rect.height,n=Math.max(48,Math.round(.5*a)),i=Math.max(24,Math.round(.25*a)),o=t.start>=n,s=e.contentExtent-(r.start+r.size)>=i;return o||s?{above:o,below:s}:null}(a),i=function(e,t){let r=new Map;for(let a of e)for(let e of t){if(!iv(a,e))continue;let t=a.start-e.start,n=8*Math.round(t/8),i=r.get(n)??[];i.push(t),r.set(n,i)}let a=null;for(let e of r.values())(!a||e.length>a.length)&&(a=e);if(!a||a.length<2)return null;let n=[...a].sort((e,t)=>e-t);return n[Math.floor(n.length/2)]??null}(a.contentBlocks,r)??function(e){let{nativeBlocks:t,visibleBlocks:r,viewportExtent:a,contentExtent:n}=e,i=[],o=[];for(let e of t)for(let t of r){if(!iv(e,t))continue;let r=e.start-t.start;16>=Math.abs(r)&&i.push(r),16>=Math.abs(r+a-n)&&o.push(r)}return o.length>0?iy(o):i.length>0?iy(i):null}({nativeBlocks:a.contentBlocks,visibleBlocks:r,viewportExtent:t.height,contentExtent:a.contentExtent});if(null===i)return n;let o=t.height;return{above:(n?.above??!1)||i>16,below:(n?.below??!1)||i+o<a.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:n,nativeScrollView:r});i&&(i.above&&(t.hiddenContentAbove=!0),i.below&&(t.hiddenContentBelow=!0))}}(t,r)}async function iS(e){return eG(()=>iN(e),{shouldRetry:ix})}async function iN(e){var t,r,a;let n,i,o=await F("adb",aK(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0}),s=i_(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await F("adb",aK(e,["shell","uiautomator","dump",l]),{allowFailure:!0}),u=(t=l,r=d.stdout,a=d.stderr,n=`${r}
18
+ ${a}`,i=/dumped to:\s*(\S+)/i.exec(n),i?.[1]??t),c=await F("adb",aK(e,["shell","cat",u])),p=i_(c.stdout,c.stderr);if(!p)throw new O("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function i_(e,t){let r=`${e}
19
+ ${t}`,a=r.indexOf("<?xml"),n=a>=0?a:r.indexOf("<hierarchy");if(n<0)return null;let i=r.lastIndexOf("</hierarchy>");if(i<0||i<n)return null;let o=r.slice(n,i+12).trim();return o.length>0?o:null}function ix(e){if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.details?.stderr??""}`.toLowerCase();return!!(t.includes("device offline")||t.includes("device not found")||t.includes("transport error")||t.includes("connection reset")||t.includes("broken pipe")||t.includes("timed out")||t.includes("no such file or directory"))}async function iD(e){try{let t=await F("adb",aK(e,["shell","dumpsys","activity","top"]),{allowFailure:!0,timeoutMs:8e3}),r=`${t.stdout}
20
+ ${t.stderr}`.trim();return r.length>0?r:null}catch{return null}}async function iM(e,t,r){await F("adb",aK(e,["shell","input","tap",String(t),String(r)]))}async function ik(e,t,r,a,n,i=250){await F("adb",aK(e,["shell","input","swipe",String(t),String(r),String(a),String(n),String(i)]))}async function iE(e){await F("adb",aK(e,["shell","input","keyevent","4"]))}async function iO(e){await F("adb",aK(e,["shell","input","keyevent","3"]))}async function iL(e,t){let r=function(e){switch(e){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new O("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await F("adb",aK(e,["shell","settings","put","system","accelerometer_rotation","0"])),await F("adb",aK(e,["shell","settings","put","system","user_rotation",r]))}async function iC(e){await F("adb",aK(e,["shell","input","keyevent","187"]))}async function iP(e,t,r,a=800){await F("adb",aK(e,["shell","input","swipe",String(t),String(r),String(t),String(r),String(a)]))}async function iR(e,t,r=0){r>0&&Array.from(t).length>1?await iq(e,t,1,r):await iT(e,t)}async function iT(e,t){let r=iH(t);if(!r||"ok"!==await iW(e,t))try{let r=t.replace(/ /g,"%s");await F("adb",aK(e,["shell","input","text",r]))}catch(e){if(r&&function(e){if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return!!(t.includes("exception occurred while executing 'text'")||t.includes("nullpointerexception")&&t.includes("inputshellcommand.sendtext"))}(e))throw new O("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function i$(e,t,r){await iM(e,t,r)}async function iF(e,t,r,a,n=0){let i=Array.from(a).length,o=iH(a),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&n<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||n>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var d,u;await i$(e,t,r);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await iz(e,s),"input_text"===o.strategy)await iR(e,a,n);else if("clipboard_paste"===o.strategy){if("ok"!==await iW(e,a))continue}else await iq(e,a,1,n>0?n:15);let c=await iU(e,t,r,a);if(l=c.actual,c.ok)return}throw new O("COMMAND_FAILED","Android fill verification failed",{expected:a,actual:l??null})}async function iU(e,t,r,a){let n=null;for(let i of[0,150,350])if(i>0&&await aZ(i),function(e,t){if(e===t)return!0;let r=iG(e),a=iG(t);return!!r&&!!a&&(!!(r===a||r.includes(a))||a.includes(r)&&r.length>=Math.max(4,Math.floor(.8*a.length)))}(n=await iJ(e,t,r),a))return{ok:!0,actual:n};return{ok:!1,actual:n}}function iG(e){return(e??"").replace(/\s+/g," ").trim()}async function iV(e,t,r){let a=await ij(e),n=is({direction:t,amount:r?.amount,pixels:r?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await F("adb",aK(e,["shell","input","swipe",String(n.x1),String(n.y1),String(n.x2),String(n.y2),"300"])),n}async function iB(e,t,r){let a=r?.maxScrolls??8,n="";try{n=await iS(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new O("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(il(n,t))return{attempts:0};for(let r=1;r<=a;r+=1){await iV(e,"down",{amount:.5});let a="";try{a=await iS(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new O("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(il(a,t))return{attempts:r};if(a===n)throw new O("COMMAND_FAILED",`scrollintoview could not find text: ${t}`,{reason:"not_found",attempts:r,stalled:!0});n=a}throw new O("COMMAND_FAILED",`scrollintoview could not find text: ${t}`,{reason:"not_found",attempts:a})}async function ij(e){let t=(await F("adb",aK(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new O("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function iq(e,t,r,a){let n=Math.max(1,Math.floor(r)),i=Array.from(t);for(let t=0;t<i.length;t+=n){let r=i.slice(t,t+n).join("");await iT(e,r),a>0&&t+n<i.length&&await aZ(a)}}function iH(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&(e<32||e>126))return!0}return!1}async function iW(e,t){let r=await F("adb",aK(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==r.exitCode?"failed":aY(r.stdout,r.stderr)?"unsupported":0===(await F("adb",aK(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await F("adb",aK(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function iz(e,t){let r=Math.max(0,t);await F("adb",aK(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<r;t+=24){let a=Math.min(24,r-t);await F("adb",aK(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function iJ(e,t,r){let a,n=await iS(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=i.exec(n));){let e=iu(a[0]),n=im(e.bounds);if(!n)continue;let i=e.className??"",d=(e.text??"").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,n.width*n.height),p=t>=n.x&&t<=n.x+n.width&&r>=n.y&&r<=n.y+n.height;if(u&&iK(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&iK(i)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function iK(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function iX(e){let t=await F("adb",aK(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new O("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let r of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=r[1],a=r[2]?.toLowerCase();e&&("true"===a||"false"===a)&&t.set(e,"true"===a)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),r=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(r=(1&e)!=0)}}let a=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),n=a.length>0?a[a.length-1]?.[1]:void 0,i=n?`0x${n.toLowerCase()}`:void 0;return{visible:r,inputType:i,type:i?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let r=15&t;if(2===r)return"number";if(3===r)return"phone";if(4===r)return"datetime";if(1!==r)return"unknown";let a=4080&t;return 32===a||208===a?"email":128===a||224===a||144===a?"password":"text"}(i):void 0}}(t.stdout)}async function iY(e){let t=await iX(e),r=t,a=0;for(;r.visible&&a<2;)await F("adb",aK(e,["shell","input","keyevent","111"])),a+=1,await aZ(120),r=await iX(e);if(t.visible&&r.visible)throw new O("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:a,inputType:r.inputType,type:r.type});return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type}}async function iZ(e){let t,r;return(r=(t=(await i0(e,["shell","cmd","clipboard","get","text"],"read")).replace(/\r\n/g,"\n").replace(/\n$/,"")).match(/^clipboard text:\s*(.*)$/i))?r[1]??"":"null"===t.trim().toLowerCase()?"":t}async function iQ(e,t){await i0(e,["shell","cmd","clipboard","set","text",t],"write")}async function i0(e,t,r){let a=await F("adb",aK(e,t),{allowFailure:!0});if(aY(a.stdout,a.stderr))throw new O("UNSUPPORTED_OPERATION",`Android shell clipboard ${r} is not supported on this device.`);if(0!==a.exitCode)throw new O("COMMAND_FAILED",`Failed to ${r} Android clipboard text`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return a.stdout}let i1=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function i2(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new O("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function i3(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new O("INVALID_ARGS",`permission setting requires a target: ${i1.join("|")}`)}function i4(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new O("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}async function i5(e,t,r,a,n){switch(t.toLowerCase()){case"wifi":{let t=i6(r);await F("adb",aK(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=i6(r);await F("adb",aK(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await F("adb",aK(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=i6(r);await F("adb",aK(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"appearance":{let t=await i9(e,r);await F("adb",aK(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]));return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new O("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await i8(e,t);return}case"permission":{if(!a)throw new O("INVALID_ARGS","permission setting requires an active app in session");let t=i2(r),i=function(e,t){let r=i3(e);if(t?.trim())throw new O("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===r)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===r)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===r)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===r)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new O("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(n?.permissionTarget,n?.permissionMode);if("notifications"===i.kind)return void await oe(e,a,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await i7(e,a,o);await F("adb",aK(e,["shell","pm",o,a,i.value]));return}default:throw new O("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function i8(e,t){var r;let a,n,i=(r=e,n=[["shell","cmd","fingerprint","touch",a="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",a]],"emulator"===r.kind&&n.push(["emu","finger","touch",a]),n),o=[];for(let t of i){let r=await F("adb",aK(e,t),{allowFailure:!0});if(0===r.exitCode)return;o.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,r;let a;return t=e.stdout,r=e.stderr,(a=`${t}
21
+ ${r}`.toLowerCase()).includes("unknown command")||a.includes("can't find service: fingerprint")||a.includes("service fingerprint was not found")||a.includes("fingerprint cmd unavailable")||a.includes("emu command is not supported")||a.includes("emulator console is not running")||a.includes("fingerprint")&&a.includes("not found")}))throw new O("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new O("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function i6(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new O("INVALID_ARGS",`Invalid setting state: ${e}`)}async function i9(e,t){let r=i4(t);if("toggle"!==r)return r;let a=await F("adb",aK(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==a.exitCode)throw new O("COMMAND_FAILED","Failed to read current Android appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let n=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
22
+ ${t}`);if(!r)return null;let a=r[1].toLowerCase();return"yes"===a?"dark":"no"===a?"light":"auto"===a?"auto":null}(a.stdout,a.stderr);if(!n)throw new O("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"auto"===n?"dark":"dark"===n?"light":"dark"}async function i7(e,t,r){let a=await ot(e),n=[];for(let i of null!==a&&a>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let a=await F("adb",aK(e,["shell","pm",r,t,i]),{allowFailure:!0});if(0===a.exitCode)return;n.push({permission:i,stderr:a.stderr,exitCode:a.exitCode})}throw new O("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:a,attempts:n})}async function oe(e,t,r,a){"grant"===r?await F("adb",aK(e,["shell","pm","grant",t,a.permission]),{allowFailure:!0}):(await F("adb",aK(e,["shell","pm","revoke",t,a.permission]),{allowFailure:!0}),"reset"===r&&(await F("adb",aK(e,["shell","pm","clear-permission-flags",t,a.permission,"user-set"]),{allowFailure:!0}),await F("adb",aK(e,["shell","pm","clear-permission-flags",t,a.permission,"user-fixed"]),{allowFailure:!0}))),await F("adb",aK(e,["shell","appops","set",t,a.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"]))}async function ot(e){let t=await F("adb",aK(e,["shell","getprop","ro.build.version.sdk"]),{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}async function or(e,t,r){let a="string"==typeof r.action&&r.action.trim()?r.action.trim():`${t}.TEST_PUSH`,n=["shell","am","broadcast","-a",a,"-p",t],i="string"==typeof r.receiver?r.receiver.trim():"";i&&n.push("-n",i);let o=r.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new O("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,r){if("string"==typeof r)return e.push("--es",t,r);if("boolean"==typeof r)return e.push("--ez",t,r?"true":"false");if("number"==typeof r&&Number.isFinite(r))return Number.isInteger(r)?e.push("--ei",t,String(r)):e.push("--ef",t,String(r));throw new O("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(n,e,t),s+=1);return await F("adb",aK(e,n)),{action:a,extrasCount:s}}let oa=Buffer.from([137,80,78,71,13,10,26,10]);async function on(e,t){await oi(e);try{await aZ(1e3),await os(e,t)}finally{await oo(e).catch(()=>{})}}async function oi(e){let t=t=>F("adb",aK(e,["shell",t]),{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let r=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await r("clock -e hhmm 0941"),await r("notifications -e visible false")}async function oo(e){await F("adb",aK(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function os(e,t){let r=await F("adb",aK(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!r.stdoutBuffer)throw new O("COMMAND_FAILED","Failed to capture screenshot");let a=r.stdoutBuffer.indexOf(oa);if(a<0)throw new O("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let n=function(e,t){let r=t+oa.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),a=r+4,n=e.toString("ascii",a,a+4),i=r+12+t;if(i>e.length)break;if("IEND"===n)return i;r=i}return null}(r.stdoutBuffer,a);if(!n)throw new O("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await d.writeFile(t,r.stdoutBuffer.subarray(a,n))}let ol=e0(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,eT,5e3),od=e0(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,eR,1e3),ou=e0(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),oc=e0(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),op=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),of=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),om=e0(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),oh=eP(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function ow(e,t){let r=["devicectl",...e],a=await F("xcrun",r,{allowFailure:!0,timeoutMs:oc});if(0===a.exitCode)return;let n=String(a.stdout??""),i=String(a.stderr??"");throw new O("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:r,exitCode:a.exitCode,stdout:n,stderr:i,deviceId:t.deviceId,hint:oI(n,i)??ov})}async function og(e,t){let r=p.join(u.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",r],n=await F("xcrun",a,{allowFailure:!0,timeoutMs:oc});try{var i,o;if(0!==n.exitCode){let t=String(n.stdout??""),r=String(n.stderr??"");throw new O("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:a,exitCode:n.exitCode,stdout:t,stderr:r,deviceId:e.id,hint:oI(t,r)??ov})}let s=await d.readFile(r,"utf8");return i=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let a="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,n="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;r.push({bundleId:t,name:a,url:n})}return r}(JSON.parse(s)),o=t,"user-installed"===o?i.filter(e=>!e.bundleId.startsWith("com.apple.")):i}catch(t){if(t instanceof O)throw t;throw new O("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await d.unlink(r).catch(()=>{})}}async function oy(e){let t=p.join(u.tmpdir(),`agent-device-ios-processes-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=["devicectl","device","info","processes","--device",e.id,"--json-output",t],a=await F("xcrun",r,{allowFailure:!0,timeoutMs:oc});try{if(0!==a.exitCode){let t=String(a.stdout??""),n=String(a.stderr??"");throw new O("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:r,exitCode:a.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:oI(t,n)??ov})}let n=await d.readFile(t,"utf8");return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",a="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(a)&&r.push({executable:t,pid:a})}return r}(JSON.parse(n))}catch(t){if(t instanceof O)throw t;throw new O("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await d.unlink(t).catch(()=>{})}}let ov="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function oI(e,t){let r=`${e}
23
+ ${t}`.toLowerCase();return r.includes("device is busy")&&r.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":r.includes("coredeviceservice")&&r.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function ob(e){if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let r=String(t.stderr??"").toLowerCase();return r.includes("fbsopenapplicationserviceerrordomain")&&r.includes("the request to open")}async function oA(e,t){let r=await F("xcrun",tt(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==r.exitCode)return{installed:!1};let a=r.stdout.trim();if(!a)return{installed:!1};let n=await F("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==n.exitCode||!n.stdout.trim())return{installed:!0};let i=n.stdout.trim(),o=`${a}/${i}`,s=await F("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function oS(e,t){if("simulator"!==e.kind)throw new O("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function oN(){await F("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:op})}async function o_(e){let t,r;if("simulator"!==e.kind||"Booted"===await oD(e))return;let a=eF.fromTimeoutMs(ol);try{await eU(async({deadline:a})=>{if(a?.isExpired())throw new O("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:ol});let n=Math.max(1e3,a?.remainingMs()??ol),i=await F("xcrun",tt(e,["boot",e.id]),{allowFailure:!0,timeoutMs:n});t={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let o=`${t.stdout}
24
+ ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new O("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await F("xcrun",tt(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:n});if(r={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==r.exitCode)throw new O("COMMAND_FAILED","simctl bootstatus failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let d=await oD(e);if("Booted"!==d)throw new O("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let a=e1({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==a&&"CI_RESOURCE_STARVATION_SUSPECTED"!==a}},{deadline:a,phase:"boot",classifyReason:e=>e1({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let n=e1({error:i,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new O("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:ol,elapsedMs:a.elapsedMs(),reason:n,hint:e2(n),boot:t,bootstatus:r})}await oN()}async function ox(e){let t=tt(e,["shutdown",e.id]),r=await F("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===r.exitCode,exitCode:r.exitCode,stdout:String(r.stdout??""),stderr:String(r.stderr??"")}}async function oD(e){let t="string"==typeof e?e:e.id,r="string"==typeof e?te(["list","devices","-j"]):tt(e,["list","devices","-j"]),a=await F("xcrun",r,{allowFailure:!0,timeoutMs:od});if(0!==a.exitCode)return null;try{let e=JSON.parse(String(a.stdout??""));for(let r of Object.values(e.devices??{})){let e=r.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function oM(e,t){try{let r=await F("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===r.exitCode){let e=String(r.stdout??"").trim();if(e.length>0)return e}}catch{}try{var r,a;let n;return r=await d.readFile(e,"utf8"),a=t,tL(tO(r),(e,t)=>{void 0===n&&e===a&&"string"===t.name&&(n=t.text??void 0)}),n}catch{return}}async function ok(e,t){if("url"===e.kind&&!nA(e.url))throw new O("INVALID_ARGS","iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.");let r=await ny({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||nA(e.url),signal:t?.signal}),a=await oO(r.installablePath,t),n=await oE(a.installPath);return{archivePath:r.archivePath??(r.installablePath.toLowerCase().endsWith(".ipa")?r.installablePath:void 0),installablePath:a.installPath,bundleId:n.bundleId,appName:n.appName,cleanup:async()=>{await a.cleanup(),await r.cleanup()}}}async function oE(e){let t=p.join(e,"Info.plist"),[r,a,n]=await Promise.all([oM(t,"CFBundleIdentifier"),oM(t,"CFBundleDisplayName"),oM(t,"CFBundleName")]);return{bundleId:r,appName:a??n}}async function oO(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let r=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-ios-ipa-")),a=async()=>{await d.rm(r,{recursive:!0,force:!0})};try{await F("ditto",["-x","-k",e,r]);let n=p.join(r,"Payload"),i=(await d.readdir(n,{withFileTypes:!0}).catch(()=>{throw new O("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:p.join(n,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===i.length)return{installPath:i[0].installPath,cleanup:a};if(0===i.length)throw new O("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await oL(i);let o=t?.appIdentifierHint?.trim();if(o){let e=function(e,t){let r=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===r);if(1===a.length)return a[0];if(a.length>1)throw new O("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===r);if(1===t.length)return t[0]}}(i,o);if(e)return{installPath:e.installPath,cleanup:a};throw new O("INVALID_ARGS",`Invalid IPA: found ${i.length} .app bundles under Payload and none matched "${o}". Available bundles: ${i.map(oC).join(", ")}`)}throw new O("INVALID_ARGS",`Invalid IPA: found ${i.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${i.map(oC).join(", ")}`)}catch(e){throw await a(),e}}async function oL(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await oE(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function oC(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function oP(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let oR="agent-device-macos-helper",oT="AGENT_DEVICE_MACOS_HELPER_BIN",o$=p.join(u.homedir(),".agent-device","macos-helper","current"),oF=p.join(o$,"manifest.json"),oU=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function oG(e){let t=e.trim();if(!oU.test(t))throw new O("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function oV(){return function(e){let t=p.dirname(e);for(;;){let e=p.join(t,"macos-helper");if(l(p.join(e,"Package.swift")))return e;let r=p.dirname(t);if(r===t)break;t=r}throw new O("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(w(import.meta.url))}async function oB(e){let t=await d.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let r=p.join(e,t.name);return t.isDirectory()?".build"===t.name?[]:await oB(r):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[r]:[]}))).flat().sort()}async function oj(e){let t=await oB(e),r=o("sha256");for(let a of t)r.update(p.relative(e,a)),r.update("\0"),r.update(await d.readFile(a)),r.update("\0");let a=await F("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return r.update("swift-version"),r.update("\0"),r.update(a.stdout||a.stderr||`exit:${a.exitCode}`),r.update("\0"),r.digest("hex")}async function oq(){try{let e=JSON.parse(await d.readFile(oF,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function oH(){let e=process.env[oT]?.trim();if(e)return e;let t=oV(),r=await oj(t),a=p.join(o$,oR);try{if(await oq()===r)return await d.access(a),a}catch{}let n=p.join(oV(),".build","release",oR);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await F("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await d.mkdir(o$,{recursive:!0});let i=`${a}.tmp`;return await d.copyFile(n,i),await d.rename(i,a),await d.chmod(a,493),await d.writeFile(oF,`${JSON.stringify({fingerprint:r},null,2)}
25
+ `,"utf8"),a}async function oW(e){let t=process.env[oT]?.trim();if("darwin"!==process.platform&&!t)throw new O("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");let r=await oH(),a=await F(r,e,{allowFailure:!0,timeoutMs:3e4}),n=a.stdout.trim(),i=null;if(n)try{i=JSON.parse(n)}catch{i=null}if(0===a.exitCode&&i?.ok)return i.data;throw new O("COMMAND_FAILED",i&&!i.ok?i.error?.message??`macOS helper exited with code ${a.exitCode}`:n||a.stderr.trim()||`macOS helper exited with code ${a.exitCode}`,{helperPath:r,args:e,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,...i&&!i.ok?i.error?.details:{}})}async function oz(){return await oW(["app","frontmost"])}async function oJ(e){return await oW(["app","quit","--bundle-id",oG(e)])}async function oK(e,t){return await oW(["permission",e,t])}async function oX(e,t={}){let r=["alert",e];return t.bundleId&&r.push("--bundle-id",oG(t.bundleId)),t.surface&&r.push("--surface",t.surface),await oW(r)}async function oY(e,t={}){let r=["snapshot","--surface",e];return t.bundleId&&r.push("--bundle-id",oG(t.bundleId)),await oW(r)}async function oZ(e,t,r={}){let a=["read","--x",String(e),"--y",String(t)];return r.bundleId&&a.push("--bundle-id",oG(r.bundleId)),r.surface&&a.push("--surface",r.surface),await oW(a)}async function oQ(e,t,r={}){let a=["press","--x",String(e),"--y",String(t)];return r.bundleId&&a.push("--bundle-id",oG(r.bundleId)),r.surface&&a.push("--surface",r.surface),await oW(a)}async function o0(e,t={}){let r=["screenshot","--out",e];return t.surface&&r.push("--surface",t.surface),t.fullscreen&&r.push("--fullscreen"),await oW(r)}let o1={settings:"com.apple.systempreferences"},o2=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;function o3(e,t){let r=["-b",e];return t&&r.push(t),r}async function o4(e){for(let t of[p.join(e,"Contents","Info.plist"),p.join(e,"Info.plist")]){let[e,r,a]=await Promise.all([oM(t,"CFBundleIdentifier"),oM(t,"CFBundleDisplayName"),oM(t,"CFBundleName")]);if(e||r||a)return{bundleId:e,appName:r??a}}return{}}async function o5(e){let t=e.trim(),r=o1[t.toLowerCase()];if(r)return r;if(o2.test(t))return t;let a=(await sr("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===a.length)return a[0].bundleId;if(a.length>1)throw new O("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:a});throw new O("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function o8(e,t,r){let a=r?.url?.trim();if(a){if(!aQ(a))throw new O("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=r?.appBundleId??await o5(t);await F("open",o3(e,a));return}let n=t.trim();if(aQ(n))return void await F("open",[n]);let i=r?.appBundleId??await o5(n);await F("open",o3(i))}async function o6(e,t){let r=await o5(t),a=await oJ(r);if(a.running&&!a.terminated&&!a.forceTerminated)throw new O("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:r,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function o9(){let e=await F("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new O("COMMAND_FAILED","Failed to read macOS clipboard",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});return e.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function o7(e){let t=await F("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new O("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function se(){let e=await F("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new O("COMMAND_FAILED","Failed to read macOS appearance",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});let t=e.stdout.trim().toLowerCase();if("true"===t)return!0;if("false"===t)return!1;throw new O("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function st(e){let t=i4(e),r="toggle"===t?!await se():"dark"===t,a=`tell application "System Events" to tell appearance preferences to set dark mode to ${r?"true":"false"}`,n=await F("osascript",["-e",a],{allowFailure:!0});if(0!==n.exitCode)throw new O("COMMAND_FAILED","Failed to set macOS appearance",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}async function sr(e="all"){let t=["/Applications","/System/Applications",p.join(u.homedir(),"Applications")],r=new Set;for(let e of t){let t=await d.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let a=await F("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===a.exitCode)for(let e of a.stdout.split("\n")){let t=e.trim();t&&r.add(t)}}return oP((await Promise.all(Array.from(r).map(async e=>{let t=await o4(e).catch(()=>({})),r=t.bundleId;return r?{bundleId:r,name:t.appName??p.basename(e,".app")}:null}))).filter(e=>null!==e).sort((e,t)=>e.name.localeCompare(t.name)),e)}let sa=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],sn={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},si={1:"searching",2:"failed",3:"active"},so={0:"notSupported",1:"searching",2:"failed",3:"active"};function ss(e,t,r){return F("xcrun",tt(e,t),r)}async function sl(e,t){var r,a;let n;await su(e),t&&await sc(e,(n=[],(r=t).dataNetwork&&n.push("--dataNetwork",r.dataNetwork),r.wifiMode&&n.push("--wifiMode",r.wifiMode),void 0!==r.wifiBars&&("wifi"===r.dataNetwork||r.wifiMode)&&n.push("--wifiBars",r.wifiBars),r.cellularMode&&n.push("--cellularMode",r.cellularMode),void 0!==r.cellularBars&&(r.cellularMode||(a=r.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==r.operatorName)&&n.push("--cellularBars",r.cellularBars),void 0!==r.operatorName&&n.push("--operatorName",r.operatorName),n))}async function sd(e){let t=await ss(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new O("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let r of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(r);if(e){let r=Number(e[1]),a=sn[r];if(!a)throw new O("COMMAND_FAILED",`Unsupported simulator data network type: ${r}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(r);if(a){let e=si[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let n=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(r);if(n){let e=Number(n[1]),r=so[e];if(!r)throw new O("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=r,t.cellularBars=n[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(r);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function su(e){await ss(e,["status_bar",e.id,"clear"])}async function sc(e,t){0!==t.length&&await ss(e,["status_bar",e.id,"override",...t])}function sp(e,t,r){U({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof O))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:r}}(r)}})}function sf(e,t,r){return F("xcrun",tt(e,t),r)}let sm={ensureBooted:o_,prepareStatusBarForScreenshot:async function e(e){let t=null,r=!1;try{t=await sd(e),r=!0}catch(t){sp(e,"snapshot_failed",t)}try{await su(e),await sc(e,sa)}catch(t){sp(e,"prepare_failed",t)}return async()=>{await sl(e,r?t:null)}},captureWithRetry:sg,runnerFallbackEnabled:oh,captureWithRunner:sy,shouldFallbackToRunner:s_};async function sh(e,t,r,a){if("macos"===e.platform)return void await sy(e,t,r,a);if("simulator"===e.kind)return void await sw(e,t,r,a);try{await ow(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",n=`${e.message}
26
26
  ${r}
27
- ${a}`.toLowerCase();return n.includes("unknown option '--device'")||n.includes("unknown subcommand")&&n.includes("screenshot")||n.includes("unrecognized subcommand")&&n.includes("screenshot")}(t))throw t;sA(e,"devicectl_screenshot",t)}await sy(e,t,r,a)}async function sw(e,t,r,a,n=sm){if("simulator"!==e.kind)throw new W("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let i="object"==typeof a&&null!==a?a:n;await i.ensureBooted(e);let o=async()=>{};try{o=await i.prepareStatusBarForScreenshot(e)}catch(t){sS(e,"prepare_failed",t)}try{try{await i.captureWithRetry(e,t);return}catch(t){if(!i.shouldFallbackToRunner(t))throw t;if(!i.runnerFallbackEnabled){var s,l,d;let r,a;throw s=e,l=t,r=sN(l),ep({level:"warn",phase:"ios_screenshot_fallback_skipped",data:{platform:s.platform,deviceKind:s.kind,deviceId:s.id,from:"simctl_screenshot",to:"runner",reason:"Simulator runner fallback is disabled to avoid XCTest automation instability during screenshot capture.",...r}}),a=(d=t)instanceof W?d:new W("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,d),new W(a.code,a.message,{...a.details??{},hint:"Restart the simulator and retry. If simctl screenshots keep timing out and you accept the stability tradeoff, set AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK=1 to allow XCTest runner fallback."},a)}sA(e,"simctl_screenshot",t)}await i.captureWithRunner(e,t,r,"boolean"==typeof a?a:void 0)}finally{await o().catch(t=>sS(e,"restore_failed",t))}}async function sg(e,t){let r=eF.fromTimeoutMs(of);await eU(async({deadline:r})=>{await sf(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,r?.remainingMs()??of)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>s_(e)},{deadline:r,phase:"ios_simulator_screenshot"})}async function sy(e,t,r,a){let n=(await rf(e,{command:"screenshot",appBundleId:r,fullscreen:a})).message;if(!n)throw new W("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await d.copyFile(n,t):"simulator"===e.kind?await sI(e,n,t):await sv(e,n,t)}async function sv(e,t,r){let a=eF.fromTimeoutMs(om),n={exitCode:1,stdout:"",stderr:""};for(let i of tq)if(0===(n=await $("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",r,"--domain-type","appDataContainer","--domain-identifier",i],{allowFailure:!0,timeoutMs:sb(a,om,"runner screenshot copy")})).exitCode)return;let i=n.stderr.trim()||n.stdout.trim()||`devicectl exited with code ${n.exitCode}`;throw new W("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}async function sI(e,t,r){let a=eF.fromTimeoutMs(om),n="Unable to locate runner container for simulator screenshot";for(let i of tq){let o=await sf(e,["get_app_container",e.id,i,"data"],{allowFailure:!0,timeoutMs:sb(a,om,"runner screenshot container lookup")});if(0!==o.exitCode){let e=o.stderr.trim();e&&(n=e);continue}let s=o.stdout.trim();if(!s){n="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let r=p.resolve(e),a=t.trim();if(!a)return[];let n=[],i=new Set,o=e=>{let t=p.normalize(e);i.has(t)||(i.add(t),n.push(t))},s=a.replace(/^\/+/,""),l=s.replace(/\\/g,"/");if(s&&o(p.join(r,s)),p.isAbsolute(a)&&o(p.normalize(a)),l.startsWith("tmp/"))o(p.join(r,l));else{let e=l.lastIndexOf("/tmp/");if(e>=0){let t=l.slice(e+1);o(p.join(r,t))}}let d=p.basename(a);return d&&o(p.join(r,"tmp",d)),n}(s,t))try{await d.copyFile(e,r);return}catch(e){n=e instanceof Error?e.message:String(e)}}throw new W("COMMAND_FAILED",`Failed to capture iOS screenshot: ${n}`)}function sb(e,t,r){let a=e.remainingMs();if(a>0)return a;throw new W("COMMAND_FAILED",`iOS ${r} timed out after ${t}ms`,{timeoutMs:t,step:r})}function sA(e,t,r){let a=sN(r);ep({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function sS(e,t,r){ep({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...sN(r)}})}function sN(e){if(!(e instanceof W))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:r}}function s_(e){if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",i=`${e.message}
27
+ ${a}`.toLowerCase();return n.includes("unknown option '--device'")||n.includes("unknown subcommand")&&n.includes("screenshot")||n.includes("unrecognized subcommand")&&n.includes("screenshot")}(t))throw t;sA(e,"devicectl_screenshot",t)}await sy(e,t,r,a)}async function sw(e,t,r,a,n=sm){if("simulator"!==e.kind)throw new O("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let i="object"==typeof a&&null!==a?a:n;await i.ensureBooted(e);let o=async()=>{};try{o=await i.prepareStatusBarForScreenshot(e)}catch(t){sS(e,"prepare_failed",t)}try{try{await i.captureWithRetry(e,t);return}catch(t){if(!i.shouldFallbackToRunner(t))throw t;if(!i.runnerFallbackEnabled){var s,l,d;let r,a;throw s=e,l=t,r=sN(l),U({level:"warn",phase:"ios_screenshot_fallback_skipped",data:{platform:s.platform,deviceKind:s.kind,deviceId:s.id,from:"simctl_screenshot",to:"runner",reason:"Simulator runner fallback is disabled to avoid XCTest automation instability during screenshot capture.",...r}}),a=(d=t)instanceof O?d:new O("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,d),new O(a.code,a.message,{...a.details??{},hint:"Restart the simulator and retry. If simctl screenshots keep timing out and you accept the stability tradeoff, set AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK=1 to allow XCTest runner fallback."},a)}sA(e,"simctl_screenshot",t)}await i.captureWithRunner(e,t,r,"boolean"==typeof a?a:void 0)}finally{await o().catch(t=>sS(e,"restore_failed",t))}}async function sg(e,t){let r=eF.fromTimeoutMs(of);await eU(async({deadline:r})=>{await sf(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,r?.remainingMs()??of)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>s_(e)},{deadline:r,phase:"ios_simulator_screenshot"})}async function sy(e,t,r,a){let n=(await rf(e,{command:"screenshot",appBundleId:r,fullscreen:a})).message;if(!n)throw new O("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await d.copyFile(n,t):"simulator"===e.kind?await sI(e,n,t):await sv(e,n,t)}async function sv(e,t,r){let a=eF.fromTimeoutMs(om),n={exitCode:1,stdout:"",stderr:""};for(let i of tq)if(0===(n=await F("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",r,"--domain-type","appDataContainer","--domain-identifier",i],{allowFailure:!0,timeoutMs:sb(a,om,"runner screenshot copy")})).exitCode)return;let i=n.stderr.trim()||n.stdout.trim()||`devicectl exited with code ${n.exitCode}`;throw new O("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}async function sI(e,t,r){let a=eF.fromTimeoutMs(om),n="Unable to locate runner container for simulator screenshot";for(let i of tq){let o=await sf(e,["get_app_container",e.id,i,"data"],{allowFailure:!0,timeoutMs:sb(a,om,"runner screenshot container lookup")});if(0!==o.exitCode){let e=o.stderr.trim();e&&(n=e);continue}let s=o.stdout.trim();if(!s){n="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let r=p.resolve(e),a=t.trim();if(!a)return[];let n=[],i=new Set,o=e=>{let t=p.normalize(e);i.has(t)||(i.add(t),n.push(t))},s=a.replace(/^\/+/,""),l=s.replace(/\\/g,"/");if(s&&o(p.join(r,s)),p.isAbsolute(a)&&o(p.normalize(a)),l.startsWith("tmp/"))o(p.join(r,l));else{let e=l.lastIndexOf("/tmp/");if(e>=0){let t=l.slice(e+1);o(p.join(r,t))}}let d=p.basename(a);return d&&o(p.join(r,"tmp",d)),n}(s,t))try{await d.copyFile(e,r);return}catch(e){n=e instanceof Error?e.message:String(e)}}throw new O("COMMAND_FAILED",`Failed to capture iOS screenshot: ${n}`)}function sb(e,t,r){let a=e.remainingMs();if(a>0)return a;throw new O("COMMAND_FAILED",`iOS ${r} timed out after ${t}ms`,{timeoutMs:t,step:r})}function sA(e,t,r){let a=sN(r);U({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function sS(e,t,r){U({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...sN(r)}})}function sN(e){if(!(e instanceof O))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:r}}function s_(e){if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",i=`${e.message}
28
28
  ${r}
29
29
  ${a}
30
- ${n}`.toLowerCase();return i.includes("timeout waiting for screen surfaces")||i.includes("nsposixerrordomain")&&i.includes("code=60")&&i.includes("screenshot")||i.includes("timed out")&&i.includes("screenshot")}let sx={settings:"com.apple.Preferences"},sD=null;function sM(e,t,r){return $("xcrun",tt(e,t),r)}function sk(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function sE(e,t){if("macos"===e.platform)return await o5(t);let r=t.trim();if(r.includes("."))return r;let a=sx[r.toLowerCase()];if(a)return a;let n=("simulator"===e.kind?await sj(e):await og(e,"all")).filter(e=>e.name.toLowerCase()===r.toLowerCase());if(1===n.length)return n[0].bundleId;if(n.length>1)throw new W("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:n});throw new W("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function sO(e,t,r){if("macos"===e.platform)return void await o8(e,t,r);let a=r?.url?.trim();if(a){if(!aQ(a))throw new W("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await o_(e),await sM(e,["openurl",e.id,a]);return}let n=a0(r?.appBundleId??await sE(e,t),a);if(!n)throw new W("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await sZ(e,n,{payloadUrl:a});return}let n=t.trim();if(aQ(n)){if("simulator"===e.kind){await o_(e),await sM(e,["openurl",e.id,n]);return}let t=a0(r?.appBundleId,n);if(!t)throw new W("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await sZ(e,t,{payloadUrl:n});return}let i=r?.appBundleId??await sE(e,t);"simulator"===e.kind?await sY(e,i):await sZ(e,i)}async function sL(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await oD(e)&&await o_(e)}async function sC(e,t){if("macos"===e.platform)return void await o6(e,t);let r=await sE(e,t);if("simulator"===e.kind){await o_(e);let t=tt(e,["terminate",e.id,r]),a=await $("xcrun",t,{allowFailure:!0});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new W("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await ow(["device","process","terminate","--device",e.id,r],{action:"terminate iOS app",deviceId:e.id})}async function sP(e,t){let r=await sE(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,r],a=await $("xcrun",t,{allowFailure:!0,timeoutMs:oc});if(0!==a.exitCode){let n=String(a.stdout??""),i=String(a.stderr??"");if(!sk(`${n}
31
- ${i}`.toLowerCase()))throw new W("COMMAND_FAILED",`Failed to uninstall iOS app ${r}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:n,stderr:i,deviceId:e.id,hint:oI(n,i)??ov})}return{bundleId:r}}await o_(e);let a=await sM(e,["uninstall",e.id,r],{allowFailure:!0});if(0!==a.exitCode&&!sk(`${a.stdout}
32
- ${a.stderr}`.toLowerCase()))throw new W("COMMAND_FAILED",`simctl uninstall failed for ${r}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:r}}async function sR(e,t,r){let a=await ok({kind:"path",path:t},r);try{return await s$(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function sT(e,t,r){let{bundleId:a}=await sP(e,t);return await sR(e,r,{appIdentifierHint:t}),{bundleId:a}}async function s$(e,t){"simulator"!==e.kind?await ow(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await o_(e),await sM(e,["install",e.id,t]))}async function sF(e){if("macos"===e.platform)return await o9();oS(e,"clipboard"),await o_(e);let t=await sM(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new W("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function sU(e,t){if("macos"===e.platform)return void await o7(t);oS(e,"clipboard"),await o_(e);let r=await sM(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==r.exitCode)throw new W("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function sG(e,t,r){oS(e,"push"),await o_(e);let a=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-ios-push-")),n=p.join(a,"payload.apns");try{await d.writeFile(n,`${JSON.stringify(r)}
33
- `,"utf8"),await sM(e,["push",e.id,t,n])}finally{await d.rm(a,{recursive:!0,force:!0})}}async function sV(e,t,r,a,n){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await st(r);if("permission"===e){let e=i2(r);if("deny"===e)throw new W("INVALID_ARGS",K("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new W("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(n?.permissionTarget);return await oK(e,t)}throw new W("INVALID_ARGS",K(t))}oS(e,"settings"),await o_(e);let i=t.toLowerCase();switch(i){case"wifi":{let t=sq(r);await sM(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(sq(r)?await sM(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await sM(e,["status_bar",e.id,"clear"]));case"location":{let t=sq(r);if(!a)throw new W("INVALID_ARGS","location setting requires an active app in session");await sM(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=sW[i],a=function(e,t){let r=e.trim().toLowerCase();if("match"===r)return"match";if("nonmatch"===r)return"nonmatch";if("enroll"===r)return"enroll";if("unenroll"===r)return"unenroll";throw new W("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(r,i);await sX(e,a,{settingName:i,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await sH(e,r);await sM(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!a)throw new W("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=i2(r))?"revoke":o,i=function(e,t){let r=i3(e);if("photos"!==r&&t?.trim())throw new W("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return"camera";if("microphone"===r)return"microphone";if("contacts"===r)return"contacts";if("contacts-limited"===r)return"contacts-limited";if("notifications"===r)return"notifications";if("calendar"===r)return"calendar";if("location"===r)return"location";if("location-always"===r)return"location-always";if("media-library"===r)return"media-library";if("motion"===r)return"motion";if("reminders"===r)return"reminders";if("siri"===r)return"siri";if("photos"===r){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new W("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new W("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(n?.permissionTarget,n?.permissionMode);await sz(e,t,i,a);return}default:throw new W("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function sB(e,t="all"){return"macos"===e.platform?await sr(t):"simulator"===e.kind?oP(await sj(e),t):await og(e,t)}async function sj(e){let t=(await sM(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let r=null;if(t.startsWith("{"))try{r=JSON.parse(t)}catch{r=null}if(!r&&t.startsWith("{"))try{let e=await $("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>({bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e})):[]}function sq(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new W("INVALID_ARGS",`Invalid setting state: ${e}`)}async function sH(e,t){let r=i4(t);if("toggle"!==r)return r;let a=await sM(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new W("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let n=function(e,t){let r=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
34
- ${t}`);if(!r)return null;let a=r[1].toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!n)throw new W("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===n?"light":"dark"}let sW={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function sz(e,t,r,a){let n=await sK(e);if(!n.has(r))throw new W("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(n).sort().join(", ")}`});let i=["privacy",e.id,t,r,a],o="notifications"===r;if(!("reset"===t&&o))try{await sM(e,i);return}catch(t){if(!(o&&sJ(t)))throw t;throw new W("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:a,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await sM(e,i);return}catch(e){if(!sJ(e))throw e}try{await sM(e,["privacy",e.id,"reset","all",a])}catch(t){throw new W("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:a,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function sJ(e){if(!(e instanceof W)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function sK(e){let r=e6(e.simulatorSetPath),a=`${process.env.PATH??""}::${r??""}`;if(sD&&t===a)return sD;let n=await sM(e,["privacy","help"],{allowFailure:!0}),i=function(e){let t=new Set,r=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){r=!0;continue}if(!r)continue;if(e.startsWith("bundle identifier"))break;let n=/^([a-z-]+)\s+-\s+/.exec(e);n&&t.add(n[1])}return t}(`${n.stdout}
35
- ${n.stderr}`);if(0===i.size)throw new W("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return sD=i,t=a,i}async function sX(e,t,r){let a=function(e,t,r){let a=r.length>0?r:["face"];switch(t){case"match":return a.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return a.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,r.modalityAliases),n=[];for(let t of a){let r=tt(e,t),a=await $("xcrun",r,{allowFailure:!0});if(0===a.exitCode)return;n.push({args:r,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let i=n.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(n.length>0&&n.every(e=>{var t,r;let a;return t=e.stdout,r=e.stderr,(a=`${t}
36
- ${r}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new W("UNSUPPORTED_OPERATION",`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:i});throw new W("COMMAND_FAILED",`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:i})}async function sY(e,t){await o_(e);let r=0,a=eF.fromTimeoutMs(ou);try{await eU(async({deadline:r})=>{var a;if(r?.isExpired())throw new W("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:ou});let n=(a=["launch",e.id,t],tt(e,a)),i=await $("xcrun",n,{allowFailure:!0});if(0!==i.exitCode)throw new W("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:n,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!ob(e)&&(r+=1)<3},{deadline:a})}catch(r){if(ob(r)){var n;let a=(n=await oA(e,t)).installed?!1===n.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";r.details={...r.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw r}}async function sZ(e,t,r){let a=["device","process","launch","--device",e.id,t];r?.payloadUrl&&a.push("--payload-url",r.payloadUrl),await ow(a,{action:"launch iOS app",deviceId:e.id})}async function sQ(e,t,r,a){let n=a?.maxScrolls??48,i=await e({command:"findText",text:r});if(i?.found)return{attempts:0};let o=s0(await e({command:"snapshot",interactiveOnly:!0,compact:!0}));for(let a=1;a<=n;a+=1){t(),await e({command:"swipe",direction:"up"}),await new Promise(e=>setTimeout(e,80));let n=await e({command:"findText",text:r});if(n?.found)return{attempts:a};let i=s0(await e({command:"snapshot",interactiveOnly:!0,compact:!0}));if(i===o)throw new W("COMMAND_FAILED",`scrollintoview could not find text: ${r}`,{reason:"not_found",attempts:a,stalled:!0});o=i}throw new W("COMMAND_FAILED",`scrollintoview could not find text: ${r}`,{reason:"not_found",attempts:n})}function s0(e){let t=e.nodes;return JSON.stringify(Array.isArray(t)?t:e)}async function s1(e,t,r,a,n,i,o){if("tv"===t.target)return s4(await e(t,{command:"swipe",direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left";default:return e}}(n),appBundleId:r.appBundleId},a),i);let s=o??await s2(e,t,r,a),l=is({direction:n,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return s4(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:r.appBundleId},a),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function s2(e,t,r,a){let n=await e(t,{command:"interactionFrame",appBundleId:r.appBundleId},a),i=s3(n.x),o=s3(n.y),s=s3(n.referenceWidth),l=s3(n.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new W("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function s3(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function s4(e,t){var r;let{x1:a,y1:n,x2:i,y2:o}={x1:s3((r=e).x),y1:s3(r.y),x2:s3(r.x2),y2:s3(r.y2)},s=s3(e.referenceWidth),l=s3(e.referenceHeight),d=void 0!==a&&void 0!==i?Math.round(Math.abs(i-a)):void 0,u=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:d&&d>0?d:u&&u>0?u:void 0;return{...void 0!==a?{x1:a}:{},...void 0!==n?{y1:n}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}function s5(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}function s8(){return"wayland"===s5()}let s6=null;async function s9(){if(s6)return s6;let e=s5();if("wayland"===e){if(await Y("ydotool"))return s6={tool:"ydotool",display:e};throw new W("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await Y("xdotool"))return s6={tool:"xdotool",display:e};throw new W("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function s7(...e){await $("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function le(...e){await $("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function lt(e,t){let{tool:r}=await s9();"xdotool"===r?await s7("mousemove","--sync",String(e),String(t)):await le("mousemove","--absolute","-x",String(e),"-y",String(t))}async function lr(e,t){let{tool:r}=await s9();"xdotool"===r?await s7("key","--clearmodifiers",e):await le("key",...t)}async function la(e,t,r,a){await lt(e,t);let{tool:n}=await s9();"xdotool"===n?await s7("click",r):await le("click",a)}async function ln(e,t){await la(e,t,"1","0xC0")}async function li(e,t){await la(e,t,"3","0xC1")}async function lo(e,t){await la(e,t,"2","0xC2")}async function ls(e,t){let{tool:r}=await s9();await lt(e,t),"xdotool"===r?await s7("click","--repeat","2","1"):(await le("click","0xC0"),await le("click","0xC0"))}async function ll(e,t,r=800){let{tool:a}=await s9();await lt(e,t),"xdotool"===a?(await s7("mousedown","1"),await lm(r),await s7("mouseup","1")):(await le("click","--down","0xC0"),await lm(r),await le("click","--up","0xC0"))}async function ld(e,t){await ln(e,t)}async function lu(e,t,r,a,n=300){let{tool:i}=await s9();await lt(e,t),"xdotool"===i?(await s7("mousedown","1"),await s7("mousemove","--sync",String(r),String(a)),await lm(n),await s7("mouseup","1")):(await le("click","--down","0xC0"),await le("mousemove","--absolute","-x",String(r),"-y",String(a)),await lm(n),await le("click","--up","0xC0"))}async function lc(e,t){let{tool:r}=await s9(),a=5;if(t?.pixels!=null?a="xdotool"===r?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===r)await s7("click","--repeat",String(a),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-a):String(a);await le("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await le("mousemove","--wheel","-x",t)}}async function lp(e,t=0){let{tool:r}=await s9();if("xdotool"===r){let r=["type"];t>0&&r.push("--delay",String(t)),r.push("--clearmodifiers","--",e),await s7(...r)}else await le("type","--",e)}async function lf(e,t,r,a=0){await ln(e,t),await lm(100),await lr("ctrl+a",["29:1","30:1","30:0","29:0"]),await lm(50),await lp(r,a)}function lm(e){return new Promise(t=>setTimeout(t,e))}let lh=null;async function lw(){if(lh)return lh;if(s8()){if(await Y("grim"))return lh={tool:"grim",display:"wayland"};if(await Y("gnome-screenshot"))return lh={tool:"gnome-screenshot",display:"wayland"};throw new W("TOOL_MISSING","grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.")}if(await Y("scrot"))return lh={tool:"scrot",display:"x11"};if(await Y("import"))return lh={tool:"import",display:"x11"};if(await Y("gnome-screenshot"))return lh={tool:"gnome-screenshot",display:"x11"};throw new W("TOOL_MISSING","scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager.")}async function lg(e){let{tool:t}=await lw();switch(t){case"grim":await $("grim",[e]);break;case"scrot":await $("scrot",[e]);break;case"import":await $("import",["-window","root",e]);break;case"gnome-screenshot":await $("gnome-screenshot",["-f",e])}}async function ly(e){if(e.includes("://")||e.startsWith("/"))return void await $("xdg-open",[e]);if(await Y(e)){$(e,[],{allowFailure:!0}).catch(t=>{ep({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await new Promise(e=>setTimeout(e,500));return}await $("xdg-open",[e],{allowFailure:!0})}async function lv(e){await Y("wmctrl")?await $("wmctrl",["-c",e],{allowFailure:!0}):await $("pkill",["-x",e],{allowFailure:!0})}async function lI(){await lr("alt+Left",["56:1","105:1","105:0","56:0"])}async function lb(){await lr("super+d",["125:1","32:1","32:0","125:0"])}let lA=null;async function lS(){if(lA)return lA;if(s8()){if(await Y("wl-paste"))return lA={tool:"wl-clipboard",display:"wayland"};throw new W("TOOL_MISSING","wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.")}if(await Y("xclip"))return lA={tool:"xclip",display:"x11"};if(await Y("xsel"))return lA={tool:"xsel",display:"x11"};throw new W("TOOL_MISSING","xclip or xsel is required for clipboard access on X11. Install via your package manager.")}async function lN(){let{tool:e}=await lS();switch(e){case"wl-clipboard":return(await $("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await $("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await $("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function l_(e){let{tool:t}=await lS();switch(t){case"wl-clipboard":await $("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await $("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await $("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}async function lx(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:c(),kind:"device",target:"desktop",booted:!0}]}let lD={"push button":"Button","toggle button":"Button","push button menu":"Button",label:"StaticText",static:"StaticText",caption:"StaticText",text:"TextField",entry:"TextField","password text":"TextField","spin button":"TextField",terminal:"TextArea","document text":"TextArea",paragraph:"TextArea",frame:"Window",window:"Window",dialog:"Dialog",alert:"Alert","file chooser":"Dialog","color chooser":"Dialog","font chooser":"Dialog",panel:"Group",filler:"Group",section:"Group",form:"Group",grouping:"Group","layered pane":"Group","glass pane":"Group","root pane":"Group","option pane":"Group","internal frame":"Group","desktop frame":"Group","block quote":"Group",article:"Group",comment:"Group",landmark:"Group",log:"Group",marquee:"Group",math:"Group",notification:"Group","content deletion":"Group","content insertion":"Group",mark:"Group",suggestion:"Group","scroll pane":"ScrollArea","scroll bar":"ScrollBar","menu bar":"MenuBar",menu:"Menu","popup menu":"Menu","menu item":"MenuItem","check menu item":"MenuItem","radio menu item":"MenuItem","tearoff menu item":"MenuItem","check box":"CheckBox","radio button":"RadioButton",switch:"Switch","combo box":"ComboBox","page tab":"Tab","page tab list":"TabList",table:"Table","tree table":"Table","table cell":"Cell","table row":"Row","table column header":"Cell","table row header":"Cell","column header":"Cell","row header":"Cell",list:"List","list item":"ListItem","list box":"List",tree:"Tree","tree item":"TreeItem","description list":"List","description term":"ListItem","description value":"ListItem","tool bar":"Toolbar","status bar":"StatusBar","info bar":"StatusBar",slider:"Slider","progress bar":"ProgressBar","level bar":"ProgressBar",image:"Image",icon:"Image",animation:"Image",canvas:"Image","drawing area":"Image",video:"Video",audio:"Audio",link:"Link",hyperlink:"Link",separator:"Separator",application:"Application","tool tip":"Tooltip",timer:"Timer",heading:"Heading",footnote:"Footnote","title bar":"TitleBar","date editor":"DateEditor",rating:"Slider"},lM="atspi-dump.py",lk=null;async function lE(e,t={}){let r;if("linux"!==process.platform)throw new W("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await Y("python3"))throw new W("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let a=t.maxNodes??1500,n=t.maxDepth??12,i=t.maxApps??24,o=[function(){if(lk)return lk;let e=p.dirname(w(import.meta.url));for(let t=0;t<5;t++){let r=p.join(e,"src","platforms","linux",lM);if(s.existsSync(r))return lk=r,r;if(0===t){let t=p.join(e,lM);if(s.existsSync(t))return lk=t,t}e=p.dirname(e)}throw new W("TOOL_MISSING",`Cannot find ${lM}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(a),"--max-depth",String(n),"--max-apps",String(i)],l=await $("python3",o,{allowFailure:!0,timeoutMs:3e4});if(0!==l.exitCode){let e=l.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new W("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new W("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${l.exitCode}): ${e||l.stdout}`)}try{r=JSON.parse(l.stdout)}catch{throw new W("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${l.stdout.slice(0,200)}`)}if(r.error)throw new W("COMMAND_FAILED",`AT-SPI2: ${r.error}`);return{nodes:(r.nodes??[]).map(e=>{let t,r;return{index:e.index,type:(r=lD[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:r.truncated,surface:e}}async function lO(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&ep({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),r=await lE(t);return{nodes:r.nodes,truncated:r.truncated}}function lL(e){return e?.clickButton??"primary"}function lC(e){return"primary"===e.button?null:"click"!==e.commandLabel?new W("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new W("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new W("UNSUPPORTED_OPERATION","click --button middle is not supported by the macOS runner yet"):"number"==typeof e.count||"number"==typeof e.intervalMs||"number"==typeof e.holdMs||"number"==typeof e.jitterPx||!0===e.doubleTap?new W("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}let lP=/^[A-Za-z0-9_.:-]{1,64}$/,lR=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function lT(e,t,r,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<r||e>a)throw new W("INVALID_ARGS",`${t} must be an integer between ${r} and ${a}`);return e}async function l$(e,t,r){for(let a=0;a<e;a+=1)await r(a),a<e-1&&t>0&&await lF(t)}async function lF(e){await new Promise(t=>setTimeout(t,e))}function lU(e,t){let r,a=t?.subject??"Payload",n=e.trim();if(!n)throw new W("INVALID_ARGS",`${a} cannot be empty`);let i=t?.expandPath?t.expandPath(n,t.cwd):n;try{if(!s.statSync(i).isFile())throw new W("INVALID_ARGS",`${a} path is not a file: ${i}`);return{kind:"file",path:i}}catch(t){if(t instanceof W)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new W("INVALID_ARGS",`${a} file is not readable: ${i}`);if(e&&"ENOENT"!==e)throw new W("COMMAND_FAILED",`Unable to read ${a} file: ${i}`,{cause:String(t)})}if((r=n.trim()).startsWith("{")&&r.endsWith("}")||r.startsWith("[")&&r.endsWith("]"))return{kind:"inline",text:n};throw new W("INVALID_ARGS",`${a} file not found: ${i}`)}async function lG(e){let t=lU(e,{subject:"Push payload"}),r="inline"===t.kind?t.text:await lV(t.path);try{let e=JSON.parse(r);if(!e||"object"!=typeof e||Array.isArray(e))throw new W("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof W)throw t;throw new W("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function lV(e){try{return await d.readFile(e,"utf8")}catch(r){let t=r.code;if("ENOENT"===t)throw new W("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new W("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new W("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new W("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(r)})}}let lB=e0(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),lj=/^(iphone|ipad|ipod|appletv)/i,lq=/\b(iphone|ipad|ipod)\b/i,lH=/^appletv/i,lW=["apple tv","appletv","tvos"],lz=/^==\s*(.+?)\s*==$/,lJ=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function lK(e){return(e??"").trim().toLowerCase()}function lX(e){return lK(e.hardwareProperties?.platform)}function lY(e){return e.includes("tvos")}function lZ(e){let t=lK(e);return lW.some(e=>t.includes(e))}function lQ(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function l0(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function l1(e={}){let t,r,a=e6(e.simulatorSetPath),n=e.target;try{t=await $("xcrun",te(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{r=JSON.parse(t.stdout)}catch{return null}let i=l2(r,a),o=null,s=null,l=null;for(let e of i)n&&e.target!==n||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function l2(e,t){let r=[];for(let[a,n]of Object.entries(e.devices))if(function(e){let t=lK(e);return t.includes("ios")||t.includes("tvos")}(a))for(let e of n)e.isAvailable&&r.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:lY(lK(a))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return r}function l3(e,t){let r=new Set(e.map(e=>e.id)),a=[...e];for(let e of t)r.has(e.id)||(r.add(e.id),a.push(e));return a}async function l4(){let e=null;try{e=p.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await $("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:lB});if(0!==t.exitCode)return[];let r=await d.readFile(e,"utf8");return function(e){let t=[];for(let r of e.result?.devices??[]){if(!function(e){var t;let r=lX(e);return!!(r.includes("ios")||r.includes("tvos"))||(t=l0(e),!!lj.test(t.trim())||lQ(e).some(lZ))}(r))continue;let e=r.hardwareProperties?.udid??r.identifier??"",a=r.name??r.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:a,kind:"device",target:function(e){var t;return lY(lX(e))?"tv":(t=l0(e),lH.test(t.trim())||lQ(e).some(lZ))?"tv":"mobile"}(r),booted:!0})}return t}(JSON.parse(r))}catch{return[]}finally{e&&await d.rm(e,{force:!0}).catch(()=>{})}}async function l5(){try{let e=await $("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],r=null;for(let a of e.split(/\r?\n/)){let e=a.trim();if(!e)continue;let n=lz.exec(e);if(n){r=n[1]?.trim()??null;continue}if("Devices"!==r)continue;let i=lJ.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return lZ(e)?"tv":lq.test(e.trim())?"mobile":null}(s);l&&t.push({platform:"ios",id:o,name:s,kind:"device",target:l,booted:!0})}return t}(e.stdout)}catch{return[]}}async function l8(e={}){if("darwin"!==process.platform)throw new W("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await Y("xcrun"))throw new W("TOOL_MISSING","xcrun not found in PATH");let t=e6(e.simulatorSetPath),r=await $("xcrun",te(["list","devices","-j"],{simulatorSetPath:t})),a=[];try{let e=JSON.parse(r.stdout);a=l2(e,t)}catch(e){throw new W("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(a.push({platform:"macos",id:"host-macos-local",name:u.hostname(),kind:"device",target:"desktop",booted:!0}),t)return a;let[n,i]=await Promise.all([l4(),l5()]);return a=l3(a,n),l3(a,i)}async function l6(e,t,r){let a,n=!!(t.udid||t.serial||t.deviceName);try{a=await tD(e,t,r)}catch(e){if(n||!(e instanceof W)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!n&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!a||"device"===a.kind)){let e=await l1({simulatorSetPath:r.simulatorSetPath,target:t.target});if(e)return e}if(a)return a;throw new W("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function l9(e){let t=e.platform,r=tx({simulatorSetPath:e6(e.iosSimulatorDeviceSet),platform:t,target:e.target}),a=e7(e.androidDeviceAllowlist);return await ed("resolve_target_device",async()=>{let n={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(n.target&&!n.platform)throw new W("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");if("linux"===n.platform){let e=await lx();return await tD(e,n)}if("android"===n.platform){await aX();let e=await na({serialAllowlist:a});return await tD(e,n)}if(n.platform){let e=await l8({simulatorSetPath:r});return await l6(e,n,{simulatorSetPath:r})}let i=[];try{i.push(...await na({serialAllowlist:a}))}catch{}try{i.push(...await l8({simulatorSetPath:r}))}catch{}try{i.push(...await lx())}catch{}return await tD(i,n,{simulatorSetPath:r})},{platform:t,target:e.target})}async function l7(e,t,r,a,n){let i={requestId:n?.requestId,appBundleId:n?.appBundleId,verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath},o=function(e,t){switch(e.platform){case"android":return{open:(t,r)=>nX(e,t,r?.activity),openDevice:()=>n2(e),close:t=>n3(e,t),tap:(t,r)=>iM(e,t,r),doubleTap:async(t,r)=>{await iM(e,t,r),await iM(e,t,r)},swipe:(t,r,a,n,i)=>ik(e,t,r,a,n,i),longPress:(t,r,a)=>iP(e,t,r,a),focus:(t,r)=>i$(e,t,r),type:(t,r)=>iR(e,t,r),fill:(t,r,a,n)=>iF(e,t,r,a,n),scroll:(t,r)=>iV(e,t,r),scrollIntoView:(t,r)=>iB(e,t,r),screenshot:t=>on(e,t),back:t=>iE(e),home:()=>iO(e),rotate:t=>iL(e,t),appSwitcher:()=>iC(e),readClipboard:()=>iZ(e),writeClipboard:t=>iQ(e,t),setSetting:(t,r,a,n)=>i5(e,t,r,a,n)};case"linux":return{open:e=>ly(e),openDevice:()=>Promise.resolve(),close:e=>lv(e),tap:(e,t)=>ln(e,t),doubleTap:(e,t)=>ls(e,t),swipe:(e,t,r,a,n)=>lu(e,t,r,a,n),longPress:(e,t,r)=>ll(e,t,r),focus:(e,t)=>ld(e,t),type:(e,t)=>lp(e,t),fill:(e,t,r,a)=>lf(e,t,r,a),scroll:(e,t)=>lc(e,t),scrollIntoView:()=>{throw new W("UNSUPPORTED_OPERATION","scrollIntoView not yet supported on Linux")},screenshot:e=>lg(e),back:()=>lI(),home:()=>lb(),rotate:()=>{throw new W("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new W("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>lN(),writeClipboard:e=>l_(e),setSetting:()=>{throw new W("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let r,a,{overrides:n,runnerOpts:i}=(r={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},a=()=>{if(eX(t.requestId))throw eZ()},{runnerOpts:r,overrides:{tap:async(a,n)=>await rf(e,{command:"tap",x:a,y:n,appBundleId:t.appBundleId},r),doubleTap:async(a,n)=>await rf(e,{command:"tapSeries",x:a,y:n,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},r),swipe:async(a,n,i,o,s)=>await rf(e,{command:"drag",x:a,y:n,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},r),longPress:async(a,n,i)=>await rf(e,{command:"longPress",x:a,y:n,durationMs:i,appBundleId:t.appBundleId},r),focus:async(a,n)=>await rf(e,{command:"tap",x:a,y:n,appBundleId:t.appBundleId},r),type:async(a,n)=>{await rf(e,{command:"type",text:a,delayMs:n,appBundleId:t.appBundleId},r)},fill:async(a,n,i,o)=>{let s=await rf(e,{command:"tap",x:a,y:n,appBundleId:t.appBundleId},r);return await rf(e,{command:"type",text:i,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},r),s},scroll:async(a,n)=>await s1(rf,e,t,r,a,n),scrollIntoView:async(n,i)=>await sQ(a=>rf(e,{...a,appBundleId:t.appBundleId},r),a,n,i)}});return{open:(t,r)=>sO(e,t,{appBundleId:r?.appBundleId,url:r?.url}),openDevice:()=>sL(e),close:t=>sC(e,t),screenshot:async(t,r)=>{"macos"===e.platform&&r?.surface&&"app"!==r.surface?await o0(t,{surface:r.surface,fullscreen:r.fullscreen}):await sh(e,t,r?.appBundleId,r?.fullscreen)},back:async r=>{await rf(e,{command:"system"===r?"backSystem":"backInApp",appBundleId:t.appBundleId},i)},home:async()=>{await rf(e,{command:"home",appBundleId:t.appBundleId},i)},rotate:async r=>{await rf(e,{command:"rotate",orientation:r,appBundleId:t.appBundleId},i)},appSwitcher:async()=>{await rf(e,{command:"appSwitcher",appBundleId:t.appBundleId},i)},readClipboard:()=>sF(e),writeClipboard:t=>sU(e,t),setSetting:(t,r,a,n)=>sV(e,t,r,a,n),...n}}default:throw new W("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,i);return ep({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await ed("platform_command",async()=>{switch(t){case"open":return de(e,o,r,n);case"close":{let e=r[0];if(!e)return{closed:"session",...ec("Closed session")};return await o.close(e),{app:e,...ec(`Closed: ${e}`)}}case"press":return dt(e,o,r,n,i);case"swipe":return dr(e,o,r,n,i);case"longpress":{let e=Number(r[0]),t=Number(r[1]),a=r[2]?Number(r[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new W("INVALID_ARGS","longpress requires x y [durationMs]");return await o.longPress(e,t,a),{x:e,y:t,durationMs:a,...ec(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=r.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new W("INVALID_ARGS","focus requires x y");return await o.focus(e,t),{x:e,y:t,...ec(`Focused (${e}, ${t})`)}}case"type":{let e=function(e){let t=e[0]?.trim();if(!t||!t.startsWith("@")||t.length<3)return null;let r=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(r)||/^(?:ref|node|element|el)[\w-]*$/i.test(r)?t:null}(r);if(e)throw new W("INVALID_ARGS",`type does not accept a target ref like "${e}"`,{hint:`Use fill ${e} "text" to target that field, or press ${e} then type "text" to append.`});let t=r.join(" ");if(!t)throw new W("INVALID_ARGS","type requires text");let a=lT(n?.delayMs??0,"delay-ms",0,1e4);return await o.type(t,a),{text:t,delayMs:a,...ec(dm("Typed",t))}}case"fill":{let e=Number(r[0]),t=Number(r[1]),a=r.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!a)throw new W("INVALID_ARGS","fill requires x y text");let i=lT(n?.delayMs??0,"delay-ms",0,1e4);return await o.fill(e,t,a,i),{x:e,y:t,text:a,delayMs:i,...ec(dm("Filled",a))}}case"scroll":return da(o,r,n);case"scrollintoview":{let e=r.join(" ").trim();if(!e)throw new W("INVALID_ARGS","scrollintoview requires text");let t=await o.scrollIntoView(e,{maxScrolls:n?.maxScrolls});if("number"==typeof t?.attempts)return{text:e,attempts:t.attempts,...ec(`Scrolled into view: ${e}`)};return{text:e,...ec(`Scrolled into view: ${e}`)}}case"pinch":return dn(e,r,n,i);case"trigger-app-event":{let{eventName:t,payload:a}=function(e){let t=e[0]?.trim(),r=e[1]?.trim();if(!t)throw new W("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!lP.test(t))throw new W("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new W("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let a=function(e,t){if(e)try{let r=JSON.parse(e);if(!r||"object"!=typeof r||Array.isArray(r))throw new W("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let a=JSON.stringify(r);if(Buffer.byteLength(a,"utf8")>8192)throw new W("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return r}catch(t){if(t instanceof W)throw t;throw new W("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(r,t);return{eventName:t,payload:a}}(r),i=function(e,t,r){var a;let n,i=(n=("ios"===(a=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===a?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,n?.trim()||void 0);if(!i)throw new W("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new W("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,a);return await o.open(i,{appBundleId:n?.appBundleId}),{event:t,eventUrl:i,transport:"deep-link",...ec(`Triggered app event: ${t}`)}}case"screenshot":{let e=r[0]??a??`./screenshot-${Date.now()}.png`;return await d.mkdir(p.dirname(e),{recursive:!0}),await o.screenshot(e,{appBundleId:n?.appBundleId,fullscreen:n?.screenshotFullscreen,surface:n?.surface}),{path:e,...ec(`Saved screenshot: ${e}`)}}case"back":return await o.back(n?.backMode),{action:"back",mode:n?.backMode??"in-app",...ec("Back")};case"home":return await o.home(),{action:"home",...ec("Home")};case"rotate":{let e=function(e){if(void 0===e)throw new W("INVALID_ARGS","rotate requires an orientation argument. Use portrait|portrait-upside-down|landscape-left|landscape-right.");switch(e?.trim().toLowerCase()){case"portrait":return"portrait";case"portrait-upside-down":case"upside-down":return"portrait-upside-down";case"landscape-left":case"left":return"landscape-left";case"landscape-right":case"right":return"landscape-right";default:throw new W("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}(r[0]);return await o.rotate(e),{action:"rotate",orientation:e,...ec(`Rotated to ${e}`)}}case"app-switcher":return await o.appSwitcher(),{action:"app-switcher",...ec("Opened app switcher")};case"clipboard":return di(o,r);case"keyboard":return ds(e,o,r,n,i);case"settings":return dl(e,o,r,n);case"push":return dd(e,r,n);case"snapshot":return du(e,r,n,i);case"read":return dc(e,r,n,i);default:throw new W("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function de(e,t,r,a){let n=r[0],i=r[1];if(r.length>2)throw new W("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!n)return await t.openDevice(),{app:null,...ec("Opened device")};if(void 0!==i){if("android"===e.platform)throw new W("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(aQ(n))throw new W("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!aQ(i))throw new W("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(n,{activity:a?.activity,appBundleId:a?.appBundleId,url:i}),{app:n,url:i,...ec(`Opened: ${n}`)}}return await t.open(n,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:n,...ec(`Opened: ${n}`)}}async function dt(e,t,r,a,n){let i,[o,s]=r.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new W("INVALID_ARGS","press requires x y");if("macos"===e.platform&&a?.surface&&"app"!==a.surface){let e=lL(a);if("primary"!==e)throw new W("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${a.surface} sessions.`);return await oQ(o,s,{bundleId:a.appBundleId,surface:a.surface}),{x:o,y:s,...ec(dp({x:o,y:s}))}}let l=lL(a);if("primary"!==l){let t=lC({commandLabel:"click",platform:e.platform,button:l,count:a?.count,intervalMs:a?.intervalMs,holdMs:a?.holdMs,jitterPx:a?.jitterPx,doubleTap:a?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await li(o,s):await lo(o,s):await rf(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x:o,y:s,button:l,...ec(dp({x:o,y:s,button:l}))}}let d=lT(a?.count??1,"count",1,200),u=lT(a?.intervalMs??0,"interval-ms",0,1e4),c=lT(a?.holdMs??0,"hold-ms",0,1e4),p=lT(a?.jitterPx??0,"jitter-px",0,100),f=a?.doubleTap===!0;if(f&&c>0)throw new W("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new W("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(("ios"===e.platform||"macos"===e.platform)&&d>1&&0===c&&0===p){let t=await rf(e,{command:"tapSeries",x:o,y:s,count:d,intervalMs:u,doubleTap:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...ec(dp({x:o,y:s}))}}return await l$(d,u,async e=>{let[r,a]=function(e,t){if(t<=0)return[0,0];let[r,a]=lR[e%lR.length];return[r*t,a*t]}(e,p),n=o+r,l=s+a;if(f){i??=await t.doubleTap(n,l)??void 0;return}c>0?i??=await t.longPress(n,l,c)??void 0:i??=await t.tap(n,l)??void 0}),H({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},dp({x:o,y:s}))}async function dr(e,t,r,a,n){let i=Number(r[0]),o=Number(r[1]),s=Number(r[2]),l=Number(r[3]);if([i,o,s,l].some(Number.isNaN))throw new W("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let d=lT(r[4]?Number(r[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=lT(a?.count??1,"count",1,200),p=lT(a?.pauseMs??0,"pause-ms",0,1e4),f=a?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new W("INVALID_ARGS",`Invalid pattern: ${f}`);if(("ios"===e.platform||"macos"===e.platform)&&c>1){let t=await rf(e,{command:"dragSeries",x:i,y:o,x2:s,y2:l,durationMs:u,count:c,pauseMs:p,pattern:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...ec(df(c,f))}}return await l$(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,i,o,u):await t.swipe(i,o,s,l,u)}),H({x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},df(c,f))}async function da(e,t,r){let a=t[0],n=t[1]?Number(t[1]):void 0,i=r?.pixels;if(!a)throw new W("INVALID_ARGS","scroll requires direction");if(void 0!==n&&!Number.isFinite(n))throw new W("INVALID_ARGS","scroll amount must be a number");if(void 0!==n&&void 0!==i)throw new W("INVALID_ARGS","scroll accepts either a relative amount or --pixels, not both");let o=function(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new W("INVALID_ARGS",`Unknown direction: ${e}`)}}(a),s=await e.scroll(o,{amount:n,pixels:i});return H({direction:o,...void 0!==n?{amount:n}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==n?`Scrolled ${o} by ${n}`:`Scrolled ${o}`)}async function dn(e,t,r,a){if("android"===e.platform)throw new W("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");if("macos"===e.platform&&r?.surface&&"app"!==r.surface)throw new W("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let n=Number(t[0]),i=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(n)||n<=0)throw new W("INVALID_ARGS","pinch requires scale > 0");return await rf(e,{command:"pinch",scale:n,x:i,y:o,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{scale:n,x:i,y:o,...ec(`Pinched to scale ${n}`)}}async function di(e,t){let r=(t[0]??"").toLowerCase();if("read"!==r&&"write"!==r)throw new W("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===r){if(1!==t.length)throw new W("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:r,text:await e.readClipboard()}}if(t.length<2)throw new W("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let a=t.slice(1).join(" ");return await e.writeClipboard(a),{action:r,textLength:Array.from(a).length,...ec("Clipboard updated")}}async function ds(e,t,r,a,n){let i=(r[0]??"status").toLowerCase();if("status"!==i&&"get"!==i&&"dismiss"!==i)throw new W("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(r.length>1)throw new W("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===i){let t=await iY(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type}}let t=await iX(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==i)throw new W("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await rf(e,{command:"keyboardDismiss",appBundleId:a?.appBundleId},n);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...ec(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new W("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function dl(e,t,r,a){var n;let[i,o,s,l,d]=r,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;ep({level:"debug",phase:"settings_apply",data:{setting:i,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(i,o,d??a?.appBundleId,u);return c&&"object"==typeof c?H({setting:i,state:o,...c},("string"==typeof(n=c).message&&n.message.length>0?n.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...ec(`Updated setting: ${i}`)}}async function dd(e,t,r){let a=t[0]?.trim(),n=t[1]?.trim();if(!a||!n)throw new W("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await lG(n);if("ios"===e.platform)return await sG(e,a,i),{platform:"ios",bundleId:a,...ec(`Pushed notification to ${a}`)};let o=await or(e,a,i);return{platform:"android",package:a,action:o.action,extrasCount:o.extrasCount,...ec(`Pushed notification to ${a}`)}}async function du(e,t,r,a){if("linux"===e.platform){let e=await ed("snapshot_capture",async()=>await lO(r?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await ed("snapshot_capture",async()=>await rf(e,{command:"snapshot",appBundleId:r?.appBundleId,interactiveOnly:r?.snapshotInteractiveOnly,compact:r?.snapshotCompact,depth:r?.snapshotDepth,scope:r?.snapshotScope,raw:r?.snapshotRaw},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{backend:"xctest"}),a=t.nodes??[];if(0===a.length&&"simulator"===e.kind)throw new W("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:a,truncated:t.truncated??!1,backend:"xctest"}}let n=await ed("snapshot_capture",async()=>await ib(e,{interactiveOnly:r?.snapshotInteractiveOnly,compact:r?.snapshotCompact,depth:r?.snapshotDepth,scope:r?.snapshotScope,raw:r?.snapshotRaw}),{backend:"android"});return{nodes:n.nodes??[],truncated:n.truncated??!1,backend:"android",analysis:n.analysis}}async function dc(e,t,r,a){let[n,i]=t.map(Number);if(Number.isNaN(n)||Number.isNaN(i))throw new W("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await iJ(e,n,i)??""};if("macos"===e.platform&&r?.surface&&"app"!==r.surface)return{action:"read",text:(await oZ(n,i,{bundleId:r.appBundleId,surface:r.surface})).text};let o=await rf(e,{command:"readText",x:n,y:i,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{action:"read",text:"string"==typeof o.text?o.text:"string"==typeof o.message?o.message:""}}function dp(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function df(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function dm(e,t){return`${e} ${Array.from(t).length} chars`}let dh=e=>"macos"!==e.platform,dw=e=>"macos"===e.platform||"simulator"===e.kind,dg={device:!0},dy={},dv={alert:{apple:{simulator:!0,device:!0},android:{},linux:dy,supports:dw},pinch:{apple:{simulator:!0,device:!0},android:{},linux:dy,supports:dw},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg,supports:e=>"android"===e.platform||"linux"===e.platform||"macos"===e.platform||"simulator"===e.kind},keyboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},close:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg,supports:dh},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},screenshot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},scrollintoview:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:e=>"android"===e.platform||"macos"===e.platform||"simulator"===e.kind},snapshot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg}};function dI(e,t){let r=dv[e];if(!r)return!0;let a=tN(t.platform)?r.apple:"linux"===t.platform?r.linux:r.android;return!!a&&(!r.supports||!!r.supports(t))&&!0===a[t.kind??"unknown"]}function db(e,t,r,a,n){return{requestId:n??es().requestId,appBundleId:r,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:a,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:lL(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern,maxScrolls:t?.maxScrolls}}let dA=e0(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function dS(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eO);await t(e);return}if("device"===e.kind)return void await dN(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(eD);await t(e.id)}}async function dN(e){let t=p.join(u.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=Math.max(1,Math.ceil(dA/1e3));try{let a=await $("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(r)],{allowFailure:!0,timeoutMs:dA+3e3}),n=String(a.stdout??""),i=String(a.stderr??""),o=await d_(t);if(0===a.exitCode){if(!o.parsed)throw new W("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:n,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new W("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new W("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:n,stderr:i,exitCode:a.exitCode,tunnelState:o?.tunnelState,hint:dx(n,i)})}catch(t){if(t instanceof W&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let r=t.details??{},a=String(r.stdout??""),n=String(r.stderr??""),i=Number(r.timeoutMs??dA),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new W("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:a,stderr:n,hint:a||n?dx(a,n):o},t)}throw new W("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await d.rm(t,{force:!0}).catch(()=>{})}}async function d_(e){try{let t=await d.readFile(e,"utf8"),r=JSON.parse(t),a=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let r=t.connectionProperties?.tunnelState,a=t.device?.connectionProperties?.tunnelState,n="string"==typeof r?r:"string"==typeof a?a:void 0;return n?{tunnelState:n}:{}}(r);return{parsed:!0,tunnelState:a.tunnelState}}catch{return{parsed:!1}}}function dx(e,t){let r=oI(e,t);return r||(`${e}
37
- ${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":ov)}let dD=e0(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),dM=new Map;async function dk(e){let t=await A.mkdtemp(p.join(u.tmpdir(),"agent-device-materialized-"));try{let r=await dL(e.installablePath,p.join(t,"installable")),a=e.archivePath?await dL(e.archivePath,p.join(t,"archive")):void 0,n=i.randomUUID(),o=e.ttlMs??dD,s=Date.now()+o,l=setTimeout(()=>{dE(n)},o);return dM.set(n,{rootPath:t,installablePath:r,archivePath:a,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:s,timer:l}),{materializationId:n,installablePath:r,...a?{archivePath:a}:{},expiresAt:new Date(s).toISOString()}}catch(e){throw await A.rm(t,{recursive:!0,force:!0}),e}}async function dE(e,t){let r=dM.get(e);if(!r)throw new W("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new W("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),dM.delete(e),await A.rm(r.rootPath,{recursive:!0,force:!0})}async function dO(e){let t=Array.from(dM.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await dE(e)}))}async function dL(e,t){let r=await A.stat(e);await A.mkdir(t,{recursive:!0});let a=p.join(t,p.basename(e));return r.isDirectory()?await A.cp(e,a,{recursive:!0}):await A.copyFile(e,a),a}async function dC(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new W("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await dS(e.session.device),e.session.device}if(!r)throw new W("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await l9(e.flags??{});return await dS(a),a}async function dP(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);try{let e,i,o,s=(i=function(e){let t=e.meta?.installSource;if(!t)throw new W("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new W("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new W("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===i.kind?{source:{kind:"path",path:ah(o,t.meta?.tenantId)},cleanup:()=>{aw(o)}}:{source:i,cleanup:()=>{}}),l=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new W("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await dC({session:n,flags:t.flags});if(!dI("install",d))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"install_from_source is not supported on this device"}};let u=eY(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:i}=await Promise.resolve(eO),{prepareIosInstallArtifact:o}=await Promise.resolve(eL),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await dk({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:n?r:void 0,ttlMs:l.ttlMs})),await i(d,c.installablePath),!c.bundleId)throw new W("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let o={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},s=H(o,dR(o));return n&&a.recordAction(n,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await dE(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await Promise.resolve(ek),{installAndroidInstallablePathAndResolvePackageName:p}=await Promise.resolve(eM),f=await c(s.source,{signal:u});try{l.enabled&&(e=await dk({archivePath:f.archivePath,installablePath:f.installablePath,tenantId:t.meta?.tenantId,sessionName:n?r:void 0,ttlMs:l.ttlMs}));let i=await p(d,f.installablePath,f.packageName);if(!i)throw new W("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await Promise.resolve(eM),s=o(i),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:i,...s?{appName:s}:{},launchTarget:i,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=H(u,dR(u));return n&&a.recordAction(n,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await dE(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await f.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:ea(e)}}}function dR(e){return`Installed: ${eN(e)}`}async function dT(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new W("INVALID_ARGS","release_materialized_paths requires a materializationId");return await dE(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:ea(e)}}}let d$=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),dF=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function dU(e,t,r){return t||dG(r)?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} requires an active session or an explicit device selector (e.g. --platform ios).`}}}function dG(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function dV(e){return"ios"===e.platform&&"simulator"===e.kind}async function dB(e,t){dV(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function dj(e){let t=dG(e.flags)||!e.session?await l9(e.flags??{}):await dq(e.session.device);return!1!==e.ensureReady&&await dS(t),t}async function dq(e){if("ios"!==e.platform||"simulator"!==e.kind||"darwin"!==process.platform)return e;let t={platform:"ios",target:e.target,udid:e.id,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}};try{return await l9(t)}catch(e){if(!(e instanceof W)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await l9({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function dH(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let dW="shared_prefs/ReactNativeDevPrefs.xml",dz="debug_http_host",dJ="dev_server_https",dK="RCT_jsLocation",dX="RCT_packager_scheme",dY="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",dZ='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function dQ(e){return void 0!==d0(e)}function d0(e){if(!e)return;let t=ur(e.metroHost),r=un(e.metroPort),a="http",n=ur(e.bundleUrl);if(n){var i;let e;try{e=new h(n)}catch(e){throw new W("INVALID_ARGS",`Invalid runtime bundle URL: ${n}`,{},e)}("http:"===e.protocol||"https:"===e.protocol)&&(t??=ur(e.hostname),r??=un(e.port.length>0?Number(e.port):"https:"===(i=e.protocol)?443:"http:"===i?80:void 0),a="https:"===e.protocol?"https":"http")}if(t&&r)return{host:t,port:r,scheme:a}}async function d1(e){let{device:t,appId:r,runtime:a}=e;if(!r)return;let n=d0(a);if(n){if("android"===t.platform)return void await d3(t,r,n);"ios"===t.platform&&"simulator"===t.kind&&await d6(t,r,n)}}async function d2(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await d4(t,r);"ios"===t.platform&&"simulator"===t.kind&&await d9(t,r)}}async function d3(e,t,r){var a,n,i,o,s,l;let d,u;ua(t);let c=(a=await d5(e,t),n=dz,i=`${r.host}:${r.port}`,d=` <string name="${ui(n)}">${ui(i)}</string>`,ue(ut(a,n),d));o=c,s=dJ,l="https"===r.scheme,u=` <boolean name="${ui(s)}" value="${l?"true":"false"}" />`,c=ue(ut(o,s),u),await d8(e,t,c)}async function d4(e,t){ua(t);let r=await d5(e,t),a=ut(r,dz),n=ut(a,dJ);n!==r&&await d8(e,t,n)}async function d5(e,t){let r=await $("adb",aK(e,["shell","run-as",t,"cat",dW]),{allowFailure:!0});return 0!==r.exitCode?dZ:d7(r.stdout)}async function d8(e,t,r){let a=aK(e,["shell","run-as",t,"id"]),n=await $("adb",a,{allowFailure:!0});if(0!==n.exitCode){let e=uo(n.stdout,n.stderr);throw new W("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:a,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:e?dY:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await $("adb",aK(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await $("adb",aK(e,["shell","run-as",t,"tee",dW]),{stdin:r.trimEnd()})}catch(a){let e=j(a);if("TOOL_MISSING"===e.code)throw e;let r=uo("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new W("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?dY:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function d6(e,t,r){await $("xcrun",tt(e,["spawn",e.id,"defaults","write",t,dK,"-string",`${r.host}:${r.port}`])),await $("xcrun",tt(e,["spawn",e.id,"defaults","write",t,dX,"-string",r.scheme]))}async function d9(e,t){await $("xcrun",tt(e,["spawn",e.id,"defaults","delete",t,dK]),{allowFailure:!0}),await $("xcrun",tt(e,["spawn",e.id,"defaults","delete",t,dX]),{allowFailure:!0})}function d7(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
30
+ ${n}`.toLowerCase();return i.includes("timeout waiting for screen surfaces")||i.includes("nsposixerrordomain")&&i.includes("code=60")&&i.includes("screenshot")||i.includes("timed out")&&i.includes("screenshot")}let sx={settings:"com.apple.Preferences"},sD=null;function sM(e,t,r){return F("xcrun",tt(e,t),r)}function sk(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function sE(e,t){if("macos"===e.platform)return await o5(t);let r=t.trim();if(r.includes("."))return r;let a=sx[r.toLowerCase()];if(a)return a;let n=("simulator"===e.kind?await sj(e):await og(e,"all")).filter(e=>e.name.toLowerCase()===r.toLowerCase());if(1===n.length)return n[0].bundleId;if(n.length>1)throw new O("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:n});throw new O("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function sO(e,t,r){if("macos"===e.platform)return void await o8(e,t,r);let a=r?.url?.trim();if(a){if(!aQ(a))throw new O("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await o_(e),await sM(e,["openurl",e.id,a]);return}let n=a0(r?.appBundleId??await sE(e,t),a);if(!n)throw new O("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await sZ(e,n,{payloadUrl:a});return}let n=t.trim();if(aQ(n)){if("simulator"===e.kind){await o_(e),await sM(e,["openurl",e.id,n]);return}let t=a0(r?.appBundleId,n);if(!t)throw new O("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await sZ(e,t,{payloadUrl:n});return}let i=r?.appBundleId??await sE(e,t);"simulator"===e.kind?await sY(e,i):await sZ(e,i)}async function sL(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await oD(e)&&await o_(e)}async function sC(e,t){if("macos"===e.platform)return void await o6(e,t);let r=await sE(e,t);if("simulator"===e.kind){await o_(e);let t=tt(e,["terminate",e.id,r]),a=await F("xcrun",t,{allowFailure:!0});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new O("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await ow(["device","process","terminate","--device",e.id,r],{action:"terminate iOS app",deviceId:e.id})}async function sP(e,t){let r=await sE(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,r],a=await F("xcrun",t,{allowFailure:!0,timeoutMs:oc});if(0!==a.exitCode){let n=String(a.stdout??""),i=String(a.stderr??"");if(!sk(`${n}
31
+ ${i}`.toLowerCase()))throw new O("COMMAND_FAILED",`Failed to uninstall iOS app ${r}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:n,stderr:i,deviceId:e.id,hint:oI(n,i)??ov})}return{bundleId:r}}await o_(e);let a=await sM(e,["uninstall",e.id,r],{allowFailure:!0});if(0!==a.exitCode&&!sk(`${a.stdout}
32
+ ${a.stderr}`.toLowerCase()))throw new O("COMMAND_FAILED",`simctl uninstall failed for ${r}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:r}}async function sR(e,t,r){let a=await ok({kind:"path",path:t},r);try{return await s$(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function sT(e,t,r){let{bundleId:a}=await sP(e,t);return await sR(e,r,{appIdentifierHint:t}),{bundleId:a}}async function s$(e,t){"simulator"!==e.kind?await ow(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await o_(e),await sM(e,["install",e.id,t]))}async function sF(e){if("macos"===e.platform)return await o9();oS(e,"clipboard"),await o_(e);let t=await sM(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new O("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function sU(e,t){if("macos"===e.platform)return void await o7(t);oS(e,"clipboard"),await o_(e);let r=await sM(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==r.exitCode)throw new O("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function sG(e,t,r){oS(e,"push"),await o_(e);let a=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-ios-push-")),n=p.join(a,"payload.apns");try{await d.writeFile(n,`${JSON.stringify(r)}
33
+ `,"utf8"),await sM(e,["push",e.id,t,n])}finally{await d.rm(a,{recursive:!0,force:!0})}}async function sV(e,t,r,a,n){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await st(r);if("permission"===e){let e=i2(r);if("deny"===e)throw new O("INVALID_ARGS",ea("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new O("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(n?.permissionTarget);return await oK(e,t)}throw new O("INVALID_ARGS",ea(t))}oS(e,"settings"),await o_(e);let i=t.toLowerCase();switch(i){case"wifi":{let t=sq(r);await sM(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(sq(r)?await sM(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await sM(e,["status_bar",e.id,"clear"]));case"location":{let t=sq(r);if(!a)throw new O("INVALID_ARGS","location setting requires an active app in session");await sM(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=sW[i],a=function(e,t){let r=e.trim().toLowerCase();if("match"===r)return"match";if("nonmatch"===r)return"nonmatch";if("enroll"===r)return"enroll";if("unenroll"===r)return"unenroll";throw new O("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(r,i);await sX(e,a,{settingName:i,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await sH(e,r);await sM(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!a)throw new O("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=i2(r))?"revoke":o,i=function(e,t){let r=i3(e);if("photos"!==r&&t?.trim())throw new O("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return"camera";if("microphone"===r)return"microphone";if("contacts"===r)return"contacts";if("contacts-limited"===r)return"contacts-limited";if("notifications"===r)return"notifications";if("calendar"===r)return"calendar";if("location"===r)return"location";if("location-always"===r)return"location-always";if("media-library"===r)return"media-library";if("motion"===r)return"motion";if("reminders"===r)return"reminders";if("siri"===r)return"siri";if("photos"===r){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new O("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new O("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(n?.permissionTarget,n?.permissionMode);await sz(e,t,i,a);return}default:throw new O("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function sB(e,t="all"){return"macos"===e.platform?await sr(t):"simulator"===e.kind?oP(await sj(e),t):await og(e,t)}async function sj(e){let t=(await sM(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let r=null;if(t.startsWith("{"))try{r=JSON.parse(t)}catch{r=null}if(!r&&t.startsWith("{"))try{let e=await F("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>({bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e})):[]}function sq(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new O("INVALID_ARGS",`Invalid setting state: ${e}`)}async function sH(e,t){let r=i4(t);if("toggle"!==r)return r;let a=await sM(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new O("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let n=function(e,t){let r=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
34
+ ${t}`);if(!r)return null;let a=r[1].toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!n)throw new O("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===n?"light":"dark"}let sW={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function sz(e,t,r,a){let n=await sK(e);if(!n.has(r))throw new O("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(n).sort().join(", ")}`});let i=["privacy",e.id,t,r,a],o="notifications"===r;if(!("reset"===t&&o))try{await sM(e,i);return}catch(t){if(!(o&&sJ(t)))throw t;throw new O("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:a,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await sM(e,i);return}catch(e){if(!sJ(e))throw e}try{await sM(e,["privacy",e.id,"reset","all",a])}catch(t){throw new O("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:a,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function sJ(e){if(!(e instanceof O)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function sK(e){let r=e6(e.simulatorSetPath),a=`${process.env.PATH??""}::${r??""}`;if(sD&&t===a)return sD;let n=await sM(e,["privacy","help"],{allowFailure:!0}),i=function(e){let t=new Set,r=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){r=!0;continue}if(!r)continue;if(e.startsWith("bundle identifier"))break;let n=/^([a-z-]+)\s+-\s+/.exec(e);n&&t.add(n[1])}return t}(`${n.stdout}
35
+ ${n.stderr}`);if(0===i.size)throw new O("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return sD=i,t=a,i}async function sX(e,t,r){let a=function(e,t,r){let a=r.length>0?r:["face"];switch(t){case"match":return a.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return a.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,r.modalityAliases),n=[];for(let t of a){let r=tt(e,t),a=await F("xcrun",r,{allowFailure:!0});if(0===a.exitCode)return;n.push({args:r,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let i=n.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(n.length>0&&n.every(e=>{var t,r;let a;return t=e.stdout,r=e.stderr,(a=`${t}
36
+ ${r}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new O("UNSUPPORTED_OPERATION",`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:i});throw new O("COMMAND_FAILED",`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:i})}async function sY(e,t){await o_(e);let r=0,a=eF.fromTimeoutMs(ou);try{await eU(async({deadline:r})=>{var a;if(r?.isExpired())throw new O("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:ou});let n=(a=["launch",e.id,t],tt(e,a)),i=await F("xcrun",n,{allowFailure:!0});if(0!==i.exitCode)throw new O("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:n,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!ob(e)&&(r+=1)<3},{deadline:a})}catch(r){if(ob(r)){var n;let a=(n=await oA(e,t)).installed?!1===n.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";r.details={...r.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw r}}async function sZ(e,t,r){let a=["device","process","launch","--device",e.id,t];r?.payloadUrl&&a.push("--payload-url",r.payloadUrl),await ow(a,{action:"launch iOS app",deviceId:e.id})}async function sQ(e,t,r,a){let n=a?.maxScrolls??48,i=await e({command:"findText",text:r});if(i?.found)return{attempts:0};let o=s0(await e({command:"snapshot",interactiveOnly:!0,compact:!0}));for(let a=1;a<=n;a+=1){t(),await e({command:"swipe",direction:"up"}),await new Promise(e=>setTimeout(e,80));let n=await e({command:"findText",text:r});if(n?.found)return{attempts:a};let i=s0(await e({command:"snapshot",interactiveOnly:!0,compact:!0}));if(i===o)throw new O("COMMAND_FAILED",`scrollintoview could not find text: ${r}`,{reason:"not_found",attempts:a,stalled:!0});o=i}throw new O("COMMAND_FAILED",`scrollintoview could not find text: ${r}`,{reason:"not_found",attempts:n})}function s0(e){let t=e.nodes;return JSON.stringify(Array.isArray(t)?t:e)}async function s1(e,t,r,a,n,i,o){if("tv"===t.target)return s4(await e(t,{command:"swipe",direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left";default:return e}}(n),appBundleId:r.appBundleId},a),i);let s=o??await s2(e,t,r,a),l=is({direction:n,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return s4(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:r.appBundleId},a),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function s2(e,t,r,a){let n=await e(t,{command:"interactionFrame",appBundleId:r.appBundleId},a),i=s3(n.x),o=s3(n.y),s=s3(n.referenceWidth),l=s3(n.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new O("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function s3(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function s4(e,t){var r;let{x1:a,y1:n,x2:i,y2:o}={x1:s3((r=e).x),y1:s3(r.y),x2:s3(r.x2),y2:s3(r.y2)},s=s3(e.referenceWidth),l=s3(e.referenceHeight),d=void 0!==a&&void 0!==i?Math.round(Math.abs(i-a)):void 0,u=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:d&&d>0?d:u&&u>0?u:void 0;return{...void 0!==a?{x1:a}:{},...void 0!==n?{y1:n}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}function s5(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}function s8(){return"wayland"===s5()}let s6=null;async function s9(){if(s6)return s6;let e=s5();if("wayland"===e){if(await x("ydotool"))return s6={tool:"ydotool",display:e};throw new O("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await x("xdotool"))return s6={tool:"xdotool",display:e};throw new O("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function s7(...e){await F("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function le(...e){await F("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function lt(e,t){let{tool:r}=await s9();"xdotool"===r?await s7("mousemove","--sync",String(e),String(t)):await le("mousemove","--absolute","-x",String(e),"-y",String(t))}async function lr(e,t){let{tool:r}=await s9();"xdotool"===r?await s7("key","--clearmodifiers",e):await le("key",...t)}async function la(e,t,r,a){await lt(e,t);let{tool:n}=await s9();"xdotool"===n?await s7("click",r):await le("click",a)}async function ln(e,t){await la(e,t,"1","0xC0")}async function li(e,t){await la(e,t,"3","0xC1")}async function lo(e,t){await la(e,t,"2","0xC2")}async function ls(e,t){let{tool:r}=await s9();await lt(e,t),"xdotool"===r?await s7("click","--repeat","2","1"):(await le("click","0xC0"),await le("click","0xC0"))}async function ll(e,t,r=800){let{tool:a}=await s9();await lt(e,t),"xdotool"===a?(await s7("mousedown","1"),await lm(r),await s7("mouseup","1")):(await le("click","--down","0xC0"),await lm(r),await le("click","--up","0xC0"))}async function ld(e,t){await ln(e,t)}async function lu(e,t,r,a,n=300){let{tool:i}=await s9();await lt(e,t),"xdotool"===i?(await s7("mousedown","1"),await s7("mousemove","--sync",String(r),String(a)),await lm(n),await s7("mouseup","1")):(await le("click","--down","0xC0"),await le("mousemove","--absolute","-x",String(r),"-y",String(a)),await lm(n),await le("click","--up","0xC0"))}async function lc(e,t){let{tool:r}=await s9(),a=5;if(t?.pixels!=null?a="xdotool"===r?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===r)await s7("click","--repeat",String(a),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-a):String(a);await le("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await le("mousemove","--wheel","-x",t)}}async function lp(e,t=0){let{tool:r}=await s9();if("xdotool"===r){let r=["type"];t>0&&r.push("--delay",String(t)),r.push("--clearmodifiers","--",e),await s7(...r)}else await le("type","--",e)}async function lf(e,t,r,a=0){await ln(e,t),await lm(100),await lr("ctrl+a",["29:1","30:1","30:0","29:0"]),await lm(50),await lp(r,a)}function lm(e){return new Promise(t=>setTimeout(t,e))}let lh=null;async function lw(){if(lh)return lh;if(s8()){if(await x("grim"))return lh={tool:"grim",display:"wayland"};if(await x("gnome-screenshot"))return lh={tool:"gnome-screenshot",display:"wayland"};throw new O("TOOL_MISSING","grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.")}if(await x("scrot"))return lh={tool:"scrot",display:"x11"};if(await x("import"))return lh={tool:"import",display:"x11"};if(await x("gnome-screenshot"))return lh={tool:"gnome-screenshot",display:"x11"};throw new O("TOOL_MISSING","scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager.")}async function lg(e){let{tool:t}=await lw();switch(t){case"grim":await F("grim",[e]);break;case"scrot":await F("scrot",[e]);break;case"import":await F("import",["-window","root",e]);break;case"gnome-screenshot":await F("gnome-screenshot",["-f",e])}}async function ly(e){if(e.includes("://")||e.startsWith("/"))return void await F("xdg-open",[e]);if(await x(e)){F(e,[],{allowFailure:!0}).catch(t=>{U({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await new Promise(e=>setTimeout(e,500));return}await F("xdg-open",[e],{allowFailure:!0})}async function lv(e){await x("wmctrl")?await F("wmctrl",["-c",e],{allowFailure:!0}):await F("pkill",["-x",e],{allowFailure:!0})}async function lI(){await lr("alt+Left",["56:1","105:1","105:0","56:0"])}async function lb(){await lr("super+d",["125:1","32:1","32:0","125:0"])}let lA=null;async function lS(){if(lA)return lA;if(s8()){if(await x("wl-paste"))return lA={tool:"wl-clipboard",display:"wayland"};throw new O("TOOL_MISSING","wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.")}if(await x("xclip"))return lA={tool:"xclip",display:"x11"};if(await x("xsel"))return lA={tool:"xsel",display:"x11"};throw new O("TOOL_MISSING","xclip or xsel is required for clipboard access on X11. Install via your package manager.")}async function lN(){let{tool:e}=await lS();switch(e){case"wl-clipboard":return(await F("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await F("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await F("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function l_(e){let{tool:t}=await lS();switch(t){case"wl-clipboard":await F("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await F("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await F("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}async function lx(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:c(),kind:"device",target:"desktop",booted:!0}]}let lD={"push button":"Button","toggle button":"Button","push button menu":"Button",label:"StaticText",static:"StaticText",caption:"StaticText",text:"TextField",entry:"TextField","password text":"TextField","spin button":"TextField",terminal:"TextArea","document text":"TextArea",paragraph:"TextArea",frame:"Window",window:"Window",dialog:"Dialog",alert:"Alert","file chooser":"Dialog","color chooser":"Dialog","font chooser":"Dialog",panel:"Group",filler:"Group",section:"Group",form:"Group",grouping:"Group","layered pane":"Group","glass pane":"Group","root pane":"Group","option pane":"Group","internal frame":"Group","desktop frame":"Group","block quote":"Group",article:"Group",comment:"Group",landmark:"Group",log:"Group",marquee:"Group",math:"Group",notification:"Group","content deletion":"Group","content insertion":"Group",mark:"Group",suggestion:"Group","scroll pane":"ScrollArea","scroll bar":"ScrollBar","menu bar":"MenuBar",menu:"Menu","popup menu":"Menu","menu item":"MenuItem","check menu item":"MenuItem","radio menu item":"MenuItem","tearoff menu item":"MenuItem","check box":"CheckBox","radio button":"RadioButton",switch:"Switch","combo box":"ComboBox","page tab":"Tab","page tab list":"TabList",table:"Table","tree table":"Table","table cell":"Cell","table row":"Row","table column header":"Cell","table row header":"Cell","column header":"Cell","row header":"Cell",list:"List","list item":"ListItem","list box":"List",tree:"Tree","tree item":"TreeItem","description list":"List","description term":"ListItem","description value":"ListItem","tool bar":"Toolbar","status bar":"StatusBar","info bar":"StatusBar",slider:"Slider","progress bar":"ProgressBar","level bar":"ProgressBar",image:"Image",icon:"Image",animation:"Image",canvas:"Image","drawing area":"Image",video:"Video",audio:"Audio",link:"Link",hyperlink:"Link",separator:"Separator",application:"Application","tool tip":"Tooltip",timer:"Timer",heading:"Heading",footnote:"Footnote","title bar":"TitleBar","date editor":"DateEditor",rating:"Slider"},lM="atspi-dump.py",lk=null;async function lE(e,t={}){let r;if("linux"!==process.platform)throw new O("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await x("python3"))throw new O("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let a=t.maxNodes??1500,n=t.maxDepth??12,i=t.maxApps??24,o=[function(){if(lk)return lk;let e=p.dirname(w(import.meta.url));for(let t=0;t<5;t++){let r=p.join(e,"src","platforms","linux",lM);if(s.existsSync(r))return lk=r,r;if(0===t){let t=p.join(e,lM);if(s.existsSync(t))return lk=t,t}e=p.dirname(e)}throw new O("TOOL_MISSING",`Cannot find ${lM}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(a),"--max-depth",String(n),"--max-apps",String(i)],l=await F("python3",o,{allowFailure:!0,timeoutMs:3e4});if(0!==l.exitCode){let e=l.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new O("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new O("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${l.exitCode}): ${e||l.stdout}`)}try{r=JSON.parse(l.stdout)}catch{throw new O("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${l.stdout.slice(0,200)}`)}if(r.error)throw new O("COMMAND_FAILED",`AT-SPI2: ${r.error}`);return{nodes:(r.nodes??[]).map(e=>{let t,r;return{index:e.index,type:(r=lD[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:r.truncated,surface:e}}async function lO(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&U({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),r=await lE(t);return{nodes:r.nodes,truncated:r.truncated}}function lL(e){return e?.clickButton??"primary"}function lC(e){return"primary"===e.button?null:"click"!==e.commandLabel?new O("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new O("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new O("UNSUPPORTED_OPERATION","click --button middle is not supported by the macOS runner yet"):"number"==typeof e.count||"number"==typeof e.intervalMs||"number"==typeof e.holdMs||"number"==typeof e.jitterPx||!0===e.doubleTap?new O("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}let lP=/^[A-Za-z0-9_.:-]{1,64}$/,lR=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function lT(e,t,r,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<r||e>a)throw new O("INVALID_ARGS",`${t} must be an integer between ${r} and ${a}`);return e}async function l$(e,t,r){for(let a=0;a<e;a+=1)await r(a),a<e-1&&t>0&&await lF(t)}async function lF(e){await new Promise(t=>setTimeout(t,e))}function lU(e,t){let r,a=t?.subject??"Payload",n=e.trim();if(!n)throw new O("INVALID_ARGS",`${a} cannot be empty`);let i=t?.expandPath?t.expandPath(n,t.cwd):n;try{if(!s.statSync(i).isFile())throw new O("INVALID_ARGS",`${a} path is not a file: ${i}`);return{kind:"file",path:i}}catch(t){if(t instanceof O)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new O("INVALID_ARGS",`${a} file is not readable: ${i}`);if(e&&"ENOENT"!==e)throw new O("COMMAND_FAILED",`Unable to read ${a} file: ${i}`,{cause:String(t)})}if((r=n.trim()).startsWith("{")&&r.endsWith("}")||r.startsWith("[")&&r.endsWith("]"))return{kind:"inline",text:n};throw new O("INVALID_ARGS",`${a} file not found: ${i}`)}async function lG(e){let t=lU(e,{subject:"Push payload"}),r="inline"===t.kind?t.text:await lV(t.path);try{let e=JSON.parse(r);if(!e||"object"!=typeof e||Array.isArray(e))throw new O("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof O)throw t;throw new O("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function lV(e){try{return await d.readFile(e,"utf8")}catch(r){let t=r.code;if("ENOENT"===t)throw new O("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new O("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new O("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new O("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(r)})}}let lB=e0(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),lj=/^(iphone|ipad|ipod|appletv)/i,lq=/\b(iphone|ipad|ipod)\b/i,lH=/^appletv/i,lW=["apple tv","appletv","tvos"],lz=/^==\s*(.+?)\s*==$/,lJ=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function lK(e){return(e??"").trim().toLowerCase()}function lX(e){return lK(e.hardwareProperties?.platform)}function lY(e){return e.includes("tvos")}function lZ(e){let t=lK(e);return lW.some(e=>t.includes(e))}function lQ(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function l0(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function l1(e={}){let t,r,a=e6(e.simulatorSetPath),n=e.target;try{t=await F("xcrun",te(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{r=JSON.parse(t.stdout)}catch{return null}let i=l2(r,a),o=null,s=null,l=null;for(let e of i)n&&e.target!==n||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function l2(e,t){let r=[];for(let[a,n]of Object.entries(e.devices))if(function(e){let t=lK(e);return t.includes("ios")||t.includes("tvos")}(a))for(let e of n)e.isAvailable&&r.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:lY(lK(a))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return r}function l3(e,t){let r=new Set(e.map(e=>e.id)),a=[...e];for(let e of t)r.has(e.id)||(r.add(e.id),a.push(e));return a}async function l4(){let e=null;try{e=p.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await F("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:lB});if(0!==t.exitCode)return[];let r=await d.readFile(e,"utf8");return function(e){let t=[];for(let r of e.result?.devices??[]){if(!function(e){var t;let r=lX(e);return!!(r.includes("ios")||r.includes("tvos"))||(t=l0(e),!!lj.test(t.trim())||lQ(e).some(lZ))}(r))continue;let e=r.hardwareProperties?.udid??r.identifier??"",a=r.name??r.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:a,kind:"device",target:function(e){var t;return lY(lX(e))?"tv":(t=l0(e),lH.test(t.trim())||lQ(e).some(lZ))?"tv":"mobile"}(r),booted:!0})}return t}(JSON.parse(r))}catch{return[]}finally{e&&await d.rm(e,{force:!0}).catch(()=>{})}}async function l5(){try{let e=await F("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],r=null;for(let a of e.split(/\r?\n/)){let e=a.trim();if(!e)continue;let n=lz.exec(e);if(n){r=n[1]?.trim()??null;continue}if("Devices"!==r)continue;let i=lJ.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return lZ(e)?"tv":lq.test(e.trim())?"mobile":null}(s);l&&t.push({platform:"ios",id:o,name:s,kind:"device",target:l,booted:!0})}return t}(e.stdout)}catch{return[]}}async function l8(e={}){if("darwin"!==process.platform)throw new O("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await x("xcrun"))throw new O("TOOL_MISSING","xcrun not found in PATH");let t=e6(e.simulatorSetPath),r=await F("xcrun",te(["list","devices","-j"],{simulatorSetPath:t})),a=[];try{let e=JSON.parse(r.stdout);a=l2(e,t)}catch(e){throw new O("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(a.push({platform:"macos",id:"host-macos-local",name:u.hostname(),kind:"device",target:"desktop",booted:!0}),t)return a;let[n,i]=await Promise.all([l4(),l5()]);return a=l3(a,n),l3(a,i)}async function l6(e,t,r){let a,n=!!(t.udid||t.serial||t.deviceName);try{a=await tD(e,t,r)}catch(e){if(n||!(e instanceof O)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!n&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!a||"device"===a.kind)){let e=await l1({simulatorSetPath:r.simulatorSetPath,target:t.target});if(e)return e}if(a)return a;throw new O("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function l9(e){let t=e.platform,r=tx({simulatorSetPath:e6(e.iosSimulatorDeviceSet),platform:t,target:e.target}),a=e7(e.androidDeviceAllowlist);return await T("resolve_target_device",async()=>{let n={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(n.target&&!n.platform)throw new O("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");if("linux"===n.platform){let e=await lx();return await tD(e,n)}if("android"===n.platform){await aX();let e=await na({serialAllowlist:a});return await tD(e,n)}if(n.platform){let e=await l8({simulatorSetPath:r});return await l6(e,n,{simulatorSetPath:r})}let i=[];try{i.push(...await na({serialAllowlist:a}))}catch{}try{i.push(...await l8({simulatorSetPath:r}))}catch{}try{i.push(...await lx())}catch{}return await tD(i,n,{simulatorSetPath:r})},{platform:t,target:e.target})}async function l7(e,t,r,a,n){let i={requestId:n?.requestId,appBundleId:n?.appBundleId,verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath},o=function(e,t){switch(e.platform){case"android":return{open:(t,r)=>nX(e,t,r?.activity),openDevice:()=>n2(e),close:t=>n3(e,t),tap:(t,r)=>iM(e,t,r),doubleTap:async(t,r)=>{await iM(e,t,r),await iM(e,t,r)},swipe:(t,r,a,n,i)=>ik(e,t,r,a,n,i),longPress:(t,r,a)=>iP(e,t,r,a),focus:(t,r)=>i$(e,t,r),type:(t,r)=>iR(e,t,r),fill:(t,r,a,n)=>iF(e,t,r,a,n),scroll:(t,r)=>iV(e,t,r),scrollIntoView:(t,r)=>iB(e,t,r),screenshot:t=>on(e,t),back:t=>iE(e),home:()=>iO(e),rotate:t=>iL(e,t),appSwitcher:()=>iC(e),readClipboard:()=>iZ(e),writeClipboard:t=>iQ(e,t),setSetting:(t,r,a,n)=>i5(e,t,r,a,n)};case"linux":return{open:e=>ly(e),openDevice:()=>Promise.resolve(),close:e=>lv(e),tap:(e,t)=>ln(e,t),doubleTap:(e,t)=>ls(e,t),swipe:(e,t,r,a,n)=>lu(e,t,r,a,n),longPress:(e,t,r)=>ll(e,t,r),focus:(e,t)=>ld(e,t),type:(e,t)=>lp(e,t),fill:(e,t,r,a)=>lf(e,t,r,a),scroll:(e,t)=>lc(e,t),scrollIntoView:()=>{throw new O("UNSUPPORTED_OPERATION","scrollIntoView not yet supported on Linux")},screenshot:e=>lg(e),back:()=>lI(),home:()=>lb(),rotate:()=>{throw new O("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new O("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>lN(),writeClipboard:e=>l_(e),setSetting:()=>{throw new O("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let r,a,{overrides:n,runnerOpts:i}=(r={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},a=()=>{if(eX(t.requestId))throw eZ()},{runnerOpts:r,overrides:{tap:async(a,n)=>await rf(e,{command:"tap",x:a,y:n,appBundleId:t.appBundleId},r),doubleTap:async(a,n)=>await rf(e,{command:"tapSeries",x:a,y:n,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},r),swipe:async(a,n,i,o,s)=>await rf(e,{command:"drag",x:a,y:n,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},r),longPress:async(a,n,i)=>await rf(e,{command:"longPress",x:a,y:n,durationMs:i,appBundleId:t.appBundleId},r),focus:async(a,n)=>await rf(e,{command:"tap",x:a,y:n,appBundleId:t.appBundleId},r),type:async(a,n)=>{await rf(e,{command:"type",text:a,delayMs:n,appBundleId:t.appBundleId},r)},fill:async(a,n,i,o)=>{let s=await rf(e,{command:"tap",x:a,y:n,appBundleId:t.appBundleId},r);return await rf(e,{command:"type",text:i,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},r),s},scroll:async(a,n)=>await s1(rf,e,t,r,a,n),scrollIntoView:async(n,i)=>await sQ(a=>rf(e,{...a,appBundleId:t.appBundleId},r),a,n,i)}});return{open:(t,r)=>sO(e,t,{appBundleId:r?.appBundleId,url:r?.url}),openDevice:()=>sL(e),close:t=>sC(e,t),screenshot:async(t,r)=>{"macos"===e.platform&&r?.surface&&"app"!==r.surface?await o0(t,{surface:r.surface,fullscreen:r.fullscreen}):await sh(e,t,r?.appBundleId,r?.fullscreen)},back:async r=>{await rf(e,{command:"system"===r?"backSystem":"backInApp",appBundleId:t.appBundleId},i)},home:async()=>{await rf(e,{command:"home",appBundleId:t.appBundleId},i)},rotate:async r=>{await rf(e,{command:"rotate",orientation:r,appBundleId:t.appBundleId},i)},appSwitcher:async()=>{await rf(e,{command:"appSwitcher",appBundleId:t.appBundleId},i)},readClipboard:()=>sF(e),writeClipboard:t=>sU(e,t),setSetting:(t,r,a,n)=>sV(e,t,r,a,n),...n}}default:throw new O("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,i);return U({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await T("platform_command",async()=>{switch(t){case"open":return de(e,o,r,n);case"close":{let e=r[0];if(!e)return{closed:"session",...ep("Closed session")};return await o.close(e),{app:e,...ep(`Closed: ${e}`)}}case"press":return dt(e,o,r,n,i);case"swipe":return dr(e,o,r,n,i);case"longpress":{let e=Number(r[0]),t=Number(r[1]),a=r[2]?Number(r[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new O("INVALID_ARGS","longpress requires x y [durationMs]");return await o.longPress(e,t,a),{x:e,y:t,durationMs:a,...ep(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=r.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new O("INVALID_ARGS","focus requires x y");return await o.focus(e,t),{x:e,y:t,...ep(`Focused (${e}, ${t})`)}}case"type":{let e=function(e){let t=e[0]?.trim();if(!t||!t.startsWith("@")||t.length<3)return null;let r=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(r)||/^(?:ref|node|element|el)[\w-]*$/i.test(r)?t:null}(r);if(e)throw new O("INVALID_ARGS",`type does not accept a target ref like "${e}"`,{hint:`Use fill ${e} "text" to target that field, or press ${e} then type "text" to append.`});let t=r.join(" ");if(!t)throw new O("INVALID_ARGS","type requires text");let a=lT(n?.delayMs??0,"delay-ms",0,1e4);return await o.type(t,a),{text:t,delayMs:a,...ep(dm("Typed",t))}}case"fill":{let e=Number(r[0]),t=Number(r[1]),a=r.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!a)throw new O("INVALID_ARGS","fill requires x y text");let i=lT(n?.delayMs??0,"delay-ms",0,1e4);return await o.fill(e,t,a,i),{x:e,y:t,text:a,delayMs:i,...ep(dm("Filled",a))}}case"scroll":return da(o,r,n);case"scrollintoview":{let e=r.join(" ").trim();if(!e)throw new O("INVALID_ARGS","scrollintoview requires text");let t=await o.scrollIntoView(e,{maxScrolls:n?.maxScrolls});if("number"==typeof t?.attempts)return{text:e,attempts:t.attempts,...ep(`Scrolled into view: ${e}`)};return{text:e,...ep(`Scrolled into view: ${e}`)}}case"pinch":return dn(e,r,n,i);case"trigger-app-event":{let{eventName:t,payload:a}=function(e){let t=e[0]?.trim(),r=e[1]?.trim();if(!t)throw new O("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!lP.test(t))throw new O("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new O("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let a=function(e,t){if(e)try{let r=JSON.parse(e);if(!r||"object"!=typeof r||Array.isArray(r))throw new O("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let a=JSON.stringify(r);if(Buffer.byteLength(a,"utf8")>8192)throw new O("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return r}catch(t){if(t instanceof O)throw t;throw new O("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(r,t);return{eventName:t,payload:a}}(r),i=function(e,t,r){var a;let n,i=(n=("ios"===(a=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===a?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,n?.trim()||void 0);if(!i)throw new O("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new O("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,a);return await o.open(i,{appBundleId:n?.appBundleId}),{event:t,eventUrl:i,transport:"deep-link",...ep(`Triggered app event: ${t}`)}}case"screenshot":{let e=r[0]??a??`./screenshot-${Date.now()}.png`;return await d.mkdir(p.dirname(e),{recursive:!0}),await o.screenshot(e,{appBundleId:n?.appBundleId,fullscreen:n?.screenshotFullscreen,surface:n?.surface}),{path:e,...ep(`Saved screenshot: ${e}`)}}case"back":return await o.back(n?.backMode),{action:"back",mode:n?.backMode??"in-app",...ep("Back")};case"home":return await o.home(),{action:"home",...ep("Home")};case"rotate":{let e=function(e){if(void 0===e)throw new O("INVALID_ARGS","rotate requires an orientation argument. Use portrait|portrait-upside-down|landscape-left|landscape-right.");switch(e?.trim().toLowerCase()){case"portrait":return"portrait";case"portrait-upside-down":case"upside-down":return"portrait-upside-down";case"landscape-left":case"left":return"landscape-left";case"landscape-right":case"right":return"landscape-right";default:throw new O("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}(r[0]);return await o.rotate(e),{action:"rotate",orientation:e,...ep(`Rotated to ${e}`)}}case"app-switcher":return await o.appSwitcher(),{action:"app-switcher",...ep("Opened app switcher")};case"clipboard":return di(o,r);case"keyboard":return ds(e,o,r,n,i);case"settings":return dl(e,o,r,n);case"push":return dd(e,r,n);case"snapshot":return du(e,r,n,i);case"read":return dc(e,r,n,i);default:throw new O("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function de(e,t,r,a){let n=r[0],i=r[1];if(r.length>2)throw new O("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!n)return await t.openDevice(),{app:null,...ep("Opened device")};if(void 0!==i){if("android"===e.platform)throw new O("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(aQ(n))throw new O("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!aQ(i))throw new O("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(n,{activity:a?.activity,appBundleId:a?.appBundleId,url:i}),{app:n,url:i,...ep(`Opened: ${n}`)}}return await t.open(n,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:n,...ep(`Opened: ${n}`)}}async function dt(e,t,r,a,n){let i,[o,s]=r.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new O("INVALID_ARGS","press requires x y");if("macos"===e.platform&&a?.surface&&"app"!==a.surface){let e=lL(a);if("primary"!==e)throw new O("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${a.surface} sessions.`);return await oQ(o,s,{bundleId:a.appBundleId,surface:a.surface}),{x:o,y:s,...ep(dp({x:o,y:s}))}}let l=lL(a);if("primary"!==l){let t=lC({commandLabel:"click",platform:e.platform,button:l,count:a?.count,intervalMs:a?.intervalMs,holdMs:a?.holdMs,jitterPx:a?.jitterPx,doubleTap:a?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await li(o,s):await lo(o,s):await rf(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x:o,y:s,button:l,...ep(dp({x:o,y:s,button:l}))}}let d=lT(a?.count??1,"count",1,200),u=lT(a?.intervalMs??0,"interval-ms",0,1e4),c=lT(a?.holdMs??0,"hold-ms",0,1e4),p=lT(a?.jitterPx??0,"jitter-px",0,100),f=a?.doubleTap===!0;if(f&&c>0)throw new O("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new O("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(("ios"===e.platform||"macos"===e.platform)&&d>1&&0===c&&0===p){let t=await rf(e,{command:"tapSeries",x:o,y:s,count:d,intervalMs:u,doubleTap:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...ep(dp({x:o,y:s}))}}return await l$(d,u,async e=>{let[r,a]=function(e,t){if(t<=0)return[0,0];let[r,a]=lR[e%lR.length];return[r*t,a*t]}(e,p),n=o+r,l=s+a;if(f){i??=await t.doubleTap(n,l)??void 0;return}c>0?i??=await t.longPress(n,l,c)??void 0:i??=await t.tap(n,l)??void 0}),ee({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},dp({x:o,y:s}))}async function dr(e,t,r,a,n){let i=Number(r[0]),o=Number(r[1]),s=Number(r[2]),l=Number(r[3]);if([i,o,s,l].some(Number.isNaN))throw new O("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let d=lT(r[4]?Number(r[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=lT(a?.count??1,"count",1,200),p=lT(a?.pauseMs??0,"pause-ms",0,1e4),f=a?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new O("INVALID_ARGS",`Invalid pattern: ${f}`);if(("ios"===e.platform||"macos"===e.platform)&&c>1){let t=await rf(e,{command:"dragSeries",x:i,y:o,x2:s,y2:l,durationMs:u,count:c,pauseMs:p,pattern:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...ep(df(c,f))}}return await l$(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,i,o,u):await t.swipe(i,o,s,l,u)}),ee({x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},df(c,f))}async function da(e,t,r){let a=t[0],n=t[1]?Number(t[1]):void 0,i=r?.pixels;if(!a)throw new O("INVALID_ARGS","scroll requires direction");if(void 0!==n&&!Number.isFinite(n))throw new O("INVALID_ARGS","scroll amount must be a number");if(void 0!==n&&void 0!==i)throw new O("INVALID_ARGS","scroll accepts either a relative amount or --pixels, not both");let o=function(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new O("INVALID_ARGS",`Unknown direction: ${e}`)}}(a),s=await e.scroll(o,{amount:n,pixels:i});return ee({direction:o,...void 0!==n?{amount:n}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==n?`Scrolled ${o} by ${n}`:`Scrolled ${o}`)}async function dn(e,t,r,a){if("android"===e.platform)throw new O("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");if("macos"===e.platform&&r?.surface&&"app"!==r.surface)throw new O("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let n=Number(t[0]),i=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(n)||n<=0)throw new O("INVALID_ARGS","pinch requires scale > 0");return await rf(e,{command:"pinch",scale:n,x:i,y:o,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{scale:n,x:i,y:o,...ep(`Pinched to scale ${n}`)}}async function di(e,t){let r=(t[0]??"").toLowerCase();if("read"!==r&&"write"!==r)throw new O("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===r){if(1!==t.length)throw new O("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:r,text:await e.readClipboard()}}if(t.length<2)throw new O("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let a=t.slice(1).join(" ");return await e.writeClipboard(a),{action:r,textLength:Array.from(a).length,...ep("Clipboard updated")}}async function ds(e,t,r,a,n){let i=(r[0]??"status").toLowerCase();if("status"!==i&&"get"!==i&&"dismiss"!==i)throw new O("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(r.length>1)throw new O("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===i){let t=await iY(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type}}let t=await iX(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==i)throw new O("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await rf(e,{command:"keyboardDismiss",appBundleId:a?.appBundleId},n);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...ep(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new O("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function dl(e,t,r,a){var n;let[i,o,s,l,d]=r,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;U({level:"debug",phase:"settings_apply",data:{setting:i,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(i,o,d??a?.appBundleId,u);return c&&"object"==typeof c?ee({setting:i,state:o,...c},("string"==typeof(n=c).message&&n.message.length>0?n.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...ep(`Updated setting: ${i}`)}}async function dd(e,t,r){let a=t[0]?.trim(),n=t[1]?.trim();if(!a||!n)throw new O("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await lG(n);if("ios"===e.platform)return await sG(e,a,i),{platform:"ios",bundleId:a,...ep(`Pushed notification to ${a}`)};let o=await or(e,a,i);return{platform:"android",package:a,action:o.action,extrasCount:o.extrasCount,...ep(`Pushed notification to ${a}`)}}async function du(e,t,r,a){if("linux"===e.platform){let e=await T("snapshot_capture",async()=>await lO(r?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await T("snapshot_capture",async()=>await rf(e,{command:"snapshot",appBundleId:r?.appBundleId,interactiveOnly:r?.snapshotInteractiveOnly,compact:r?.snapshotCompact,depth:r?.snapshotDepth,scope:r?.snapshotScope,raw:r?.snapshotRaw},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{backend:"xctest"}),a=t.nodes??[];if(0===a.length&&"simulator"===e.kind)throw new O("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:a,truncated:t.truncated??!1,backend:"xctest"}}let n=await T("snapshot_capture",async()=>await ib(e,{interactiveOnly:r?.snapshotInteractiveOnly,compact:r?.snapshotCompact,depth:r?.snapshotDepth,scope:r?.snapshotScope,raw:r?.snapshotRaw}),{backend:"android"});return{nodes:n.nodes??[],truncated:n.truncated??!1,backend:"android",analysis:n.analysis}}async function dc(e,t,r,a){let[n,i]=t.map(Number);if(Number.isNaN(n)||Number.isNaN(i))throw new O("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await iJ(e,n,i)??""};if("macos"===e.platform&&r?.surface&&"app"!==r.surface)return{action:"read",text:(await oZ(n,i,{bundleId:r.appBundleId,surface:r.surface})).text};let o=await rf(e,{command:"readText",x:n,y:i,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{action:"read",text:"string"==typeof o.text?o.text:"string"==typeof o.message?o.message:""}}function dp(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function df(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function dm(e,t){return`${e} ${Array.from(t).length} chars`}let dh=e=>"macos"!==e.platform,dw=e=>"macos"===e.platform||"simulator"===e.kind,dg={device:!0},dy={},dv={alert:{apple:{simulator:!0,device:!0},android:{},linux:dy,supports:dw},pinch:{apple:{simulator:!0,device:!0},android:{},linux:dy,supports:dw},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg,supports:e=>"android"===e.platform||"linux"===e.platform||"macos"===e.platform||"simulator"===e.kind},keyboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},close:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg,supports:dh},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:dh},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},screenshot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},scrollintoview:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy,supports:e=>"android"===e.platform||"macos"===e.platform||"simulator"===e.kind},snapshot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dy},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:dg}};function dI(e,t){let r=dv[e];if(!r)return!0;let a=tN(t.platform)?r.apple:"linux"===t.platform?r.linux:r.android;return!!a&&(!r.supports||!!r.supports(t))&&!0===a[t.kind??"unknown"]}function db(e,t,r,a,n){return{requestId:n??P().requestId,appBundleId:r,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:a,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:lL(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern,maxScrolls:t?.maxScrolls}}let dA=e0(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function dS(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eO);await t(e);return}if("device"===e.kind)return void await dN(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(eD);await t(e.id)}}async function dN(e){let t=p.join(u.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=Math.max(1,Math.ceil(dA/1e3));try{let a=await F("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(r)],{allowFailure:!0,timeoutMs:dA+3e3}),n=String(a.stdout??""),i=String(a.stderr??""),o=await d_(t);if(0===a.exitCode){if(!o.parsed)throw new O("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:n,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new O("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new O("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:n,stderr:i,exitCode:a.exitCode,tunnelState:o?.tunnelState,hint:dx(n,i)})}catch(t){if(t instanceof O&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let r=t.details??{},a=String(r.stdout??""),n=String(r.stderr??""),i=Number(r.timeoutMs??dA),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new O("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:a,stderr:n,hint:a||n?dx(a,n):o},t)}throw new O("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await d.rm(t,{force:!0}).catch(()=>{})}}async function d_(e){try{let t=await d.readFile(e,"utf8"),r=JSON.parse(t),a=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let r=t.connectionProperties?.tunnelState,a=t.device?.connectionProperties?.tunnelState,n="string"==typeof r?r:"string"==typeof a?a:void 0;return n?{tunnelState:n}:{}}(r);return{parsed:!0,tunnelState:a.tunnelState}}catch{return{parsed:!1}}}function dx(e,t){let r=oI(e,t);return r||(`${e}
37
+ ${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":ov)}let dD=e0(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),dM=new Map;async function dk(e){let t=await A.mkdtemp(p.join(u.tmpdir(),"agent-device-materialized-"));try{let r=await dL(e.installablePath,p.join(t,"installable")),a=e.archivePath?await dL(e.archivePath,p.join(t,"archive")):void 0,n=i.randomUUID(),o=e.ttlMs??dD,s=Date.now()+o,l=setTimeout(()=>{dE(n)},o);return dM.set(n,{rootPath:t,installablePath:r,archivePath:a,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:s,timer:l}),{materializationId:n,installablePath:r,...a?{archivePath:a}:{},expiresAt:new Date(s).toISOString()}}catch(e){throw await A.rm(t,{recursive:!0,force:!0}),e}}async function dE(e,t){let r=dM.get(e);if(!r)throw new O("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new O("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),dM.delete(e),await A.rm(r.rootPath,{recursive:!0,force:!0})}async function dO(e){let t=Array.from(dM.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await dE(e)}))}async function dL(e,t){let r=await A.stat(e);await A.mkdir(t,{recursive:!0});let a=p.join(t,p.basename(e));return r.isDirectory()?await A.cp(e,a,{recursive:!0}):await A.copyFile(e,a),a}async function dC(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new O("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await dS(e.session.device),e.session.device}if(!r)throw new O("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await l9(e.flags??{});return await dS(a),a}async function dP(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);try{let e,i,o,s=(i=function(e){let t=e.meta?.installSource;if(!t)throw new O("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new O("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new O("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===i.kind?{source:{kind:"path",path:ah(o,t.meta?.tenantId)},cleanup:()=>{aw(o)}}:{source:i,cleanup:()=>{}}),l=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new O("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await dC({session:n,flags:t.flags});if(!dI("install",d))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"install_from_source is not supported on this device"}};let u=eY(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:i}=await Promise.resolve(eO),{prepareIosInstallArtifact:o}=await Promise.resolve(eL),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await dk({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:n?r:void 0,ttlMs:l.ttlMs})),await i(d,c.installablePath),!c.bundleId)throw new O("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let o={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},s=ee(o,dR(o));return n&&a.recordAction(n,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await dE(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await Promise.resolve(ek),{installAndroidInstallablePathAndResolvePackageName:p}=await Promise.resolve(eM),f=await c(s.source,{signal:u});try{l.enabled&&(e=await dk({archivePath:f.archivePath,installablePath:f.installablePath,tenantId:t.meta?.tenantId,sessionName:n?r:void 0,ttlMs:l.ttlMs}));let i=await p(d,f.installablePath,f.packageName);if(!i)throw new O("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await Promise.resolve(eM),s=o(i),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:i,...s?{appName:s}:{},launchTarget:i,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=ee(u,dR(u));return n&&a.recordAction(n,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await dE(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await f.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:E(e)}}}function dR(e){return`Installed: ${eS(e)}`}async function dT(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new O("INVALID_ARGS","release_materialized_paths requires a materializationId");return await dE(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:E(e)}}}let d$=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),dF=e0(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function dU(e,t,r){return t||dG(r)?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} requires an active session or an explicit device selector (e.g. --platform ios).`}}}function dG(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function dV(e){return"ios"===e.platform&&"simulator"===e.kind}async function dB(e,t){dV(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function dj(e){let t=dG(e.flags)||!e.session?await l9(e.flags??{}):await dq(e.session.device);return!1!==e.ensureReady&&await dS(t),t}async function dq(e){if("ios"!==e.platform||"simulator"!==e.kind||"darwin"!==process.platform)return e;let t={platform:"ios",target:e.target,udid:e.id,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}};try{return await l9(t)}catch(e){if(!(e instanceof O)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await l9({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function dH(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let dW="shared_prefs/ReactNativeDevPrefs.xml",dz="debug_http_host",dJ="dev_server_https",dK="RCT_jsLocation",dX="RCT_packager_scheme",dY="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",dZ='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function dQ(e){return void 0!==d0(e)}function d0(e){if(!e)return;let t=ur(e.metroHost),r=un(e.metroPort),a="http",n=ur(e.bundleUrl);if(n){var i;let e;try{e=new h(n)}catch(e){throw new O("INVALID_ARGS",`Invalid runtime bundle URL: ${n}`,{},e)}("http:"===e.protocol||"https:"===e.protocol)&&(t??=ur(e.hostname),r??=un(e.port.length>0?Number(e.port):"https:"===(i=e.protocol)?443:"http:"===i?80:void 0),a="https:"===e.protocol?"https":"http")}if(t&&r)return{host:t,port:r,scheme:a}}async function d1(e){let{device:t,appId:r,runtime:a}=e;if(!r)return;let n=d0(a);if(n){if("android"===t.platform)return void await d3(t,r,n);"ios"===t.platform&&"simulator"===t.kind&&await d6(t,r,n)}}async function d2(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await d4(t,r);"ios"===t.platform&&"simulator"===t.kind&&await d9(t,r)}}async function d3(e,t,r){var a,n,i,o,s,l;let d,u;ua(t);let c=(a=await d5(e,t),n=dz,i=`${r.host}:${r.port}`,d=` <string name="${ui(n)}">${ui(i)}</string>`,ue(ut(a,n),d));o=c,s=dJ,l="https"===r.scheme,u=` <boolean name="${ui(s)}" value="${l?"true":"false"}" />`,c=ue(ut(o,s),u),await d8(e,t,c)}async function d4(e,t){ua(t);let r=await d5(e,t),a=ut(r,dz),n=ut(a,dJ);n!==r&&await d8(e,t,n)}async function d5(e,t){let r=await F("adb",aK(e,["shell","run-as",t,"cat",dW]),{allowFailure:!0});return 0!==r.exitCode?dZ:d7(r.stdout)}async function d8(e,t,r){let a=aK(e,["shell","run-as",t,"id"]),n=await F("adb",a,{allowFailure:!0});if(0!==n.exitCode){let e=uo(n.stdout,n.stderr);throw new O("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:a,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:e?dY:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await F("adb",aK(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await F("adb",aK(e,["shell","run-as",t,"tee",dW]),{stdin:r.trimEnd()})}catch(a){let e=k(a);if("TOOL_MISSING"===e.code)throw e;let r=uo("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new O("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?dY:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function d6(e,t,r){await F("xcrun",tt(e,["spawn",e.id,"defaults","write",t,dK,"-string",`${r.host}:${r.port}`])),await F("xcrun",tt(e,["spawn",e.id,"defaults","write",t,dX,"-string",r.scheme]))}async function d9(e,t){await F("xcrun",tt(e,["spawn",e.id,"defaults","delete",t,dK]),{allowFailure:!0}),await F("xcrun",tt(e,["spawn",e.id,"defaults","delete",t,dX]),{allowFailure:!0})}function d7(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
38
38
  `:dZ}function ue(e,t){return d7(e).replace("</map>",`${t}
39
- </map>`)}function ut(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return d7(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function ur(e){let t=e?.trim();return t&&t.length>0?t:void 0}function ua(e){if("binary"!==nf(e))return;let t=nm(e);throw new W("INVALID_ARGS",t,{package:e,hint:t})}function un(e){if(Number.isInteger(e)&&!(e<=0)&&!(e>65535))return e}function ui(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function uo(e,t){let r=`${e}
40
- ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}let us=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function ul(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ud(e){let t=e?.trim();return t&&t.length>0?t:void 0}function uu(e,t){if(void 0!==e){if("string"!=typeof e)throw new W("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return ud(e)}}function uc(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new W("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function up(e){if("ios"===e||"android"===e)return e}async function uf(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:n}=e;!t||!n?.appBundleId||!dQ(r)||dQ(a)||await d2({device:n.device,appId:n.appBundleId})}async function um(e){var t,r;let{req:a,sessionName:n,sessionStore:i}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=i.get(n),l=i.getRuntimeHints(n);if(!["set","show","clear"].includes(o))return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime requires set, show, or clear"}};if("clear"===o){dQ(l)&&s?.appBundleId&&await d2({device:s.device,appId:s.appBundleId});let e=i.clearRuntimeHints(n);return{ok:!0,data:{session:n,cleared:e}}}if("show"===o)return{ok:!0,data:{session:n,configured:!!l,runtime:l}};let d=up(a.flags?.platform??l?.platform??s?.device.platform);if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first."}};if(s&&s.device.platform!==d)return{ok:!1,error:{code:"INVALID_ARGS",message:`runtime set targets ${d}, but session "${n}" is already bound to ${s.device.platform}.`}};let u={platform:(t=a.flags,r={platform:d,metroHost:ud(t?.metroHost),metroPort:uc(t?.metroPort),bundleUrl:ud(t?.bundleUrl),launchUrl:ud(t?.launchUrl)}).platform??l?.platform,metroHost:r.metroHost??l?.metroHost,metroPort:r.metroPort??l?.metroPort,bundleUrl:r.bundleUrl??l?.bundleUrl,launchUrl:r.launchUrl??l?.launchUrl};return 0===ul(u)?{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."}}:(i.setRuntimeHints(n,u),{ok:!0,data:{session:n,configured:!0,runtime:u}})}let uh="open-command-roundtrip",uw="Not implemented for this platform in this release.",ug=new Set(["app","desktop","frontmost-app"]);async function uy(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await oz();return{appBundleId:t.bundleId,appName:t.appName}}let uv=[250,400];function uI(e,t,r=e.snapshot){if("android"!==e.device.platform)return;let a=r?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:r?.nodes.length??0,baselineSignatures:a?uN(r?.nodes??[]):void 0,routeComparable:a}}function ub(e){if(!e||"android"!==e.device.platform)return;let t=e.androidSnapshotFreshness;if(t)return Date.now()-t.markedAt>2500?void delete e.androidSnapshotFreshness:t}function uA(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function uS(e){return"press"===e||"click"===e||"back"===e||"open"===e}function uN(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}function u_(e,t){return!(e<12)&&t<=Math.floor(.2*e)}async function ux(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return aQ(t)?"macos"===e.platform?void 0:"device"===e.kind?a0(r,t):void 0:await uD(e,t)}async function uD(e,t){try{let{resolveIosApp:r}=await Promise.resolve(eO);return await r(e,t)}catch{return}}async function uM(e,t){if(!("android"!==e.platform||!t||aQ(t)))try{let{resolveAndroidApp:r}=await Promise.resolve(eM),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function uk(e,t,r,a){return await ux(e,t,r)??await a(e,t)??("android"===e.platform&&t&&aQ(t)?r:void 0)}function uE(e){return{ok:!1,error:{code:"INVALID_ARGS",message:e}}}function uO(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:n}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return n??"app";if("linux"===t.platform){if(!r)return"app";let e=ex(r);if(!ug.has(e))throw new W("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new W("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new W("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let i=r?ex(r):"app";if("app"!==i&&"menubar"!==i&&a)throw new W("INVALID_ARGS",`open --surface ${i} does not accept an app target`);return i}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return{ok:!1,error:{code:e instanceof W?e.code:"INVALID_ARGS",message:String(e.message)}}}}function uL(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:n}=e;return t?r&&aQ(r)?uE("open --relaunch does not support URL targets."):"app"!==a?uE("open --relaunch is supported only for app surfaces."):"android"===n.platform&&r&&"binary"===nf(r)?uE(nm(r)):null:null}async function uC(e){let{req:t,sessionName:r,sessionStore:a,device:n,surface:i,openTarget:o,existingSession:s}=e;await dS(n);let{appBundleId:l,appName:d}=await uP({device:n,surface:i,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:n}=e,i=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new W("INVALID_ARGS","open runtime must be an object.");let n=Object.keys(t).find(e=>!us.includes(e));if(n)throw new W("INVALID_ARGS",`Invalid open runtime field: ${n}. Supported fields are ${us.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new W("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new W("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:uu(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new W("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return uc(e)}}(t.metroPort),bundleUrl:uu(t.bundleUrl,"bundleUrl"),launchUrl:uu(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:up(n.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let n=r?.platform,i=up(n);if(a.platform&&r&&!i)throw new W("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${n}.`);if(a.platform&&i&&a.platform!==i)throw new W("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${n}. Clear the runtime hints or use a different session.`);return i&&a.platform!==i?{...a,platform:i}:a}(r,a,n),previousRuntime:i,replacedStoredRuntime:!1}:{runtime:o&&ul(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=j(t);return{ok:!1,response:{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}}({req:t,sessionStore:a,sessionName:r,device:n});if(!u.ok)return{type:"response",response:u.response};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await uf({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function uP(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:n}=e,i=await uy(r);return{appBundleId:i.appBundleId??await uk(t,a,n,uM),appName:i.appName??a}}let uR=new Map;async function uT(e){let{device:t,closeTarget:r,outFlag:a,context:n}=e;"android"!==t.platform&&await ro(t.id),await l7(t,"close",[r],a,n),await dB(t,d$)}async function u$(e){let{runtime:t,device:r,req:a,logPath:n,appBundleId:i,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||aQ(d)||await l7(r,"open",[l],a.flags?.out,{...db(n,a.flags,i,o)})}async function uF(e){var t,r,a;let{req:n,sessionName:i,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:p,appBundleId:f,runtime:m,existingSession:h}=e,w=n.flags?.relaunch===!0,g=h?.trace?.outPath;if(w&&d){let e=f??d;await uT({device:l,closeTarget:e,outFlag:n.flags?.out,context:{...db(s,n.flags,f??h?.appBundleId,g)}})}await d1({device:l,appId:f,runtime:m});let y=Date.now();await l7(l,"open",u,n.flags?.out,{...db(s,n.flags,f)}),await u$({runtime:m,device:l,req:n,logPath:s,appBundleId:f,traceLogPath:g,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:uh,appTarget:d,appBundleId:f}:void 0;if(await dB(l,dF),eX(n.meta?.requestId)){let e=eZ();return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}h&&uI(h,"open",h.snapshot);let I=function(e){let{existingSession:t,sessionName:r,device:a,surface:n,appBundleId:i,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:n,appBundleId:i,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:n,appBundleId:i,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:i,device:l,surface:p,appBundleId:f,appName:c,saveScript:!!n.flags?.saveScript});void 0!==n.runtime&&(t=o,r=i,(a=m)&&(0===ul(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let b=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:n,startup:i,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:n};return r&&(d.appName=r),a&&(d.appBundleId=a),i&&(d.startup=i),s&&l(s)>0&&(d.runtime=s),o&&(d.platform=o.platform,d.target=o.target??"mobile",d.device=o.name,d.id=o.id,d.kind=o.kind,"android"===o.platform&&(d.serial=o.id)),o?.platform==="ios"&&(d.device_udid=o.id,d.ios_simulator_device_set=o.simulatorSetPath??null),{...d,...ec(`Opened: ${r??a??t}`)}}({sessionName:i,appName:c,appBundleId:f,surface:p,startup:v,device:l,runtime:m,runtimeHintCount:ul});return o.recordAction(I,{command:"open",positionals:u,flags:n.flags??{},runtime:void 0!==n.runtime?m:void 0,result:b}),o.set(i,I),{ok:!0,data:b}}async function uU(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e;if(n.has(r)){let e=n.get(r);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:`Session "${r}" not found.`}};let i=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(i?e.appName:void 0),l=uO(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return i?uE("open --relaunch requires an app name or an active session app."):uE("Session already active. Close it first or pass a new --session name.");let d=uL({shouldRelaunch:i,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await dq(e.device),c=await uC({req:t,sessionName:r,sessionStore:n,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await uF({req:t,sessionName:r,sessionStore:n,logPath:a,device:u,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let i=t.flags?.relaunch===!0,o=t.positionals?.[0];if(i&&!o)return uE("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&aQ(r)?uE("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===nf(r)?uE(nm(r)):null:null}({shouldRelaunch:i,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await l9(t.flags??{}),d=uO(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=uL({shouldRelaunch:i,openTarget:o,surface:d,device:l});return u||await tS(uR,l.id,async()=>{let e=n.toArray().find(e=>e.device.id===l.id);if(e)return{ok:!1,error:{code:"DEVICE_IN_USE",message:`Device is already in use by session "${e.name}".`,details:{session:e.name,deviceId:l.id,deviceName:l.name}}};let i=await uC({req:t,sessionName:r,sessionStore:n,device:l,surface:d,openTarget:o});return"response"===i.type?i.response:await uF({req:t,sessionName:r,sessionStore:n,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:i.details.appBundleId,appName:i.details.appName,runtime:i.details.runtime,surface:d})})}async function uG(e){let t=await $("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function uV(e){let{device:t,shutdownRequested:r}=e;if(r&&(dV(t)||"android"===t.platform&&"emulator"===t.kind))try{return dV(t)?await ox(t):await uG(t)}catch(t){let e=ea(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function uB(e){if(await ro(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await oX("dismiss",t).catch(t=>{ep({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function uj(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,i=n.get(r);if(!i)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session"}};i.appLog&&await ad(i.appLog),t.positionals&&t.positionals.length>0&&(("ios"===i.device.platform||"macos"===i.device.platform)&&await uB(i),await l7(i.device,"close",t.positionals,t.flags?.out,{...db(a,t.flags,i.appBundleId,i.trace?.outPath)}),await dB(i.device,d$)),("ios"===i.device.platform||"macos"===i.device.platform)&&await uB(i),dQ(n.getRuntimeHints(r))&&i.appBundleId&&await d2({device:i.device,appId:i.appBundleId}).catch(()=>{}),n.recordAction(i,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...ec(`Closed: ${r}`)}}),t.flags?.saveScript&&(i.recordSession=!0),n.writeSessionLog(i),await dO(r).catch(()=>{}),n.delete(r);let o=await uV({device:i.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:H({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...ec(`Closed: ${r}`)}}}function uq(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}let uH={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await Promise.resolve(eO);return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await Promise.resolve(eM);return await a(e,t,r)}},uW={ios:async(e,t,r)=>{let{installIosApp:a}=await Promise.resolve(eO),n=await a(e,r,{appIdentifierHint:t});return{bundleId:n.bundleId,appName:n.appName,launchTarget:n.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await Promise.resolve(eM),n=await a(e,r);return{package:n.packageName,appName:n.appName,launchTarget:n.launchTarget}}};async function uz(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:i}=e,o=n.get(a),l=t.flags??{},d=dU(r,o,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return uq("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let p=t.meta?.uploadedArtifactId;try{var f;let e,a=p?ah(p,t.meta?.tenantId):rC.expandHome(c);if(!s.existsSync(a))return uq("INVALID_ARGS",`App binary not found: ${a}`);let d=await dj({session:o,flags:l,ensureReady:!1});if(!dI(r,d))return uq("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await i.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await i.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=H(e,(f=e,`Installed: ${f.appName??U(f)}`));return o&&n.recordAction(o,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&aw(p)}}let uJ=["platform","target","device","udid","serial","verbose","out"];async function uK(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return{ok:!1,error:{code:"INVALID_ARGS",message:`Unsupported batch on-error mode: ${a}.`}};let n=e.flags?.batchMaxSteps??ew;if(!Number.isInteger(n)||n<1||n>1e3)return{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`}};try{let a=T(e.flags?.batchSteps,n),i=Date.now(),o=[];for(let n=0;n<a.length;n+=1){let i=a[n],s=await uX(e,t,i,r,n+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${i.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:i.command,positionals:i.positionals,executed:n,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-i,results:o}}}catch(t){let e=j(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}async function uX(e,t,r,a,n){let i=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:n,...i}=t??{},o=e??{};for(let e of uJ)void 0===i[e]&&void 0!==o[e]&&(i[e]=o[e]);return i}(e.flags,r.flags);void 0===o.session&&(o.session=t);let s=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:o,runtime:r.runtime,meta:e.meta}),l=Date.now()-i;return s.ok?{ok:!0,step:n,result:{step:n,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:n,error:s.error}}async function uY(e){let t,r,a,{deviceName:n,runtime:i,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new W("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await uZ({deviceName:n,runtime:i,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await uQ({deviceName:n,runtime:i,simctlOpts:u})).udid,r=await u0(t,u),a=!0)}else t=(await uQ({deviceName:n,runtime:i,simctlOpts:u})).udid,r=await u0(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:n,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:n,runtime:r,created:a,booted:c}}async function uZ(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,n=await $("xcrun",te(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:od});if(0!==n.exitCode)return null;try{let e=JSON.parse(String(n.stdout??""));for(let[a,n]of Object.entries(e.devices??{}))if(!r||u1(a).includes(u1(r))){for(let e of n)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function uQ(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,n=r?["create",t,t,r]:["create",t,t],i=await $("xcrun",te(n,a),{allowFailure:!0});if(0!==i.exitCode)throw new W("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(i.stdout??"").trim();if(!o)throw new W("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(i.stdout??""),stderr:String(i.stderr??"")});return{udid:o}}async function u0(e,t){let r=await $("xcrun",te(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:od});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,a]of Object.entries(t.devices??{}))if(a.some(t=>t.udid===e))return r;return""}catch{return""}}function u1(e){return e.toLowerCase().replace(/[._-]/g,"")}async function u2(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,n=e6(e.iosSimulatorDeviceSet);if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"ensure-simulator requires --device <name>"}};let i=await uY({deviceName:r,runtime:a,simulatorSetPath:n,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:dS});return{ok:!0,data:{udid:i.udid,device:i.device,runtime:i.runtime,ios_simulator_device_set:n??null,created:i.created,booted:i.booted}}}catch(t){let e=j(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("devices"===t.command)try{let e=[],r=e7(t.flags?.androidDeviceAllowlist),a=t.flags?.platform,n=tx({simulatorSetPath:e6(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await Promise.resolve(eD);e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await Promise.resolve(eE);e.push(...await t({simulatorSetPath:n}))}else{if("apple"!==a){let{listAndroidDevices:t}=await Promise.resolve(eD);try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await Promise.resolve(eE);try{e.push(...await t({simulatorSetPath:n}))}catch{}}let i="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?i.filter(e=>(e.target??"mobile")===t.flags?.target):i).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=j(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("apps"===t.command){let e=a.get(r),n=t.flags??{},i=dU(t.command,e,n);if(i)return i;let o=await dj({session:e,flags:n,ensureReady:!0});if(!dI("apps",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"apps is not supported on this device"}};let s=t.flags?.appsFilter??"all";if(tN(o.platform)){let{listIosApps:e}=await Promise.resolve(eO);return{ok:!0,data:{apps:(await e(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await Promise.resolve(eM);return{ok:!0,data:{apps:(await l(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function u3(e){let{ensureAndroidEmulatorBooted:t}=await Promise.resolve(eD);return await t(e)}let u4='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',u5='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function u8(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r),i=t.flags??{},o=i.platform;if(!n&&"string"==typeof i?.session&&i.session.trim().length>0)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"ios"===o?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`}};let s=dU("appstate",n,i);if(s)return s;let l=(n?.device.platform==="ios"||n?.device.platform==="macos")&&function(e,t){if(!t)return!1;if(!dG(e))return!0;let r=e?.platform;return!(r&&!t_(t.device.platform,r)||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(i,n);if("ios"===o&&!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u4}};if("macos"===o&&!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u5}};if(l&&n){let e=n.appName??n.appBundleId;if(!n.appName&&!n.appBundleId){if("macos"===n.device.platform&&n.surface&&"app"!==n.surface&&"frontmost-app"!==n.surface)return{ok:!0,data:{platform:n.device.platform,appName:n.surface,appBundleId:n.appBundleId,source:"session",surface:n.surface}};let e="macos"===n.device.platform?"macOS":"iOS";return{ok:!1,error:{code:"COMMAND_FAILED",message:`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`}}}return{ok:!0,data:{platform:n.device.platform,appName:e??"unknown",appBundleId:n.appBundleId,source:"session",surface:n.surface??"app",..."ios"===n.device.platform?{device_udid:n.device.id,ios_simulator_device_set:n.device.simulatorSetPath??null}:{}}}}let d=await dj({session:n,flags:i,ensureReady:!0});if("ios"===d.platform)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u4}};if("macos"===d.platform)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u5}};let{getAndroidAppState:u}=await Promise.resolve(eM),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function u6(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,n=a.get(r),i=t.flags??{},o=dU(t.command,n,i);if(o)return o;let s="android"===(i.platform??n?.device.platform),l=!0===i.headless;if(l&&!s)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};let d=dH({flags:i,sessionDevice:n?.device}),u=s&&!!d,c=!1;try{e=await dj({session:n,flags:i,ensureReady:!1})}catch(r){let t=j(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await u3({avdName:d,serial:i.serial,headless:l}),c=!0}if(i.target&&(e.target??"mobile")!==i.target)return{ok:!1,error:{code:"DEVICE_NOT_FOUND",message:`No ${e.platform} device found matching --target ${i.target}.`}};if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};if(!c){let t=dH({flags:i,sessionDevice:n?.device,resolvedDevice:e});if(!t)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};e=await u3({avdName:t,serial:i.serial,headless:!0})}await dS(e)}else("android"!==e.platform||!0!==e.booted)&&await dS(e);return dI("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"boot is not supported on this device"}}}return"appstate"===t.command?await u8({req:t,sessionName:r,sessionStore:a}):null}let u9="adb-shell-dumpsys-cpuinfo",u7="adb-shell-dumpsys-meminfo";async function ce(e,t){try{let r=await $("adb",aK(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){var a,n,i;let o=new Set,s=0;for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let i=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!i)continue;let l=Number(i[1]),d=i[2];Number.isFinite(l)&&(a=d,n=t,a===n||a.startsWith(`${n}:`))&&(s+=l,o.add(d))}return{usagePercent:(i=s,Math.round(10*i)/10),measuredAt:r,method:u9,matchedProcesses:[...o]}}(r.stdout,t,new Date().toISOString())}catch(e){throw cr("cpu",t,e)}}async function ct(e,t){try{let r=await $("adb",aK(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new W("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let a=ca(e,"TOTAL PSS")??function(e){for(let t of e.split("\n")){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let r=e.split(/\s+/).slice(1).find(e=>null!==cn(e));if(!r)break;return cn(r)??void 0}}(e);if(void 0===a)throw new W("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:a,totalRssKb:ca(e,"TOTAL RSS"),measuredAt:r,method:u7}}(r.stdout,t,new Date().toISOString())}catch(e){throw cr("memory",t,e)}}function cr(e,t,r){return r instanceof W&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new W(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof W?r:new W("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function ca(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return cn(a[1])??void 0}function cn(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let ci="ps-process-snapshot",co="ps-process-snapshot",cs="xctrace-activity-monitor",cl="xctrace-activity-monitor";async function cd(e,t){if("ios"===e.platform&&"device"===e.kind)return await cp(e,t);let r=await cc(e,t),a=await cy(e,r);if(0===a.length)throw new W("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let n=new Date().toISOString(),i=rw(a.map(e=>p.basename(cv(e.command))));return cI({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:n,matchedProcesses:i,cpuMethod:ci,memoryMethod:co})}async function cu(e){let t=tO(e),r=cb(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new W("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}),n=a.indexOf("pid"),i=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(n<0||i<0||o<0||s<0)throw new W("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let n of t)r(n)&&a.push(n),a.push(...e(n.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,p;let t=e.children;if(0===t.length)continue;for(let e of t){let t=cb(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);u.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&u.set(e.attributes.id,{numberValue:cA(e),processName:cN(e)})}let r=cS(t[n],u),a=(c=t[i],p=u,c?c.attributes.ref?p.get(c.attributes.ref)?.processName??null:cN(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:cS(t[o],u),residentMemoryBytes:cS(t[s],u)})}return d}async function cc(e,t){let r="macos"===e.platform?await cw(t):await cg(e,t),a="macos"===e.platform?p.join(r,"Contents","Info.plist"):p.join(r,"Info.plist"),n=await oM(a,"CFBundleExecutable");if(!n)throw new W("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:n,executablePath:"macos"===e.platform?p.join(r,"Contents","MacOS",n):void 0}}async function cp(e,t){let r=await cf(e,t),a=await cm(e,t),n=await cm(e,t),i=ch(await cu(a.xml),r,t,e),o=ch(await cu(n.xml),r,t,e),s=n.capturedAtMs-a.capturedAtMs;if(s<=0)throw new W("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===i.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new W("COMMAND_FAILED",`Incomplete Activity Monitor sample for ${t}`,{appBundleId:t,deviceId:e.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});return cI({usagePercent:Math.max(0,o.cpuTimeNs-i.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(n.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:cs,memoryMethod:cl})}async function cf(e,t){let r=(await og(e,"all")).find(e=>e.bundleId===t);if(!r)throw new W("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new W("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),n=w(a),i=(await oy(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===i.length)throw new W("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:n,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return i}async function cm(e,t){let r=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-ios-perf-")),a=p.join(r,"sample.trace"),n=p.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",a,"--quiet","--no-prompt"],i=await $("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),o=Date.now();if(0!==i.exitCode)throw new W("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:i.exitCode,stdout:i.stdout,stderr:i.stderr,appBundleId:t,deviceId:e.id,hint:c_(i.stdout,i.stderr)});let s=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",n],l=await $("xcrun",s,{allowFailure:!0,timeoutMs:15e3});if(0!==l.exitCode)throw new W("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:s,exitCode:l.exitCode,stdout:l.stdout,stderr:l.stderr,appBundleId:t,deviceId:e.id,hint:c_(l.stdout,l.stderr)});return{capturedAtMs:o,xml:await d.readFile(n,"utf8")}}finally{await d.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function ch(e,t,r,a){let n=new Set(t.map(e=>e.pid)),i=new Set(t.map(e=>p.basename(w(e.executable)))),o=e.filter(e=>n.has(e.pid)||i.has(e.processName));if(0===o.length)throw new W("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:a.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let s=new Map;for(let e of o){let t=s.get(e.pid);if(!t){s.set(e.pid,e);continue}s.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:cx(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:cx(t.residentMemoryBytes,e.residentMemoryBytes)})}let l=[...s.values()],d=l.map(e=>e.cpuTimeNs).filter(e=>null!==e),u=l.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:d.length>0?d.reduce((e,t)=>e+t,0):null,residentMemoryBytes:u.length>0?u.reduce((e,t)=>e+t,0):null,matchedProcesses:rw(l.map(e=>e.processName))}}async function cw(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await $("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new W("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!a)throw new W("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function cg(e,t){let r=tt(e,["get_app_container",e.id,t,"app"]),a=await $("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new W("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let n=a.stdout.trim();if(0===n.length)throw new W("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return n}async function cy(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:tt(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let a=e.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!a)continue;let n=Number(a[1]),i=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(o)&&t.push({pid:n,cpuPercent:i,rssKb:o,command:s})}return t})((await $("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let n;return r=e.command,a=t,n=cv(r),!!(a.executablePath&&(n===a.executablePath||r.startsWith(`${a.executablePath} `)))||p.basename(n)===a.executableName})}function cv(e){let[t=""]=e.trim().split(/\s+/,1);return t}function cI(e){return{cpu:{usagePercent:Math.round(10*e.usagePercent)/10,measuredAt:e.measuredAt,method:e.cpuMethod,matchedProcesses:e.matchedProcesses},memory:{residentMemoryKb:Math.round(e.residentMemoryKb),measuredAt:e.measuredAt,method:e.memoryMethod,matchedProcesses:e.matchedProcesses}}}function cb(e,t){for(let r of e){if(t(r))return r;let e=cb(r.children,t);if(e)return e}}function cA(e){if(!e||e.children.some(e=>"sentinel"===e.name)||!e.text)return null;let t=Number(e.text);return Number.isFinite(t)?t:null}function cS(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:cA(e):null}function cN(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function c_(e,t){let r=oI(e,t);if(r)return r;let a=`${e}
41
- ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?ov:a.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function cx(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function cD(e){var t;let r=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===uh&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:uh,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}(e.actions),a=r.at(-1),n=a?{available:!0,lastDurationMs:a.durationMs,lastMeasuredAt:a.measuredAt,method:uh,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:uh},i={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:n,fps:{available:!1,reason:uw},memory:{available:!1,reason:uw},cpu:{available:!1,reason:uw}},sampling:{startup:{method:uh,description:"Elapsed wall-clock time around dispatching the open command for the active session app target.",unit:"ms"},...function(e){if("android"===e.device.platform)return{memory:{method:u7,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:u9,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"}};var t=e.device;if("ios"===t.platform&&"device"===t.kind)return{memory:{method:cl,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:cs,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let r="macos"===t.platform?"host ps for the running macOS app executable resolved from the bundle ID.":"xcrun simctl spawn ps for the running iOS simulator app executable resolved from the bundle ID.";return{memory:{method:co,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:ci,description:`Recent CPU usage snapshot from ${r}`,unit:"percent"}}}(e)}};if("android"!==(t=e).device.platform&&"ios"!==t.device.platform&&"macos"!==t.device.platform)return i;if(!e.appBundleId){let t="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.";return i.metrics.memory={available:!1,reason:t},i.metrics.cpu={available:!1,reason:t},i}let[o,s]=await cM(e);return i.metrics.memory=ck(o),i.metrics.cpu=ck(s),i}async function cM(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([ct(e.device,t),ce(e.device,t)]);return[r,a]}try{let r=await cd(e.device,t);return[{status:"fulfilled",value:r.memory},{status:"fulfilled",value:r.cpu}]}catch(e){return[{status:"rejected",reason:e},{status:"rejected",reason:e}]}}function ck(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=ea(e.reason);return{available:!1,reason:t.message,error:t}}let cE=["path","start","stop","doctor","mark","clear"],cO=`logs requires ${cE.slice(0,-1).join(", ")}, or ${cE.at(-1)}`,cL=["dump","log"],cC=`network requires ${cL.join(" or ")}`,cP=["summary","headers","body","all"],cR=`network include mode must be one of: ${cP.join(", ")}`;async function cT(e){let{req:t}=e;return"perf"===t.command?c$(e):"logs"===t.command?cF(e):"network"===t.command?cj(e):null}async function c$(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"perf requires an active session. Run open first."}};try{return{ok:!0,data:await cD(a)}}catch(e){return{ok:!1,error:ea(e)}}}async function cF(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"logs requires an active session"}};if(!dI("logs",n.device))return{ok:!1,error:ea(new W("UNSUPPORTED_OPERATION","logs is not supported on this device"))};let i=(t.positionals?.[0]??"path").toLowerCase(),o=!!t.flags?.restart;return cE.includes(i)?o&&"clear"!==i?{ok:!1,error:{code:"INVALID_ARGS",message:"logs --restart is only supported with logs clear"}}:"path"===i?function(e,t,r){let a=r.resolveAppLogPath(t),n=function(e){if(!s.existsSync(e))return{exists:!1,sizeBytes:0};let t=s.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(a);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:n.sizeBytes,modifiedAt:n.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(n,r,a):"doctor"===i?cU(n,r,a):"mark"===i?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",i=r.resolveAppLogPath(t);return an(i),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
42
- `,s.appendFileSync(i,a,"utf8"),{ok:!0,data:{path:i,marked:!0}}}(t,r,a):"clear"===i?cG(n,r,a,o):"start"===i?cV(n,r,a):"stop"===i?cB(n,r,a):{ok:!1,error:{code:"INVALID_ARGS",message:cO}}:{ok:!1,error:{code:"INVALID_ARGS",message:cO}}}async function cU(e,t,r){let a=r.resolveAppLogPath(t),n=await au(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:n.checks,notes:n.notes}}}async function cG(e,t,r,a){if(e.appLog&&!a)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear requires logs to be stopped first; run logs stop"}};if(a&&!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear --restart requires an app session; run open <app> first"}};let n=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:ac(n)};e.appLog&&await ad(e.appLog);let i=ac(n),o=r.resolveAppLogPidPath(t);try{let a=await as(e.device,e.appBundleId,n,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:n,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...i,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:ea(a)}}}async function cV(e,t,r){if(e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"app log already streaming; run logs stop first"}};if(!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs start requires an app session; run open <app> first"}};let a=r.resolveAppLogPath(t),n=r.resolveAppLogPidPath(t);try{let i=await as(e.device,e.appBundleId,a,n);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:a,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:ea(e)}}}async function cB(e,t,r){if(!e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"no app log stream active"}};let a=e.appLog.outPath;return await ad(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function cj(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"network requires an active session"}};if(!dI("network",n.device))return{ok:!1,error:ea(new W("UNSUPPORTED_OPERATION","network is not supported on this device"))};let i=(t.positionals?.[0]??"dump").toLowerCase();if(!cL.includes(i))return{ok:!1,error:{code:"INVALID_ARGS",message:cC}};let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return{ok:!1,error:{code:"INVALID_ARGS",message:"network dump limit must be an integer in range 1..200"}};let s=function(e){let t=e.positionals?.[2]?.toLowerCase(),r=e.flags?.networkInclude;if(t&&r&&t!==r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"network include mode was provided both positionally and via --include with different values"}}};let a=(r??t??"summary").toLowerCase();return cP.includes(a)?{ok:!0,include:a}:{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:cR}}}}(t);if(!s.ok)return s.response;let{include:l}=s,d=await ai({device:n.device,appBundleId:n.appBundleId,appLogState:n.appLog?.getState(),appLogStartedAt:n.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!n.appLog,state:n.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let cq=new Set(["ios","android","macos","linux"]);function cH(e,t,r){let a=e[t];if(void 0!==a)throw new W("INVALID_ARGS",a===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(a)} vs ${String(r)}.`);e[t]=r}function cW(e){return!!e&&!Number.isNaN(Number(e))}let cz=/[*?[\]{}]/;async function cJ(e){let t,{filePath:r,sessionName:a,requestId:n,timeoutMs:i,platform:o,runReplay:s,cleanupSession:l}=e;ez(n);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:n,artifactPaths:d}).catch(e=>{let t=j(e);return{ok:!1,error:{code:t.code,message:t.message}}}).finally(()=>{eK(n)});try{return"number"==typeof i?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eJ(n),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(i,[...d]))},i)})]):await c}finally{t&&clearTimeout(t),u&&(await cK(c)||ep({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:n,graceMs:2e3}}));try{await l(a)}catch(e){ep({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:j(e).message}})}}}async function cK(e){return await Promise.race([e.then(()=>!0),N(2e3).then(()=>!1)])}async function cX(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return{ok:!1,error:{code:"INVALID_ARGS",message:"test requires at least one path or glob"}};try{var i,o,l,d,u,c;let e,f,m,h,w,g=function(e){let{inputs:t,cwd:r,platformFilter:a}=e,n=r??process.cwd(),i=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=rC.expandHome(e,t);if(s.existsSync(n)){let t=s.statSync(n);if(t.isDirectory())return s.globSync("**/*.ad",{cwd:n}).map(e=>p.join(n,e));if(t.isFile()){if(".ad"!==p.extname(n))throw new W("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!cz.test(r)&&(a=n,!cz.test(a)))throw new W("INVALID_ARGS",`test input not found: ${e}`);let i=p.isAbsolute(n)?n:e;return s.globSync(i,{cwd:p.isAbsolute(n)?void 0:t}).map(e=>p.isAbsolute(e)?e:p.resolve(t,e)).filter(e=>".ad"===p.extname(e)&&function(e){try{return s.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>p.normalize(e)).sort((e,t)=>e.localeCompare(t)),o=[];for(let e of i){var l,d;let t=function(e){let t=e.split(/\r?\n/),r={};for(let e of t){let t=e.trim();if(0===t.length||t.startsWith("#"))continue;if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&cq.has(e)&&cH(r,"platform",e)}let n=t.match(/(?:^|\s)timeout=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=1&&cH(r,"timeoutMs",Math.floor(e))}let i=t.match(/(?:^|\s)retries=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=0&&cH(r,"retries",Math.floor(e))}}return r}(s.readFileSync(e,"utf8"));if(!a){o.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){o.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${a}`});continue}l=a,d=t.platform,("apple"===l?"apple"===d||"ios"===d||"macos"===d:d===l)&&o.push({kind:"run",path:e,metadata:t})}if(0===o.filter(e=>"run"===e.kind).length){let e=a?` for --platform ${a}`:"";throw new W("INVALID_ARGS",`No .ad tests matched${e}.`)}return o}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(i=t.meta?.requestId,(i?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,n=rC.expandHome(t??".agent-device/test-artifacts",r);return p.join(n,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),I=[],b=Date.now(),A=0;for(let e of g){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await cY({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(o=t.flags?.timeoutMs,l=e.metadata.timeoutMs,"number"==typeof o?o:l),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(I.push(i),t.flags?.failFast===!0)break}let S=(d=g.length,u=I,c=Date.now()-b,e=u.filter(e=>"passed"===e.status).length,m=(f=u.filter(e=>"failed"===e.status)).length,h=u.filter(e=>"skipped"===e.status).length,w=e+m,{total:d,executed:w,passed:e,failed:m,skipped:h,notRun:Math.max(0,d-w-h),durationMs:c,failures:f,tests:u});return{ok:!0,data:S}}catch(t){let e=j(t);return{ok:!1,error:{code:e.code,message:e.message}}}}async function cY(e){var t,r;let a,n,{entry:i,sessionName:o,suiteInvocationId:l,caseIndex:d,cwd:u,requestId:c,retries:f,timeoutMs:m,suiteArtifactsDir:h,runReplay:w,cleanupSession:g}=e,y=Date.now(),v=p.join(h,(t=i.path,(0===(n=u?p.relative(u,t):p.basename(t)).length||n.startsWith("..")?p.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",b=0;for(let e=0;e<=f;e+=1){b=e+1;let t=function(e,t,r,a,n=0){let i=p.basename(r,p.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${i?`-${i}`:""}:attempt-${n+1}`}(o,l,i.path,d,e),n=p.join(v,`attempt-${b}`);r=i.path,s.mkdirSync(n,{recursive:!0}),s.copyFileSync(r,p.join(n,"replay.ad"));let u=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:n,attemptIndex:i}=e;return eW(`${t??r}:test:${n+1}:${p.basename(a)}:attempt:${i+1}`,r)}({requestId:c,suiteInvocationId:l,filePath:i.path,caseIndex:d,attemptIndex:e}),h=await cJ({filePath:i.path,sessionName:t,requestId:u,timeoutMs:m,platform:i.metadata.platform,runReplay:w,cleanupSession:g});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:i,attemptArtifactsDir:o}=e,l=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(t)];t.ok||"string"!=typeof t.error.logPath||l.push(t.error.logPath);let d=function(e,t){let r=[],a=new Map;for(let n of e){if(!function(e){try{return s.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=p.extname(e),a=r?e.slice(0,-r.length):e,n=t.get(e)??0;return(t.set(e,n+1),0===n)?e:`${a}-${n+1}${r}`}(p.basename(n),a),i=p.join(t,e);p.resolve(n)!==p.resolve(i)&&s.copyFileSync(n,i),r.push(i)}return r}(l,o),u=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${i}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;u.push(`replayed: ${e}`,`healed: ${r}`)}else u.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&u.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&u.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&u.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&u.push("timeoutMode: cooperative");d.length>0&&u.push(`copiedArtifacts: ${d.map(e=>p.basename(e)).join(", ")}`);let c=p.join(o,"result.txt"),f=`${u.join("\n")}
43
- `;s.writeFileSync(c,f),t.ok||s.writeFileSync(p.join(o,"failure.txt"),f)}({response:h,filePath:i.path,sessionName:t,attempts:b,maxAttempts:f+1,attemptArtifactsDir:n}),a=h,I=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:i.path,session:I,status:"passed",durationMs:A,attempts:b,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let S=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:i.path,session:I,status:"failed",durationMs:A,attempts:b,artifactsDir:v,error:S}}function cZ(e,t){let r=t.toLowerCase();return e.find(e=>{let t=(e.label??"").toLowerCase(),a=(e.value??"").toLowerCase(),n=(e.identifier??"").toLowerCase();return t.includes(r)||a.includes(r)||n.includes(r)})??null}function cQ(e,t){let r=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);return r&&c0(r)?r:function(e,t){if(!e.rect)return;let r=e.rect.y+e.rect.height/2,a=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);if(!t||!c0(t))continue;let n=Math.abs(e.rect.y+e.rect.height/2-r);(!a||n<a.distance)&&(a={label:t,distance:n})}return a?.label}(e,t)??(r&&c0(r)?r:void 0)}function c0(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function c1(e){let t=[],r=[];for(let a of e){let e=a.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let n=c2(a.type??""),i=[a.label,a.value,a.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0),o=!!i&&c0(i);if(("group"===n||"ioscontentgroup"===n)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);r.push({...a,depth:s})}return r}function c2(e){let t=e.trim().replace(/XCUIElementType/gi,"");t.startsWith("AX")&&(t=t.slice(2));let r=Math.max((t=t.toLowerCase()).lastIndexOf("."),t.lastIndexOf("/"));return -1!==r&&(t=t.slice(r+1)),t}function c3(e,t){let r=c2(e);return!r||("android"===t?r.includes("edittext")||r.includes("autocompletetextview"):r.includes("textfield")||r.includes("securetextfield")||r.includes("searchfield")||r.includes("textview")||r.includes("textarea")||"search"===r)}function c4(e,t){if(t.hittable)return t;let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(t.hittable)return t;r=t}return null}function c5(e){return[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").filter(e=>e.length>0)[0]??""}let c8=new Set(["id","role","text","label","value","appname","windowtitle"]),c6=new Set(["visible","hidden","editable","selected","enabled","hittable"]),c9=new Set([...c8,...c6]);function c7(e){let t=e.trim();if(!t)throw new W("INVALID_ARGS","Selector expression cannot be empty");let r=function(e){let t=[],r="",a=null;for(let n=0;n<e.length;n+=1){let i=e[n];if(('"'===i||"'"===i)&&!po(e,n)){a=pn(a,i),r+=i;continue}if(!a&&"|"===i&&"|"===e[n+1]){let a=r.trim();if(!a)throw new W("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);t.push(a),r="",n+=1;continue}r+=i}let n=r.trim();if(!n)throw new W("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);return t.push(n),t}(t);if(0===r.length)throw new W("INVALID_ARGS","Selector expression cannot be empty");return{raw:t,selectors:r.map(e=>(function(e){let t=e.trim();if(!t)throw new W("INVALID_ARGS","Selector segment cannot be empty");let r=function(e){let t=[],r="",a=null;for(let n=0;n<e.length;n+=1){let i=e[n];if(('"'===i||"'"===i)&&!po(e,n)){a=pn(a,i),r+=i;continue}if(!a&&/\s/.test(i)){r.trim()&&t.push(r.trim()),r="";continue}r+=i}if(a)throw new W("INVALID_ARGS",`Unclosed quote in selector: ${e}`);return r.trim()&&t.push(r.trim()),t}(t);if(0===r.length)throw new W("INVALID_ARGS",`Invalid selector segment: ${e}`);return{raw:t,terms:r.map(pa)}})(e))}}function pe(e){try{return c7(e)}catch{return null}}function pt(e,t={}){if(0===e.length)return null;let r=t.preferTrailingValue??!1,a=0,n=[];for(;a<e.length&&function(e){let t=e.trim();if(!t)return!1;if("||"===t)return!0;let r=t.indexOf("=");if(-1!==r){let e=t.slice(0,r).trim().toLowerCase();return c9.has(e)}return c9.has(t.toLowerCase())}(e[a]);){a+=1;let t=e.slice(0,a).join(" ").trim();t&&pe(t)&&n.push(a)}if(0===n.length)return null;let i=n[n.length-1];if(r){for(let t=n.length-1;t>=0;t-=1)if(n[t]<e.length){i=n[t];break}}let o=e.slice(0,i).join(" ").trim();return o?{selectorExpression:o,rest:e.slice(i)}:null}function pr(e){let t=e[0]??"",r=pt(e.slice(1),{preferTrailingValue:"text"===t});return{predicate:t,split:r}}function pa(e){let t=e.trim();if(!t)throw new W("INVALID_ARGS","Empty selector term");let r=t.indexOf("=");if(-1===r){let r=t.toLowerCase();if(!c6.has(r))throw new W("INVALID_ARGS",`Invalid selector term "${e}", expected key=value`);return{key:r,value:!0}}let a=t.slice(0,r).trim().toLowerCase(),n=t.slice(r+1).trim();if(!c9.has(a))throw new W("INVALID_ARGS",`Unknown selector key: ${a}`);if(!n)throw new W("INVALID_ARGS",`Missing selector value for key: ${a}`);if(c6.has(a)){let e,t="true"===(e=pi(n).toLowerCase())||"false"!==e&&null;if(null===t)throw new W("INVALID_ARGS",`Invalid boolean value for ${a}: ${n}`);return{key:a,value:t}}return{key:a,value:pi(n)}}function pn(e,t){return e?e===t?null:e:t}function pi(e){let t=e.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\(["'])/g,"$1"):t}function po(e,t){let r=0;for(let a=t-1;a>=0&&"\\"===e[a];a-=1)r+=1;return r%2==1}function ps(e,t,r){return t.terms.every(t=>(function(e,t,r){switch(t.key){case"id":return pu(e.identifier,String(t.value));case"role":return pu(c2(e.type??""),String(t.value));case"label":return pu(e.label,String(t.value));case"value":return pu(e.value,String(t.value));case"text":return pu(c5(e),String(t.value));case"appname":return pu(e.appName,String(t.value));case"windowtitle":return pu(e.windowTitle,String(t.value));case"visible":return pl(e)===!!t.value;case"hidden":return!pl(e)==!!t.value;case"editable":return pd(e,r)===!!t.value;case"selected":return!0===e.selected==!!t.value;case"enabled":return!1!==e.enabled==!!t.value;case"hittable":return!0===e.hittable==!!t.value;default:return!1}})(e,t,r))}function pl(e){return!0===e.hittable||!!e.rect&&e.rect.width>0&&e.rect.height>0}function pd(e,t){return c3(e.type??"",t)&&!1!==e.enabled}function pu(e,t){return pc(e??"")===pc(t)}function pc(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function pp(e,t,r){let a=r.requireRect??!1,n=r.requireUnique??!0,i=[];for(let o=0;o<t.selectors.length;o+=1){let s=t.selectors[o],l=function(e,t,r,a){let n=0,i=null,o=null,s=!1;for(let l of e){if(a&&!l.rect||!ps(l,t,r))continue;if(n+=1,i??=l,!o){o=l;continue}let e=function(e,t){let r=e.depth??0,a=t.depth??0;if(r!==a)return r>a?1:-1;let n=ph(e),i=ph(t);return n!==i?n<i?1:-1:0}(l,o);e>0?(o=l,s=!1):0===e&&(s=!0)}return{count:n,firstNode:i,disambiguated:s?null:o}}(e,s,r.platform,a);if(i.push({selector:s.raw,matches:l.count}),0!==l.count&&l.firstNode){if(n&&1!==l.count){if(!r.disambiguateAmbiguous||!l.disambiguated)continue;return{node:l.disambiguated,selector:s,selectorIndex:o,matches:l.count,diagnostics:i}}return{node:l.firstNode,selector:s,selectorIndex:o,matches:l.count,diagnostics:i}}}return null}function pf(e,t,r){let a=r.requireRect??!1,n=[];for(let i=0;i<t.selectors.length;i+=1){let o=t.selectors[i],s=function(e,t,r,a){let n=0;for(let i of e)(!a||i.rect)&&ps(i,t,r)&&(n+=1);return n}(e,o,r.platform,a);if(n.push({selector:o.raw,matches:s}),s>0)return{selectorIndex:i,selector:o,matches:s,diagnostics:n}}return null}function pm(e,t,r){if(0===t.length)return`Selector did not match: ${e.raw}`;let a=t.map(e=>`${e.selector} -> ${e.matches}`).join(", ");return r.unique??!0?`Selector did not resolve uniquely (${a})`:`Selector did not match (${a})`}function ph(e){return e.rect?e.rect.width*e.rect.height:1/0}function pw(e,t,r={}){let a=[],n=c2(e.type??""),i=py(e.identifier),o=py(e.label),s=py(e.value),l=py(c5(e)),d="fill"===r.action;i&&a.push(`id=${pg(i)}`),n&&o&&a.push(d?`role=${pg(n)} label=${pg(o)} editable=true`:`role=${pg(n)} label=${pg(o)}`),o&&a.push(d?`label=${pg(o)} editable=true`:`label=${pg(o)}`),s&&a.push(d?`value=${pg(s)} editable=true`:`value=${pg(s)}`),l&&l!==o&&l!==s&&a.push(d?`text=${pg(l)} editable=true`:`text=${pg(l)}`),n&&d&&!a.some(e=>e.includes("editable=true"))&&a.push(`role=${pg(n)} editable=true`);let u=rw(a);return 0===u.length&&n&&u.push(d?`role=${pg(n)} editable=true`:`role=${pg(n)}`),0===u.length&&pl(e)&&u.push("visible=true"),u}function pg(e){return JSON.stringify(e)}function py(e){if(!e)return null;let t=e.trim();return t||null}function pv(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=pt(r?e.slice(0,-1):e.slice());return!a||a.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:a.selectorExpression,selectorTimeout:r?t:null}}async function pI(e){let{action:t,sessionName:r,logPath:a,sessionStore:n}=e;if(!(rb(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let i=n.get(r);if(!i)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),rb(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=pr(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=pv(e.positionals??[]);r&&t.push(r)}return rw(t).filter(e=>e.trim().length>0)})(t).map(e=>pe(e)).filter(e=>null!==e);if(0===o.length)return null;let s=rb(t.command)||"fill"===t.command,l=rb(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await pb(i,t,a,s,n);for(let e of o){let r=pp(d.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=pw(r.node,i.device.platform,{action:rb(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(rb(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=rh(t);if(!e)continue;return{...t,positionals:[a,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,a]}}if("is"===t.command){let{predicate:e,split:r}=pr(t.positionals);if(!e)continue;let n=r?.rest.join(" ").trim()??"",i=[e,a];return"text"===e&&n.length>0&&i.push(n),{...t,positionals:i}}if("wait"===t.command){let{selectorTimeout:e}=pv(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function pb(e,t,r,a,n){let i=await l7(e.device,"snapshot",[],t.flags?.out,{...db(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=i?.nodes??[],s={nodes:e_(t.flags?.snapshotRaw?o:c1(o)),truncated:i?.truncated,createdAt:Date.now(),backend:i?.backend};return e.snapshot=s,n.set(e.name,e),s}let pA=["platform","target","device","udid","serial","verbose","out"];async function pS(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e,o=t.positionals?.[0];if(!o)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay requires a path"}};let l="",d=new Set;try{l=rC.expandHome(o,t.meta?.cwd);let e=s.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay accepts .ad script files. JSON replay payloads are no longer supported."}};let c=function(e){let t=[];for(let r of e.split(/\r?\n/)){let e=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let r=function(e){let t=[],r=0;for(;r<e.length;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let a=r+1,n=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!n)break;n="\\"===t&&!n,"\\"!==t&&(n=!1),a+=1}if(a>=e.length)throw new W("INVALID_ARGS",`Invalid replay script line: ${e}`);let i=e.slice(r,a+1);t.push(JSON.parse(i)),r=a+1;continue}let a=r;for(;a<e.length&&!/\s/.test(e[a]);)a+=1;t.push(e.slice(r,a)),r=a}return t}(t);if(0===r.length)return null;let[a,...n]=r;if("context"===a)return null;let i={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){i.positionals=[];for(let e=0;e<n.length;e+=1){let t=n[e];if("-i"===t){i.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){i.flags.snapshotCompact=!0;continue}if("--raw"===t){i.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<n.length){let t=Number(n[e+1]);Number.isFinite(t)&&t>=0&&(i.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<n.length){i.flags.snapshotScope=n[e+1],e+=1;continue}if("--backend"===t&&e+1<n.length){e+=1;continue}}return i}if("open"===a){let e=function(e){var t;let r=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}r.push(t)}let n=rE(r);return{positionals:n.positionals,flags:a,runtime:(t=n.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?n.flags:void 0}}(n);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i.runtime=e.runtime,i}if("runtime"===a){let e=rE(n);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i}if(rb(a)){let e=rk(a,n);if(Object.assign(i.flags,e.flags),0===e.positionals.length)return i;let t=e.positionals[0];if(t.startsWith("@"))return i.positionals=[t],e.positionals[1]&&(i.result={refLabel:e.positionals[1]}),i;let r=e.positionals[0],o=e.positionals[1];return cW(r)&&cW(o)&&e.positionals.length>=2?i.positionals=[r,o]:i.positionals=[e.positionals.join(" ")],i}if("fill"===a){let e=rk(a,n);if(Object.assign(i.flags,e.flags),e.positionals.length<2)return i.positionals=e.positionals,i;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(i.positionals=[t,e.positionals.slice(2).join(" ")],i.result={refLabel:e.positionals[1]}):i.positionals=[t,e.positionals[1]],i):(i.positionals=[t,e.positionals.slice(1).join(" ")],i)}if("get"===a){if(n.length<2)return i.positionals=n,i;let e=n[0],t=n[1];return t.startsWith("@")?(i.positionals=[e,t],n[2]&&(i.result={refLabel:n[2]})):i.positionals=[e,n.slice(1).join(" ")],i}if("swipe"===a||"type"===a){let e=rk(a,n);return Object.assign(i.flags,e.flags),i.positionals=e.positionals,i}if("record"===a){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t];if("--hide-touches"===r){i.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<n.length){let e=Number(n[t+1]);Number.isFinite(e)&&(i.flags.fps=Math.floor(e)),t+=1;continue}e.push(r)}return i.positionals=e,i}if("screenshot"===a){let e=[];for(let t of n){if("--fullscreen"===t){i.flags.screenshotFullscreen=!0;continue}e.push(t)}return i.positionals=e,i}return i.positionals=n,i}(r);e&&t.push(e)}return t}(e),p=t.flags?.replayUpdate===!0,f=0;for(let e=0;e<c.length;e+=1){let o=c[e];if(!o||"replay"===o.command)continue;let s=await pN({req:t,sessionName:r,action:o,invoke:i});if(s.ok){px(s).forEach(e=>d.add(e));continue}if(!p)return p_(s,o,e,l,[...d]);let u=await pI({action:o,sessionName:r,logPath:a,sessionStore:n});if(!u)return p_(s,o,e,l,[...d]);if(c[e]=u,!(s=await pN({req:t,sessionName:r,action:u,invoke:i})).ok)return p_(s,u,e,l,[...d]);px(s).forEach(e=>d.add(e)),f+=1}return p&&f>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${rN(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",rS(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return rL(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(r_(r));return rD(t,e.flags),t.join(" ")}if("record"===e.command)return rM(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(rS(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}for(let r of e.positionals??[])t.push(rS(r));return rx(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
44
- `,i=`${e}.tmp-${process.pid}-${Date.now()}`;s.writeFileSync(i,n),s.renameSync(i,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:f,session:r,artifactPaths:[...d]}}}catch(t){let e=j(t);return{ok:!1,error:{code:e.code,message:e.message,details:d.size>0?{artifactPaths:[...d]}:void 0}}}}async function pN(e){let{req:t,sessionName:r,action:a,invoke:n}=e;return await n({token:t.token,session:r,command:a.command,positionals:a.positionals??[],flags:function(e,t){let r={...t??{}},a=e??{};for(let e of pA)void 0===r[e]&&void 0!==a[e]&&(r[e]=a[e]);return r}(t.flags,a.flags),runtime:a.runtime,meta:t.meta})}function p_(e,t,r,a,n=[]){let i;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${i=(t.positionals??[]).map(e=>rS(e)),[t.command,...i].join(" ")}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:a,step:o,action:t.command,positionals:t.positionals??[],artifactPaths:n}}}}function px(e){if(!e.ok||!e.data)return[];let t=[];if("string"==typeof e.data.path&&t.push(e.data.path),"string"==typeof e.data.outPath&&t.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let r of e.data.artifacts){if(!r||"object"!=typeof r)continue;let e="string"==typeof r.localPath?r.localPath:void 0,a="string"==typeof r.path?r.path:void 0;e?t.push(e):a&&t.push(a)}return[...new Set(t.filter(e=>(function(e){try{return s.statSync(e).isFile()}catch{return!1}})(e)))]}async function pD(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e;return"replay"===t.command?await pS({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}):"test"===t.command?await cX({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await pS({req:{...t,command:"replay",session:r,positionals:[e],flags:void 0===o?t.flags:{...t.flags??{},platform:o},meta:s?{...t.meta??{},requestId:s}:t.meta},sessionName:r,logPath:a,sessionStore:n,invoke:async e=>{var t;return t=await i(e),l&&px(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{n.get(e)&&await uj({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:n})}}):null}let pM=new Set(["session_list","ensure-simulator","devices","apps"]),pk=new Set(["boot","appstate"]),pE=new Set(["perf","logs","network"]),pO=new Set(["replay","test"]);async function pL(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,command:i,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=n.get(r),u=t.flags??{},c=dU(i,d,u);if(c)return c;let p=await dj({session:d,flags:u,ensureReady:!0});if(!dI(i,p))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${i} is not supported on this device`}};let f=await l7(p,i,o,t.flags?.out,{...db(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,f,p):d;n.recordAction(e,{command:i,positionals:s??o,flags:t.flags??{},result:f??{}}),e!==d&&n.set(r,e)}return{ok:!0,data:f??{}}}async function pC(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,i=n.get(r),o=t.flags??{},s=dU("clipboard",i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return{ok:!1,error:{code:"INVALID_ARGS",message:"clipboard requires a subcommand: read or write"}};let d=await dj({session:i,flags:o,ensureReady:!0});if(!dI("clipboard",d))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"clipboard is not supported on this device"}};let u=await l7(d,"clipboard",t.positionals??[],t.flags?.out,{...db(a,t.flags,i?.appBundleId,i?.trace?.outPath)});return i&&n.recordAction(i,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function pP(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e;if(pM.has(t.command))return await u2({req:t,sessionName:r,sessionStore:n});if("runtime"===t.command)return await um({req:t,sessionName:r,sessionStore:n});if(pk.has(t.command))return await u6({req:t,sessionName:r,sessionStore:n});if("clipboard"===t.command)return await pC({req:t,sessionName:r,logPath:a,sessionStore:n});if("keyboard"===t.command){let e=n.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i||"ios"!==(t.flags??{}).platform?await pL({req:t,sessionName:r,logPath:a,sessionStore:n,command:"keyboard",positionals:t.positionals??[]}):{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first."}}}if(pE.has(t.command))return await cT({req:t,sessionName:r,sessionStore:n});if("install"===t.command||"reinstall"===t.command)return await uz({req:t,command:t.command,sessionName:r,sessionStore:n,deployOps:"install"===t.command?uW:uH});if("install_source"===t.command)return await dP({req:t,sessionName:r,sessionStore:n});if("release_materialized_paths"===t.command)return await dT({req:t});if("push"===t.command){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await pL({req:t,sessionName:r,logPath:a,sessionStore:n,command:"push",positionals:[i,"file"===(e=lU(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>rC.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):{ok:!1,error:{code:"INVALID_ARGS",message:"push requires <bundle|package> <payload.json|inline-json>"}}}return"trigger-app-event"===t.command?await pL({req:t,sessionName:r,logPath:a,sessionStore:n,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await uk(e.device,r,e.appBundleId,uM)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await uU({req:t,sessionName:r,logPath:a,sessionStore:n}):pO.has(t.command)?await pD({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}):"batch"===t.command?await uK(t,r,i):"close"===t.command?await uj({req:t,sessionName:r,logPath:a,sessionStore:n}):null}function pR(e,t){let r=er(e.type??"Element"),a=V(e,r),n=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),r,a,n,i,o].join("|")}function pT(e,t){return t.flatten?e.map(e=>({text:x(e,0,!1),comparable:pR(e,0)})):Z(e).map(e=>({text:e.text,comparable:pR(e.node,e.depth)}))}function p$(e,t){return e.get(t)??0}async function pF(e){let t=ub(e.session);if(t&&"android"===e.device.platform)return await pG(e,t);let r=await pU(e);return uA(e.session),{snapshot:pj(r,e.flags),analysis:r.analysis}}async function pU(e){let{device:t,session:r,flags:a,outPath:n,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await lO(r?.surface);return pq({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&r?.surface&&"app"!==r.surface?pq(await oY(r.surface,{bundleId:"menubar"===r.surface?r.appBundleId:void 0}),{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o}):await l7(t,"snapshot",[],n,{...db(i,{...a,snapshotScope:o},r?.appBundleId,r?.trace?.outPath)})}async function pG(e,t){let r=await pV(e),a=pB(r,t,e.flags),n=0;for(let i of uv){if(!a)break;await new Promise(e=>setTimeout(e,i)),r=await pV(e),n+=1,a=pB(r,t,e.flags)}return a||uA(e.session),{snapshot:r.snapshot,analysis:r.data.analysis,freshness:n>0||a?{action:t.action,retryCount:n,staleAfterRetries:!!a,reason:a??void 0}:void 0}}async function pV(e){let t=await pU(e);return{data:t,snapshot:pj(t,e.flags)}}function pB(e,t,r){let a=r?.snapshotInteractiveOnly===!0,n=e.data.analysis;return a&&0===e.snapshot.nodes.length&&n&&n.rawNodeCount>=12?"empty-interactive":u_(t.baselineCount,e.snapshot.nodes.length)?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&uS(t.action)&&function(e,t){if(!e||0===e.length)return!1;let r=Math.max(e.length,t.length);if(r<12)return!1;let a=uN(t),n=Math.min(e.length,a.length),i=0;for(let t=0;t<n;t+=1)e[t]===a[t]&&(i+=1);let o=Math.max(0,a.length-e.length),s=Math.max(0,e.length-a.length),l=Math.max(3,Math.floor(.15*r));return i>=Math.floor(.9*r)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function pj(e,t){let r=e?.nodes??[],a=ef(t?.snapshotRaw?r:c1(r));return{nodes:e_(t?.snapshotScope&&e?.backend!=="macos-helper"?pH(a,t.snapshotScope):a),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function pq(e,t){var r,a;let n=e.nodes??[];return t.snapshotScope&&(n=pH(n,t.snapshotScope)),t.snapshotInteractiveOnly&&(n=function(e){if(0===e.length)return e;let t=new Map;for(let r of e)t.set(r.index,r);let r=new Set;for(let a of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(a))continue;let e=a;for(;e&&!r.has(e.index);)r.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===r.size?e:pW(e.filter(e=>r.has(e.index)))}(n)),"number"==typeof t.snapshotDepth&&(r=n,a=t.snapshotDepth,n=pW(r.filter(e=>(e.depth??0)<=a))),{...e,nodes:n}}function pH(e,t){let r=cZ(e_(e),t);if(!r)return[];let a=e.findIndex(e=>e.index===r.index);if(-1===a)return[];let n=e[a]?.depth??0,i=[];for(let t=a;t<e.length;t+=1){let r=e[t];if(!r)continue;let o=r.depth??0;if(t>a&&o<=n)break;i.push(r)}return pW(i,n)}function pW(e,t=0){let r=new Map;for(let[t,a]of e.entries())r.set(a.index,t);return e.map((e,a)=>({...e,index:a,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?r.get(e.parentIndex):void 0}))}function pz(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"Ref scope requires an existing snapshot in session."}}};let r=eh(e.trim());if(!r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref scope: ${e}`}}};let a=eu(t.snapshot.nodes,r),n=a?cQ(a,t.snapshot.nodes):void 0;return n?{ok:!0,scope:n}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${e} not found or has no label`}}}}async function pJ(e,t,r){let a=e.get(t),n=a?.device??await l9(r??{});return a||await dS(n),{session:a,device:n}}async function pK(e,t,r){let a=!e&&"ios"===t.platform;try{return await r()}finally{a&&await ro(t.id)}}function pX(e,t,r,a){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:a})}function pY(e){let{session:t,sessionName:r,device:a,snapshot:n,appBundleId:i}=e;return t?{...t,snapshot:n}:{name:r,device:a,createdAt:Date.now(),appBundleId:i,snapshot:n,actions:[]}}function pZ(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}async function pQ(e){let{parsed:t,req:r,sessionName:a,logPath:n,sessionStore:i,session:o,device:s}=e;if("sleep"===t.kind)return await new Promise(e=>setTimeout(e,t.durationMs)),pX(i,o,r,{waitedMs:t.durationMs}),{ok:!0,data:{waitedMs:t.durationMs}};if(!dI("wait",s))return uq("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===t.kind)return await p0({device:s,logPath:n,parsed:t,req:r,session:o,sessionName:a,sessionStore:i});let l=function(e,t){if("ref"===e.kind){if(!t?.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"Ref wait requires an existing snapshot in session."}}};let r=eh(e.rawRef);if(!r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref: ${e.rawRef}`}}};let a=eu(t.snapshot.nodes,r),n=a?cQ(a,t.snapshot.nodes):void 0;return n?{ok:!0,text:n,timeoutMs:e.timeoutMs}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${e.rawRef} not found or has no label`}}}}return e.text?{ok:!0,text:e.text,timeoutMs:e.timeoutMs}:{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires text"}}}}(t,o);return l.ok?await p1({device:s,logPath:n,req:r,session:o,sessionStore:i,text:l.text,timeoutMs:l.timeoutMs}):l.response}async function p0(e){let{device:t,logPath:r,parsed:a,req:n,session:i,sessionName:o,sessionStore:s}=e,l=a.timeoutMs??1e4,d=Date.now();for(;Date.now()-d<l;){let e=pf((await p2({device:t,logPath:r,req:n,session:i,sessionName:o,sessionStore:s})).nodes,a.selector,{platform:t.platform});if(e)return p3(s,i,n,{selector:e.selector.raw,waitedMs:Date.now()-d});await new Promise(e=>setTimeout(e,300))}return uq("COMMAND_FAILED",`wait timed out for selector: ${a.selectorExpression}`)}async function p1(e){let{device:t,logPath:r,req:a,session:n,sessionStore:i,text:o,timeoutMs:s}=e,l=s??1e4,d=Date.now();for(;Date.now()-d<l;){if("macos"===t.platform&&n?.surface&&"app"!==n.surface){if(cZ((await p2({device:t,logPath:r,req:a,session:n,sessionName:n?.name??a.session??"default",sessionStore:i})).nodes,o))return p3(i,n,a,{text:o,waitedMs:Date.now()-d})}else if(tN(t.platform)){let e=await rf(t,{command:"findText",text:o,appBundleId:n?.appBundleId},{verbose:a.flags?.verbose,logPath:r,traceLogPath:n?.trace?.outPath,requestId:a.meta?.requestId});if(e?.found)return pX(i,n,a,{text:o,waitedMs:Date.now()-d}),{ok:!0,data:{text:o,waitedMs:Date.now()-d}}}else if("android"===t.platform&&cZ((await p2({device:t,logPath:r,req:a,session:n,sessionName:n?.name??a.session??"default",sessionStore:i})).nodes,o))return pX(i,n,a,{text:o,waitedMs:Date.now()-d}),{ok:!0,data:{text:o,waitedMs:Date.now()-d}};await new Promise(e=>setTimeout(e,300))}return uq("COMMAND_FAILED",`wait timed out for text: ${o}`)}async function p2(e){let{device:t,logPath:r,req:a,session:n,sessionName:i,sessionStore:o}=e,{snapshot:s}=await pF({device:t,session:n,flags:{...a.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:a.flags?.out,logPath:r});return n&&(n.snapshot=s,o.set(i,n)),s}function p3(e,t,r,a){return pX(e,t,r,a),{ok:!0,data:a}}async function p4(e){let{req:t,logPath:r,sessionStore:a,session:n,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=n?"frontmost-app"===n.surface?{surface:"frontmost-app"}:{bundleId:n.appBundleId,surface:n.surface}:{};if(!dI("alert",i))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"alert is not supported on this device"}};if("macos"===i.platform){let e=async()=>await oX("wait"===o?"get":o,s);if("wait"===o){let r=pZ(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<r;){try{let r=await e();return pX(a,n,t,r),{ok:!0,data:r}}catch{}await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"alert wait timed out"}}}let r="accept"===o||"dismiss"===o?o:"get";if("accept"===r||"dismiss"===r){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await oX(r,s);return pX(a,n,t,e),{ok:!0,data:e}}catch(r){e=r;let t=String(r?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await new Promise(e=>setTimeout(e,300))}throw p5(e)}let i=await oX("get",s);return pX(a,n,t,i),{ok:!0,data:i}}if("wait"===o){let e=pZ(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await rf(i,{command:"alert",action:"get",appBundleId:n?.appBundleId},{verbose:t.flags?.verbose,logPath:r,traceLogPath:n?.trace?.outPath,requestId:t.meta?.requestId});return pX(a,n,t,e),{ok:!0,data:e}}catch{}await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"alert wait timed out"}}}let l="accept"===o||"dismiss"===o?o:"get",d={verbose:t.flags?.verbose,logPath:r,traceLogPath:n?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,r=Date.now();for(;Date.now()-r<2e3;){try{let e=await rf(i,{command:"alert",action:l,appBundleId:n?.appBundleId},d);return pX(a,n,t,e),{ok:!0,data:e}}catch(r){e=r;let t=String(r?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await new Promise(e=>setTimeout(e,300))}throw p5(e)}let u=await rf(i,{command:"alert",action:l,appBundleId:n?.appBundleId},d);return pX(a,n,t,u),{ok:!0,data:u}}function p5(e){if(!(e instanceof W))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new W(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}async function p8(e){let{req:t,logPath:r,sessionStore:a,session:n,device:i,parsed:o}=e,{setting:s,state:l,permissionTarget:d}=o;if(!dI("settings",i))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"settings is not supported on this device"}};if("macos"===i.platform&&!E(s))return{ok:!1,error:{code:"INVALID_ARGS",message:K(s)}};let u=n?.appBundleId,c="permission"===s?[s,l,d??"",t.positionals?.[3]??"",u??""]:[s,l,u??""],p=await l7(i,"settings",c,t.flags?.out,{...db(r,t.flags,u,n?.trace?.outPath)});return pX(a,n,t,p??{setting:s,state:l}),{ok:!0,data:p??{setting:s,state:l}}}let p6=new Set(["snapshot","diff","wait","alert","settings"]);async function p9(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,i=t.command;if(!p6.has(i))return null;if("snapshot"===i){let{session:e,device:i}=await pJ(n,r,t.flags);if(!dI("snapshot",i))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"snapshot is not supported on this device"}};let o=pz(t.flags?.snapshotScope,e);return o.ok?await pK(e,i,async()=>{let s=await pF({device:i,session:e,flags:t.flags,outPath:t.flags?.out,logPath:a,snapshotScope:o.scope}),l=p7({capture:s,flags:t.flags,session:e}),d=function(e){var t;let{nodes:r,backend:a,snapshotRaw:n}=e;if(n||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:r.length,totalNodeCount:r.length,reasons:[]};let i=Q(r),o=new Set;return i.hiddenCount>0&&o.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:r.length,reasons:[...o]}}({nodes:s.snapshot.nodes,backend:s.snapshot.backend,snapshotRaw:t.flags?.snapshotRaw}),u=pY({session:e,sessionName:r,device:i,snapshot:s.snapshot,appBundleId:e?.appBundleId});return pX(n,u,t,{nodes:s.snapshot.nodes.length,truncated:s.snapshot.truncated??!1}),n.set(r,u),{ok:!0,data:{nodes:s.snapshot.nodes,truncated:s.snapshot.truncated??!1,visibility:d,...l.length>0?{warnings:l}:{},appName:u.appBundleId?u.appName??u.appBundleId:void 0,appBundleId:u.appBundleId}}}):o.response}if("diff"===i)return t.positionals?.[0]!=="snapshot"?{ok:!1,error:{code:"INVALID_ARGS",message:"diff currently supports only: diff snapshot"}}:await fe({req:t,sessionName:r,logPath:a,sessionStore:n});if("wait"===i){let{session:e,device:i}=await pJ(n,r,t.flags),o=function(e){if(0===e.length)return null;let t=pZ(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=pZ(e[e.length-1]);return{kind:"text",text:(null!==t?e.slice(1,-1).join(" "):e.slice(1).join(" ")).trim(),timeoutMs:t}}if(e[0].startsWith("@")){let t=pZ(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let r=pZ(e[e.length-1]),a=pt(null!==r?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=pe(a.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:a.selectorExpression,timeoutMs:r}}return{kind:"text",text:(null!==r?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:r}}(t.positionals??[]);if(!o)return{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires a duration or text"}};let s=()=>pQ({parsed:o,req:t,sessionName:r,logPath:a,sessionStore:n,session:e,device:i});return"sleep"===o.kind?await s():await pK(e,i,s)}if("alert"===i){let{session:e,device:i}=await pJ(n,r,t.flags);return await pK(e,i,async()=>await p4({req:t,logPath:a,sessionStore:n,session:e,device:i}))}if("settings"===i){let e,i,o,s=(e=t.positionals?.[0]?.toLowerCase(),i=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&i&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:i,permissionTarget:o}}:{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:R}}});if(!s.ok)return s.response;let{session:l,device:d}=await pJ(n,r,t.flags);return await pK(l,d,async()=>await p8({req:t,logPath:a,sessionStore:n,session:l,device:d,parsed:s.parsed}))}return null}function p7(e){let{capture:t,flags:r,session:a}=e,n=[],i=t.analysis,o=r?.snapshotInteractiveOnly===!0;"android"===t.snapshot.backend&&o&&0===t.snapshot.nodes.length&&i&&i.rawNodeCount>=12&&(n.push(`Interactive snapshot is empty after filtering ${i.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof r?.snapshotDepth&&i.maxDepth>=r.snapshotDepth+2&&n.push(`Interactive output is empty at depth ${r.snapshotDepth}; retry without -d.`));let s=a?.snapshot;return!t.freshness&&s&&Date.now()-s.createdAt<=2e3&&u_(s.nodes.length,t.snapshot.nodes.length)&&n.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once."),t.freshness?.staleAfterRetries&&"android"===t.snapshot.backend&&("stuck-route"===t.freshness.reason?n.push(`Recent ${t.freshness.action} was followed by a nearly identical snapshot after ${t.freshness.retryCount} automatic retr${1===t.freshness.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`):"sharp-drop"===t.freshness.reason&&n.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.")),rw(n)}async function fe(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,{session:i,device:o}=await pJ(n,r,t.flags);if(!dI("diff",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"diff is not supported on this device"}};let s=pz(t.flags?.snapshotScope,i);if(!s.ok)return s.response;let l=t.flags?.snapshotInteractiveOnly===!0;return await pK(i,o,async()=>{let e=await pF({device:o,session:i,flags:t.flags,outPath:t.flags?.out,logPath:a,snapshotScope:s.scope}),d=e.snapshot,u=p7({capture:e,flags:t.flags,session:i});if(!i?.snapshot){let e=function(e,t={}){return pT(e,t).length}(d.nodes,{flatten:l}),a=pY({session:i,sessionName:r,device:o,snapshot:d,appBundleId:i?.appBundleId});return pX(n,a,t,{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:e}}),n.set(r,a),{ok:!0,data:{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:e},lines:[],...u.length>0?{warnings:u}:{}}}}let c=function(e,t,r={}){let a=function(e,t){let r=e.length,a=t.length,n=r+a,i=new Map,o=[];i.set(1,0);for(let s=0;s<=n;s+=1){o.push(new Map(i));for(let n=-s;n<=s;n+=2){let l=n===-s||n!==s&&p$(i,n-1)<p$(i,n+1)?p$(i,n+1):p$(i,n-1)+1,d=l-n;for(;l<r&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(n,l),l>=r&&d>=a)return function(e,t,r,a,n){let i=[],o=a,s=n;for(let a=e.length-1;a>=0;a-=1){let n=e[a],l=o-s,d=l===-a||l!==a&&p$(n,l-1)<p$(n,l+1)?l+1:l-1,u=p$(n,d),c=u-d;for(;o>u&&s>c;)i.push({kind:"unchanged",text:r[s-1].text}),o-=1,s-=1;if(0===a)break;o===u?(i.push({kind:"added",text:r[c].text}),s=c):(i.push({kind:"removed",text:t[u].text}),o=u)}return i.reverse(),i}(o,e,t,r,a)}}return[]}(pT(e,r),pT(t,r)),n={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(n.additions+=1),"removed"===e.kind&&(n.removals+=1),"unchanged"===e.kind&&(n.unchanged+=1);return{summary:n,lines:a}}(i.snapshot.nodes,d.nodes,{flatten:l}),p={...i,snapshot:d};return pX(n,p,t,{mode:"snapshot",baselineInitialized:!1,summary:c.summary}),n.set(r,p),{ok:!0,data:{mode:"snapshot",baselineInitialized:!1,summary:c.summary,lines:c.lines,...u.length>0?{warnings:u}:{}}}})}function ft(e,t,r,a={}){let n=fa(r);if(!n)return{matches:[],score:0};let i=0,o=[];for(let r of e){if(a.requireRect&&!r.rect)continue;let e=function(e,t,r){switch(t){case"role":return function(e,t){let r=function(e){let t=e.trim();return t?t=(t.split(".").pop()??t).replace(/XCUIElementType/gi,"").toLowerCase():""}(e??"");return r?r===t?2:+!!r.includes(t):0}(e.type,r);case"label":return fr(e.label,r);case"value":return fr(e.value,r);case"id":return fr(e.identifier,r);default:return Math.max(fr(e.label,r),fr(e.value,r),fr(e.identifier,r))}}(r,t,n);if(!(e<=0)){if(e>i){i=e,o.length=0,o.push(r);continue}e===i&&o.push(r)}}return{matches:o,score:i}}function fr(e,t){let r=fa(e??"");return r?r===t?2:+!!r.includes(t):0}function fa(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function fn(e){let{session:t,refInput:r,fallbackLabel:a,requireRect:n,invalidRefMessage:i,notFoundMessage:o}=e;if(!t.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"No snapshot in session. Run snapshot first."}}};let s=eh(r);if(!s)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:i}}};let l=eu(t.snapshot.nodes,s);return((!l||n&&!l.rect)&&a.length>0&&(l=cZ(t.snapshot.nodes,a)),l&&(!n||l.rect))?{ok:!0,target:{ref:s,node:l,snapshotNodes:t.snapshot.nodes}}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:o}}}}function fi(e){let t=fo(e);if(!t)return null;let r=eS(t);return Number.isFinite(r.x)&&Number.isFinite(r.y)?r:null}function fo(e){if(!e)return null;let t=Number(e.x),r=Number(e.y),a=Number(e.width),n=Number(e.height);return Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(a)&&Number.isFinite(n)&&!(a<0)&&!(n<0)?{x:t,y:r,width:a,height:n}:null}async function fs(e){let{session:t,refInput:r,fallbackLabel:a,commandLabel:n,promoteToHittableAncestor:i,invalidRefMessage:o,missingBoundsMessage:s,invalidBoundsMessage:l,reqFlags:d,sessionStore:u,contextFromFlags:c,captureSnapshotForSession:p,resolveRefTarget:f}=e,m=f({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:o,notFoundMessage:s});if(!m.ok)return{ok:!1,response:m.response};let{ref:h}=m.target,w=i?fl(m.target.snapshotNodes,m.target.node):m.target.node,g=m.target.snapshotNodes,y=fi(w.rect);if(!y){let e=await p(t,d,u,c,{interactiveOnly:!0}),r=eu(e.nodes,h),n=a.length>0?cZ(e.nodes,a):null,o=r&&i?fl(e.nodes,r):r,s=n&&i?fl(e.nodes,n):n,l=fi(s?.rect),f=fi(o?.rect)?o:l?s:o??s,m=fi(f?.rect);f&&m&&(w=f,g=e.nodes,y=m)}if(!y)return{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:l}}};let v=w.rect?J(w,g):null;return w.rect&&v&&!k(w,g)?{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${r} is off-screen and not safe to ${n}`,hint:`Run scrollintoview ${r}, then retry ${n} with the returned currentRef or a fresh snapshot.`,details:{reason:"offscreen_ref",ref:h,rect:w.rect,viewport:v}}}}:{ok:!0,target:{ref:h,node:w,snapshotNodes:g,point:y}}}function fl(e,t){let r=function(e,t){let r=fo(t.rect);if(!r)return null;let a=t,n=new Set;for(;!n.has(a.ref);){n.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=fo(e.rect);return!!t&&fd(t,r)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(r?.rect&&fi(r.rect))return r;let a=c4(e,t);return a?.rect&&fi(a.rect)?!function(e,t,r){var a,n,i,o;let s,l,d,u=fo(e.rect),c=fo(t.rect);if(!u||!c)return!1;let p=function(e,t){let r=eS(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>fo(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let n=a.filter(e=>F(e,r.x,r.y));return em(n.length>0?n:a)}(r,u);return!!p&&(a=c,n=p,s=(i=a,o=n,Math.max(0,Math.min(i.x+i.width,o.x+o.width)-Math.max(i.x,o.x))*Math.max(0,Math.min(i.y+i.height,o.y+o.height)-Math.max(i.y,o.y))),l=a.width*a.height,d=n.width*n.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!fd(u,c)}(t,a,e)?a:t:t}function fd(e,t){return .5>=Math.abs(e.x-t.x)&&.5>=Math.abs(e.y-t.y)&&.5>=Math.abs(e.width-t.width)&&.5>=Math.abs(e.height-t.height)}async function fu(e){let{device:t,node:r,flags:a,appBundleId:n,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=z(r),d=fi(r.rect);if(!d)return l;try{let e=await l7(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,n,i),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return ep({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:o,platform:t.platform}}),l}catch(e){return ep({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:r.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}async function fc(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return uq("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:p}=function(e){let t="any",r=0;["text","label","value","role","id"].includes(e[0])&&(t=e[0],r=1);let a=e[r]??"",n=e.slice(r+1);if(0===n.length)return{locator:t,query:a,action:"click"};let i=n[0].toLowerCase();if("get"===i){let e=n[1]?.toLowerCase();if("text"===e)return{locator:t,query:a,action:"get_text"};if("attrs"===e)return{locator:t,query:a,action:"get_attrs"};throw new W("INVALID_ARGS","find get only supports text or attrs")}if("wait"===i)return{locator:t,query:a,action:"wait",timeoutMs:pZ(n[1])??void 0};if("exists"===i)return{locator:t,query:a,action:"exists"};if("click"===i)return{locator:t,query:a,action:"click"};if("focus"===i)return{locator:t,query:a,action:"focus"};if("fill"===i)return{locator:t,query:a,action:"fill",value:n.slice(1).join(" ")};if("type"===i)return{locator:t,query:a,action:"type",value:n.slice(1).join(" ")};throw new W("INVALID_ARGS",`Unsupported find action: ${n[0]}`)}(s);if(!d)return uq("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return uq("INVALID_ARGS","find accepts only one of --first or --last");let f=n.get(r);if(!f&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return uq("SESSION_NOT_FOUND","No active session. Run open first.");let m=f?.device??await l9(t.flags??{});f||await dS(m);let h="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,g=0,y=null,v=async()=>{let e=Date.now();if(y&&e-g<750&&!ub(f))return{nodes:y};let{snapshot:i}=await pF({device:m,session:f,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:h}),o=i.nodes;return g=e,y=o,f&&(f.snapshot=i,n.set(r,f)),{nodes:o,truncated:i.truncated,backend:i.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i,session:f,device:m,command:o,locator:l,query:d};if("wait"===u)return fp(I,v,l,d,p);let{nodes:b}=await v(),A=ft(b,l,d,{requireRect:w});if(w&&A.matches.length>1)if(t.flags?.findFirst)A.matches=[A.matches[0]];else{if(!t.flags?.findLast){var S,N,_;let e;return S=A.matches,N=l,_=d,e=S.slice(0,8).map(e=>{let t=c5(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),{ok:!1,error:{code:"AMBIGUOUS_MATCH",message:`find matched ${S.length} elements for ${N} "${_}". Use a more specific locator or selector.`,details:{locator:N,query:_,matches:S.length,candidates:e}}}}A.matches=[A.matches[A.matches.length-1]]}let x=A.matches[0]??null;if(!x)return uq("COMMAND_FAILED","find did not match any element");let D="click"===u||"focus"===u||"fill"===u||"type"===u?c4(b,x)??x:x,M=`@${D.ref}`,k={node:x,resolvedNode:D,ref:M,nodes:b,actionFlags:{...t.flags??{},noRecord:!0}},E={exists:()=>ff(I),get_text:()=>fm(I,k),get_attrs:()=>fh(I,k),click:()=>fw(I,k),fill:()=>fg(I,k,c),focus:()=>fy(I,k),type:()=>fv(I,k,c)}[u];return E?E():null}async function fp(e,t,r,a,n){let{req:i,sessionStore:o,session:s,command:l}=e,d=n??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(ft(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:i.positionals??[],flags:i.flags??{},result:{found:!0,waitedMs:Date.now()-u}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-u}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"find wait timed out"}}}async function ff(e){let{req:t,sessionStore:r,session:a,command:n}=e;return a&&r.recordAction(a,{command:n,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function fm(e,t){let{req:r,sessionStore:a,session:n,command:i,device:o,logPath:s}=e,l=await fu({device:o,node:t.node,flags:r.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:(e,t,r)=>db(s,e,t,r)});return n&&a.recordAction(n,{command:i,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get text",text:l}}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function fh(e,t){let{req:r,sessionStore:a,session:n,command:i}=e;return n&&a.recordAction(n,{command:i,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function fw(e,t){let{req:r,sessionName:a,sessionStore:n,session:i,invoke:o,command:s,locator:l,query:d}=e,u=await o({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let c=t.resolvedNode.rect?eS(t.resolvedNode.rect):null,p={ref:t.ref,locator:l,query:d};return c&&(p.x=c.x,p.y=c.y),i&&n.recordAction(i,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:p}}async function fg(e,t,r){let{req:a,sessionName:n,sessionStore:i,session:o,invoke:s,command:l}=e;if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"find fill requires text"}};let d=await s({token:a.token,session:n,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&i.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function fy(e,t){let{req:r,sessionStore:a,session:n,device:i,command:o,logPath:s}=e,l=t.node.rect?eS(t.node.rect):null;if(!l)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};let d=await l7(i,"focus",[String(l.x),String(l.y)],r.flags?.out,{...db(s,r.flags,n?.appBundleId,n?.trace?.outPath)});return n&&a.recordAction(n,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function fv(e,t,r){let{req:a,sessionStore:n,session:i,device:o,command:s,logPath:l}=e;if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"find type requires text"}};let d=t.node.rect?eS(t.node.rect):null;if(!d)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};await l7(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...db(l,a.flags,i?.appBundleId,i?.trace?.outPath)});let u=await l7(o,"type",[r],a.flags?.out,{...db(l,a.flags,i?.appBundleId,i?.trace?.outPath)});return i&&n.recordAction(i,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let fI=`
39
+ </map>`)}function ut(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return d7(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function ur(e){let t=e?.trim();return t&&t.length>0?t:void 0}function ua(e){if("binary"!==nf(e))return;let t=nm(e);throw new O("INVALID_ARGS",t,{package:e,hint:t})}function un(e){if(Number.isInteger(e)&&!(e<=0)&&!(e>65535))return e}function ui(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function uo(e,t){let r=`${e}
40
+ ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}let us=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function ul(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ud(e){let t=e?.trim();return t&&t.length>0?t:void 0}function uu(e,t){if(void 0!==e){if("string"!=typeof e)throw new O("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return ud(e)}}function uc(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new O("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function up(e){if("ios"===e||"android"===e)return e}async function uf(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:n}=e;!t||!n?.appBundleId||!dQ(r)||dQ(a)||await d2({device:n.device,appId:n.appBundleId})}async function um(e){var t,r;let{req:a,sessionName:n,sessionStore:i}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=i.get(n),l=i.getRuntimeHints(n);if(!["set","show","clear"].includes(o))return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime requires set, show, or clear"}};if("clear"===o){dQ(l)&&s?.appBundleId&&await d2({device:s.device,appId:s.appBundleId});let e=i.clearRuntimeHints(n);return{ok:!0,data:{session:n,cleared:e}}}if("show"===o)return{ok:!0,data:{session:n,configured:!!l,runtime:l}};let d=up(a.flags?.platform??l?.platform??s?.device.platform);if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first."}};if(s&&s.device.platform!==d)return{ok:!1,error:{code:"INVALID_ARGS",message:`runtime set targets ${d}, but session "${n}" is already bound to ${s.device.platform}.`}};let u={platform:(t=a.flags,r={platform:d,metroHost:ud(t?.metroHost),metroPort:uc(t?.metroPort),bundleUrl:ud(t?.bundleUrl),launchUrl:ud(t?.launchUrl)}).platform??l?.platform,metroHost:r.metroHost??l?.metroHost,metroPort:r.metroPort??l?.metroPort,bundleUrl:r.bundleUrl??l?.bundleUrl,launchUrl:r.launchUrl??l?.launchUrl};return 0===ul(u)?{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."}}:(i.setRuntimeHints(n,u),{ok:!0,data:{session:n,configured:!0,runtime:u}})}let uh="open-command-roundtrip",uw="Not implemented for this platform in this release.",ug=new Set(["app","desktop","frontmost-app"]);async function uy(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await oz();return{appBundleId:t.bundleId,appName:t.appName}}let uv=[250,400];function uI(e,t,r=e.snapshot){if("android"!==e.device.platform)return;let a=r?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:r?.nodes.length??0,baselineSignatures:a?uN(r?.nodes??[]):void 0,routeComparable:a}}function ub(e){if(!e||"android"!==e.device.platform)return;let t=e.androidSnapshotFreshness;if(t)return Date.now()-t.markedAt>2500?void delete e.androidSnapshotFreshness:t}function uA(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function uS(e){return"press"===e||"click"===e||"back"===e||"open"===e}function uN(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}function u_(e,t){return!(e<12)&&t<=Math.floor(.2*e)}async function ux(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return aQ(t)?"macos"===e.platform?void 0:"device"===e.kind?a0(r,t):void 0:await uD(e,t)}async function uD(e,t){try{let{resolveIosApp:r}=await Promise.resolve(eO);return await r(e,t)}catch{return}}async function uM(e,t){if(!("android"!==e.platform||!t||aQ(t)))try{let{resolveAndroidApp:r}=await Promise.resolve(eM),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function uk(e,t,r,a){return await ux(e,t,r)??await a(e,t)??("android"===e.platform&&t&&aQ(t)?r:void 0)}function uE(e){return{ok:!1,error:{code:"INVALID_ARGS",message:e}}}function uO(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:n}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return n??"app";if("linux"===t.platform){if(!r)return"app";let e=eI(r);if(!ug.has(e))throw new O("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new O("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new O("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let i=r?eI(r):"app";if("app"!==i&&"menubar"!==i&&a)throw new O("INVALID_ARGS",`open --surface ${i} does not accept an app target`);return i}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return{ok:!1,error:{code:e instanceof O?e.code:"INVALID_ARGS",message:String(e.message)}}}}function uL(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:n}=e;return t?r&&aQ(r)?uE("open --relaunch does not support URL targets."):"app"!==a?uE("open --relaunch is supported only for app surfaces."):"android"===n.platform&&r&&"binary"===nf(r)?uE(nm(r)):null:null}async function uC(e){let{req:t,sessionName:r,sessionStore:a,device:n,surface:i,openTarget:o,existingSession:s}=e;await dS(n);let{appBundleId:l,appName:d}=await uP({device:n,surface:i,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:n}=e,i=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new O("INVALID_ARGS","open runtime must be an object.");let n=Object.keys(t).find(e=>!us.includes(e));if(n)throw new O("INVALID_ARGS",`Invalid open runtime field: ${n}. Supported fields are ${us.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new O("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new O("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:uu(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new O("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return uc(e)}}(t.metroPort),bundleUrl:uu(t.bundleUrl,"bundleUrl"),launchUrl:uu(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:up(n.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let n=r?.platform,i=up(n);if(a.platform&&r&&!i)throw new O("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${n}.`);if(a.platform&&i&&a.platform!==i)throw new O("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${n}. Clear the runtime hints or use a different session.`);return i&&a.platform!==i?{...a,platform:i}:a}(r,a,n),previousRuntime:i,replacedStoredRuntime:!1}:{runtime:o&&ul(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=k(t);return{ok:!1,response:{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}}({req:t,sessionStore:a,sessionName:r,device:n});if(!u.ok)return{type:"response",response:u.response};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await uf({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function uP(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:n}=e,i=await uy(r);return{appBundleId:i.appBundleId??await uk(t,a,n,uM),appName:i.appName??a}}let uR=new Map;async function uT(e){let{device:t,closeTarget:r,outFlag:a,context:n}=e;"android"!==t.platform&&await ro(t.id),await l7(t,"close",[r],a,n),await dB(t,d$)}async function u$(e){let{runtime:t,device:r,req:a,logPath:n,appBundleId:i,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||aQ(d)||await l7(r,"open",[l],a.flags?.out,{...db(n,a.flags,i,o)})}async function uF(e){var t,r,a;let{req:n,sessionName:i,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:p,appBundleId:f,runtime:m,existingSession:h}=e,w=n.flags?.relaunch===!0,g=h?.trace?.outPath;if(w&&d){let e=f??d;await uT({device:l,closeTarget:e,outFlag:n.flags?.out,context:{...db(s,n.flags,f??h?.appBundleId,g)}})}await d1({device:l,appId:f,runtime:m});let y=Date.now();await l7(l,"open",u,n.flags?.out,{...db(s,n.flags,f)}),await u$({runtime:m,device:l,req:n,logPath:s,appBundleId:f,traceLogPath:g,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:uh,appTarget:d,appBundleId:f}:void 0;if(await dB(l,dF),eX(n.meta?.requestId)){let e=eZ();return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}h&&uI(h,"open",h.snapshot);let I=function(e){let{existingSession:t,sessionName:r,device:a,surface:n,appBundleId:i,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:n,appBundleId:i,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:n,appBundleId:i,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:i,device:l,surface:p,appBundleId:f,appName:c,saveScript:!!n.flags?.saveScript});void 0!==n.runtime&&(t=o,r=i,(a=m)&&(0===ul(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let b=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:n,startup:i,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:n};return r&&(d.appName=r),a&&(d.appBundleId=a),i&&(d.startup=i),s&&l(s)>0&&(d.runtime=s),o&&(d.platform=o.platform,d.target=o.target??"mobile",d.device=o.name,d.id=o.id,d.kind=o.kind,"android"===o.platform&&(d.serial=o.id)),o?.platform==="ios"&&(d.device_udid=o.id,d.ios_simulator_device_set=o.simulatorSetPath??null),{...d,...ep(`Opened: ${r??a??t}`)}}({sessionName:i,appName:c,appBundleId:f,surface:p,startup:v,device:l,runtime:m,runtimeHintCount:ul});return o.recordAction(I,{command:"open",positionals:u,flags:n.flags??{},runtime:void 0!==n.runtime?m:void 0,result:b}),o.set(i,I),{ok:!0,data:b}}async function uU(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e;if(n.has(r)){let e=n.get(r);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:`Session "${r}" not found.`}};let i=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(i?e.appName:void 0),l=uO(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return i?uE("open --relaunch requires an app name or an active session app."):uE("Session already active. Close it first or pass a new --session name.");let d=uL({shouldRelaunch:i,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await dq(e.device),c=await uC({req:t,sessionName:r,sessionStore:n,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await uF({req:t,sessionName:r,sessionStore:n,logPath:a,device:u,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let i=t.flags?.relaunch===!0,o=t.positionals?.[0];if(i&&!o)return uE("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&aQ(r)?uE("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===nf(r)?uE(nm(r)):null:null}({shouldRelaunch:i,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await l9(t.flags??{}),d=uO(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=uL({shouldRelaunch:i,openTarget:o,surface:d,device:l});return u||await tS(uR,l.id,async()=>{let e=n.toArray().find(e=>e.device.id===l.id);if(e)return{ok:!1,error:{code:"DEVICE_IN_USE",message:`Device is already in use by session "${e.name}".`,details:{session:e.name,deviceId:l.id,deviceName:l.name}}};let i=await uC({req:t,sessionName:r,sessionStore:n,device:l,surface:d,openTarget:o});return"response"===i.type?i.response:await uF({req:t,sessionName:r,sessionStore:n,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:i.details.appBundleId,appName:i.details.appName,runtime:i.details.runtime,surface:d})})}async function uG(e){let t=await F("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function uV(e){let{device:t,shutdownRequested:r}=e;if(r&&(dV(t)||"android"===t.platform&&"emulator"===t.kind))try{return dV(t)?await ox(t):await uG(t)}catch(t){let e=E(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function uB(e){if(await ro(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await oX("dismiss",t).catch(t=>{U({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function uj(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,i=n.get(r);if(!i)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session"}};i.appLog&&await ad(i.appLog),t.positionals&&t.positionals.length>0&&(("ios"===i.device.platform||"macos"===i.device.platform)&&await uB(i),await l7(i.device,"close",t.positionals,t.flags?.out,{...db(a,t.flags,i.appBundleId,i.trace?.outPath)}),await dB(i.device,d$)),("ios"===i.device.platform||"macos"===i.device.platform)&&await uB(i),dQ(n.getRuntimeHints(r))&&i.appBundleId&&await d2({device:i.device,appId:i.appBundleId}).catch(()=>{}),n.recordAction(i,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...ep(`Closed: ${r}`)}}),t.flags?.saveScript&&(i.recordSession=!0),n.writeSessionLog(i),await dO(r).catch(()=>{}),n.delete(r);let o=await uV({device:i.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:ee({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...ep(`Closed: ${r}`)}}}function uq(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}let uH={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await Promise.resolve(eO);return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await Promise.resolve(eM);return await a(e,t,r)}},uW={ios:async(e,t,r)=>{let{installIosApp:a}=await Promise.resolve(eO),n=await a(e,r,{appIdentifierHint:t});return{bundleId:n.bundleId,appName:n.appName,launchTarget:n.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await Promise.resolve(eM),n=await a(e,r);return{package:n.packageName,appName:n.appName,launchTarget:n.launchTarget}}};async function uz(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:i}=e,o=n.get(a),l=t.flags??{},d=dU(r,o,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return uq("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let p=t.meta?.uploadedArtifactId;try{var f;let e,a=p?ah(p,t.meta?.tenantId):rC.expandHome(c);if(!s.existsSync(a))return uq("INVALID_ARGS",`App binary not found: ${a}`);let d=await dj({session:o,flags:l,ensureReady:!1});if(!dI(r,d))return uq("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await i.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await i.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=ee(e,(f=e,`Installed: ${f.appName??K(f)}`));return o&&n.recordAction(o,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&aw(p)}}let uJ=["platform","target","device","udid","serial","verbose","out"];async function uK(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return{ok:!1,error:{code:"INVALID_ARGS",message:`Unsupported batch on-error mode: ${a}.`}};let n=e.flags?.batchMaxSteps??ew;if(!Number.isInteger(n)||n<1||n>1e3)return{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`}};try{let a=W(e.flags?.batchSteps,n),i=Date.now(),o=[];for(let n=0;n<a.length;n+=1){let i=a[n],s=await uX(e,t,i,r,n+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${i.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:i.command,positionals:i.positionals,executed:n,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-i,results:o}}}catch(t){let e=k(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}async function uX(e,t,r,a,n){let i=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:n,...i}=t??{},o=e??{};for(let e of uJ)void 0===i[e]&&void 0!==o[e]&&(i[e]=o[e]);return i}(e.flags,r.flags);void 0===o.session&&(o.session=t);let s=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:o,runtime:r.runtime,meta:e.meta}),l=Date.now()-i;return s.ok?{ok:!0,step:n,result:{step:n,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:n,error:s.error}}async function uY(e){let t,r,a,{deviceName:n,runtime:i,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new O("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await uZ({deviceName:n,runtime:i,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await uQ({deviceName:n,runtime:i,simctlOpts:u})).udid,r=await u0(t,u),a=!0)}else t=(await uQ({deviceName:n,runtime:i,simctlOpts:u})).udid,r=await u0(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:n,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:n,runtime:r,created:a,booted:c}}async function uZ(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,n=await F("xcrun",te(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:od});if(0!==n.exitCode)return null;try{let e=JSON.parse(String(n.stdout??""));for(let[a,n]of Object.entries(e.devices??{}))if(!r||u1(a).includes(u1(r))){for(let e of n)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function uQ(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,n=r?["create",t,t,r]:["create",t,t],i=await F("xcrun",te(n,a),{allowFailure:!0});if(0!==i.exitCode)throw new O("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(i.stdout??"").trim();if(!o)throw new O("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(i.stdout??""),stderr:String(i.stderr??"")});return{udid:o}}async function u0(e,t){let r=await F("xcrun",te(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:od});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,a]of Object.entries(t.devices??{}))if(a.some(t=>t.udid===e))return r;return""}catch{return""}}function u1(e){return e.toLowerCase().replace(/[._-]/g,"")}async function u2(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,n=e6(e.iosSimulatorDeviceSet);if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"ensure-simulator requires --device <name>"}};let i=await uY({deviceName:r,runtime:a,simulatorSetPath:n,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:dS});return{ok:!0,data:{udid:i.udid,device:i.device,runtime:i.runtime,ios_simulator_device_set:n??null,created:i.created,booted:i.booted}}}catch(t){let e=k(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("devices"===t.command)try{let e=[],r=e7(t.flags?.androidDeviceAllowlist),a=t.flags?.platform,n=tx({simulatorSetPath:e6(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await Promise.resolve(eD);e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await Promise.resolve(eE);e.push(...await t({simulatorSetPath:n}))}else{if("apple"!==a){let{listAndroidDevices:t}=await Promise.resolve(eD);try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await Promise.resolve(eE);try{e.push(...await t({simulatorSetPath:n}))}catch{}}let i="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?i.filter(e=>(e.target??"mobile")===t.flags?.target):i).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=k(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("apps"===t.command){let e=a.get(r),n=t.flags??{},i=dU(t.command,e,n);if(i)return i;let o=await dj({session:e,flags:n,ensureReady:!0});if(!dI("apps",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"apps is not supported on this device"}};let s=t.flags?.appsFilter??"all";if(tN(o.platform)){let{listIosApps:e}=await Promise.resolve(eO);return{ok:!0,data:{apps:(await e(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await Promise.resolve(eM);return{ok:!0,data:{apps:(await l(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function u3(e){let{ensureAndroidEmulatorBooted:t}=await Promise.resolve(eD);return await t(e)}let u4='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',u5='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function u8(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r),i=t.flags??{},o=i.platform;if(!n&&"string"==typeof i?.session&&i.session.trim().length>0)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"ios"===o?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`}};let s=dU("appstate",n,i);if(s)return s;let l=(n?.device.platform==="ios"||n?.device.platform==="macos")&&function(e,t){if(!t)return!1;if(!dG(e))return!0;let r=e?.platform;return!(r&&!t_(t.device.platform,r)||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(i,n);if("ios"===o&&!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u4}};if("macos"===o&&!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u5}};if(l&&n){let e=n.appName??n.appBundleId;if(!n.appName&&!n.appBundleId){if("macos"===n.device.platform&&n.surface&&"app"!==n.surface&&"frontmost-app"!==n.surface)return{ok:!0,data:{platform:n.device.platform,appName:n.surface,appBundleId:n.appBundleId,source:"session",surface:n.surface}};let e="macos"===n.device.platform?"macOS":"iOS";return{ok:!1,error:{code:"COMMAND_FAILED",message:`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`}}}return{ok:!0,data:{platform:n.device.platform,appName:e??"unknown",appBundleId:n.appBundleId,source:"session",surface:n.surface??"app",..."ios"===n.device.platform?{device_udid:n.device.id,ios_simulator_device_set:n.device.simulatorSetPath??null}:{}}}}let d=await dj({session:n,flags:i,ensureReady:!0});if("ios"===d.platform)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u4}};if("macos"===d.platform)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:u5}};let{getAndroidAppState:u}=await Promise.resolve(eM),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function u6(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,n=a.get(r),i=t.flags??{},o=dU(t.command,n,i);if(o)return o;let s="android"===(i.platform??n?.device.platform),l=!0===i.headless;if(l&&!s)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};let d=dH({flags:i,sessionDevice:n?.device}),u=s&&!!d,c=!1;try{e=await dj({session:n,flags:i,ensureReady:!1})}catch(r){let t=k(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await u3({avdName:d,serial:i.serial,headless:l}),c=!0}if(i.target&&(e.target??"mobile")!==i.target)return{ok:!1,error:{code:"DEVICE_NOT_FOUND",message:`No ${e.platform} device found matching --target ${i.target}.`}};if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};if(!c){let t=dH({flags:i,sessionDevice:n?.device,resolvedDevice:e});if(!t)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};e=await u3({avdName:t,serial:i.serial,headless:!0})}await dS(e)}else("android"!==e.platform||!0!==e.booted)&&await dS(e);return dI("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"boot is not supported on this device"}}}return"appstate"===t.command?await u8({req:t,sessionName:r,sessionStore:a}):null}let u9="adb-shell-dumpsys-cpuinfo",u7="adb-shell-dumpsys-meminfo";async function ce(e,t){try{let r=await F("adb",aK(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){var a,n,i;let o=new Set,s=0;for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let i=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!i)continue;let l=Number(i[1]),d=i[2];Number.isFinite(l)&&(a=d,n=t,a===n||a.startsWith(`${n}:`))&&(s+=l,o.add(d))}return{usagePercent:(i=s,Math.round(10*i)/10),measuredAt:r,method:u9,matchedProcesses:[...o]}}(r.stdout,t,new Date().toISOString())}catch(e){throw cr("cpu",t,e)}}async function ct(e,t){try{let r=await F("adb",aK(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new O("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let a=ca(e,"TOTAL PSS")??function(e){for(let t of e.split("\n")){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let r=e.split(/\s+/).slice(1).find(e=>null!==cn(e));if(!r)break;return cn(r)??void 0}}(e);if(void 0===a)throw new O("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:a,totalRssKb:ca(e,"TOTAL RSS"),measuredAt:r,method:u7}}(r.stdout,t,new Date().toISOString())}catch(e){throw cr("memory",t,e)}}function cr(e,t,r){return r instanceof O&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new O(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof O?r:new O("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function ca(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return cn(a[1])??void 0}function cn(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let ci="ps-process-snapshot",co="ps-process-snapshot",cs="xctrace-activity-monitor",cl="xctrace-activity-monitor";async function cd(e,t){if("ios"===e.platform&&"device"===e.kind)return await cp(e,t);let r=await cc(e,t),a=await cy(e,r);if(0===a.length)throw new O("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let n=new Date().toISOString(),i=rw(a.map(e=>p.basename(cv(e.command))));return cI({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:n,matchedProcesses:i,cpuMethod:ci,memoryMethod:co})}async function cu(e){let t=tO(e),r=cb(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new O("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}),n=a.indexOf("pid"),i=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(n<0||i<0||o<0||s<0)throw new O("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let n of t)r(n)&&a.push(n),a.push(...e(n.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,p;let t=e.children;if(0===t.length)continue;for(let e of t){let t=cb(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);u.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&u.set(e.attributes.id,{numberValue:cA(e),processName:cN(e)})}let r=cS(t[n],u),a=(c=t[i],p=u,c?c.attributes.ref?p.get(c.attributes.ref)?.processName??null:cN(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:cS(t[o],u),residentMemoryBytes:cS(t[s],u)})}return d}async function cc(e,t){let r="macos"===e.platform?await cw(t):await cg(e,t),a="macos"===e.platform?p.join(r,"Contents","Info.plist"):p.join(r,"Info.plist"),n=await oM(a,"CFBundleExecutable");if(!n)throw new O("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:n,executablePath:"macos"===e.platform?p.join(r,"Contents","MacOS",n):void 0}}async function cp(e,t){let r=await cf(e,t),a=await cm(e,t),n=await cm(e,t),i=ch(await cu(a.xml),r,t,e),o=ch(await cu(n.xml),r,t,e),s=n.capturedAtMs-a.capturedAtMs;if(s<=0)throw new O("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===i.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new O("COMMAND_FAILED",`Incomplete Activity Monitor sample for ${t}`,{appBundleId:t,deviceId:e.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});return cI({usagePercent:Math.max(0,o.cpuTimeNs-i.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(n.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:cs,memoryMethod:cl})}async function cf(e,t){let r=(await og(e,"all")).find(e=>e.bundleId===t);if(!r)throw new O("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new O("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),n=w(a),i=(await oy(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===i.length)throw new O("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:n,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return i}async function cm(e,t){let r=await d.mkdtemp(p.join(u.tmpdir(),"agent-device-ios-perf-")),a=p.join(r,"sample.trace"),n=p.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",a,"--quiet","--no-prompt"],i=await F("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),o=Date.now();if(0!==i.exitCode)throw new O("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:i.exitCode,stdout:i.stdout,stderr:i.stderr,appBundleId:t,deviceId:e.id,hint:c_(i.stdout,i.stderr)});let s=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",n],l=await F("xcrun",s,{allowFailure:!0,timeoutMs:15e3});if(0!==l.exitCode)throw new O("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:s,exitCode:l.exitCode,stdout:l.stdout,stderr:l.stderr,appBundleId:t,deviceId:e.id,hint:c_(l.stdout,l.stderr)});return{capturedAtMs:o,xml:await d.readFile(n,"utf8")}}finally{await d.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function ch(e,t,r,a){let n=new Set(t.map(e=>e.pid)),i=new Set(t.map(e=>p.basename(w(e.executable)))),o=e.filter(e=>n.has(e.pid)||i.has(e.processName));if(0===o.length)throw new O("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:a.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let s=new Map;for(let e of o){let t=s.get(e.pid);if(!t){s.set(e.pid,e);continue}s.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:cx(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:cx(t.residentMemoryBytes,e.residentMemoryBytes)})}let l=[...s.values()],d=l.map(e=>e.cpuTimeNs).filter(e=>null!==e),u=l.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:d.length>0?d.reduce((e,t)=>e+t,0):null,residentMemoryBytes:u.length>0?u.reduce((e,t)=>e+t,0):null,matchedProcesses:rw(l.map(e=>e.processName))}}async function cw(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await F("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new O("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!a)throw new O("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function cg(e,t){let r=tt(e,["get_app_container",e.id,t,"app"]),a=await F("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new O("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let n=a.stdout.trim();if(0===n.length)throw new O("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return n}async function cy(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:tt(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let a=e.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!a)continue;let n=Number(a[1]),i=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(o)&&t.push({pid:n,cpuPercent:i,rssKb:o,command:s})}return t})((await F("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let n;return r=e.command,a=t,n=cv(r),!!(a.executablePath&&(n===a.executablePath||r.startsWith(`${a.executablePath} `)))||p.basename(n)===a.executableName})}function cv(e){let[t=""]=e.trim().split(/\s+/,1);return t}function cI(e){return{cpu:{usagePercent:Math.round(10*e.usagePercent)/10,measuredAt:e.measuredAt,method:e.cpuMethod,matchedProcesses:e.matchedProcesses},memory:{residentMemoryKb:Math.round(e.residentMemoryKb),measuredAt:e.measuredAt,method:e.memoryMethod,matchedProcesses:e.matchedProcesses}}}function cb(e,t){for(let r of e){if(t(r))return r;let e=cb(r.children,t);if(e)return e}}function cA(e){if(!e||e.children.some(e=>"sentinel"===e.name)||!e.text)return null;let t=Number(e.text);return Number.isFinite(t)?t:null}function cS(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:cA(e):null}function cN(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function c_(e,t){let r=oI(e,t);if(r)return r;let a=`${e}
41
+ ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?ov:a.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function cx(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function cD(e){var t;let r=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===uh&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:uh,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}(e.actions),a=r.at(-1),n=a?{available:!0,lastDurationMs:a.durationMs,lastMeasuredAt:a.measuredAt,method:uh,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:uh},i={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:n,fps:{available:!1,reason:uw},memory:{available:!1,reason:uw},cpu:{available:!1,reason:uw}},sampling:{startup:{method:uh,description:"Elapsed wall-clock time around dispatching the open command for the active session app target.",unit:"ms"},...function(e){if("android"===e.device.platform)return{memory:{method:u7,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:u9,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"}};var t=e.device;if("ios"===t.platform&&"device"===t.kind)return{memory:{method:cl,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:cs,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let r="macos"===t.platform?"host ps for the running macOS app executable resolved from the bundle ID.":"xcrun simctl spawn ps for the running iOS simulator app executable resolved from the bundle ID.";return{memory:{method:co,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:ci,description:`Recent CPU usage snapshot from ${r}`,unit:"percent"}}}(e)}};if("android"!==(t=e).device.platform&&"ios"!==t.device.platform&&"macos"!==t.device.platform)return i;if(!e.appBundleId){let t="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.";return i.metrics.memory={available:!1,reason:t},i.metrics.cpu={available:!1,reason:t},i}let[o,s]=await cM(e);return i.metrics.memory=ck(o),i.metrics.cpu=ck(s),i}async function cM(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([ct(e.device,t),ce(e.device,t)]);return[r,a]}try{let r=await cd(e.device,t);return[{status:"fulfilled",value:r.memory},{status:"fulfilled",value:r.cpu}]}catch(e){return[{status:"rejected",reason:e},{status:"rejected",reason:e}]}}function ck(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=E(e.reason);return{available:!1,reason:t.message,error:t}}let cE=["path","start","stop","doctor","mark","clear"],cO=`logs requires ${cE.slice(0,-1).join(", ")}, or ${cE.at(-1)}`,cL=["dump","log"],cC=`network requires ${cL.join(" or ")}`,cP=["summary","headers","body","all"],cR=`network include mode must be one of: ${cP.join(", ")}`;async function cT(e){let{req:t}=e;return"perf"===t.command?c$(e):"logs"===t.command?cF(e):"network"===t.command?cj(e):null}async function c$(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"perf requires an active session. Run open first."}};try{return{ok:!0,data:await cD(a)}}catch(e){return{ok:!1,error:E(e)}}}async function cF(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"logs requires an active session"}};if(!dI("logs",n.device))return{ok:!1,error:E(new O("UNSUPPORTED_OPERATION","logs is not supported on this device"))};let i=(t.positionals?.[0]??"path").toLowerCase(),o=!!t.flags?.restart;return cE.includes(i)?o&&"clear"!==i?{ok:!1,error:{code:"INVALID_ARGS",message:"logs --restart is only supported with logs clear"}}:"path"===i?function(e,t,r){let a=r.resolveAppLogPath(t),n=function(e){if(!s.existsSync(e))return{exists:!1,sizeBytes:0};let t=s.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(a);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:n.sizeBytes,modifiedAt:n.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(n,r,a):"doctor"===i?cU(n,r,a):"mark"===i?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",i=r.resolveAppLogPath(t);return an(i),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
42
+ `,s.appendFileSync(i,a,"utf8"),{ok:!0,data:{path:i,marked:!0}}}(t,r,a):"clear"===i?cG(n,r,a,o):"start"===i?cV(n,r,a):"stop"===i?cB(n,r,a):{ok:!1,error:{code:"INVALID_ARGS",message:cO}}:{ok:!1,error:{code:"INVALID_ARGS",message:cO}}}async function cU(e,t,r){let a=r.resolveAppLogPath(t),n=await au(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:n.checks,notes:n.notes}}}async function cG(e,t,r,a){if(e.appLog&&!a)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear requires logs to be stopped first; run logs stop"}};if(a&&!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear --restart requires an app session; run open <app> first"}};let n=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:ac(n)};e.appLog&&await ad(e.appLog);let i=ac(n),o=r.resolveAppLogPidPath(t);try{let a=await as(e.device,e.appBundleId,n,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:n,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...i,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:E(a)}}}async function cV(e,t,r){if(e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"app log already streaming; run logs stop first"}};if(!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs start requires an app session; run open <app> first"}};let a=r.resolveAppLogPath(t),n=r.resolveAppLogPidPath(t);try{let i=await as(e.device,e.appBundleId,a,n);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:a,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:E(e)}}}async function cB(e,t,r){if(!e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"no app log stream active"}};let a=e.appLog.outPath;return await ad(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function cj(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"network requires an active session"}};if(!dI("network",n.device))return{ok:!1,error:E(new O("UNSUPPORTED_OPERATION","network is not supported on this device"))};let i=(t.positionals?.[0]??"dump").toLowerCase();if(!cL.includes(i))return{ok:!1,error:{code:"INVALID_ARGS",message:cC}};let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return{ok:!1,error:{code:"INVALID_ARGS",message:"network dump limit must be an integer in range 1..200"}};let s=function(e){let t=e.positionals?.[2]?.toLowerCase(),r=e.flags?.networkInclude;if(t&&r&&t!==r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"network include mode was provided both positionally and via --include with different values"}}};let a=(r??t??"summary").toLowerCase();return cP.includes(a)?{ok:!0,include:a}:{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:cR}}}}(t);if(!s.ok)return s.response;let{include:l}=s,d=await ai({device:n.device,appBundleId:n.appBundleId,appLogState:n.appLog?.getState(),appLogStartedAt:n.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!n.appLog,state:n.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let cq=new Set(["ios","android","macos","linux"]);function cH(e,t,r){let a=e[t];if(void 0!==a)throw new O("INVALID_ARGS",a===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(a)} vs ${String(r)}.`);e[t]=r}function cW(e){return!!e&&!Number.isNaN(Number(e))}let cz=/[*?[\]{}]/;async function cJ(e){let t,{filePath:r,sessionName:a,requestId:n,timeoutMs:i,platform:o,runReplay:s,cleanupSession:l}=e;ez(n);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:n,artifactPaths:d}).catch(e=>{let t=k(e);return{ok:!1,error:{code:t.code,message:t.message}}}).finally(()=>{eK(n)});try{return"number"==typeof i?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eJ(n),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(i,[...d]))},i)})]):await c}finally{t&&clearTimeout(t),u&&(await cK(c)||U({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:n,graceMs:2e3}}));try{await l(a)}catch(e){U({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:k(e).message}})}}}async function cK(e){return await Promise.race([e.then(()=>!0),N(2e3).then(()=>!1)])}async function cX(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return{ok:!1,error:{code:"INVALID_ARGS",message:"test requires at least one path or glob"}};try{var i,o,l,d,u,c;let e,f,m,h,w,g=function(e){let{inputs:t,cwd:r,platformFilter:a}=e,n=r??process.cwd(),i=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=rC.expandHome(e,t);if(s.existsSync(n)){let t=s.statSync(n);if(t.isDirectory())return s.globSync("**/*.ad",{cwd:n}).map(e=>p.join(n,e));if(t.isFile()){if(".ad"!==p.extname(n))throw new O("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!cz.test(r)&&(a=n,!cz.test(a)))throw new O("INVALID_ARGS",`test input not found: ${e}`);let i=p.isAbsolute(n)?n:e;return s.globSync(i,{cwd:p.isAbsolute(n)?void 0:t}).map(e=>p.isAbsolute(e)?e:p.resolve(t,e)).filter(e=>".ad"===p.extname(e)&&function(e){try{return s.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>p.normalize(e)).sort((e,t)=>e.localeCompare(t)),o=[];for(let e of i){var l,d;let t=function(e){let t=e.split(/\r?\n/),r={};for(let e of t){let t=e.trim();if(0===t.length||t.startsWith("#"))continue;if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&cq.has(e)&&cH(r,"platform",e)}let n=t.match(/(?:^|\s)timeout=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=1&&cH(r,"timeoutMs",Math.floor(e))}let i=t.match(/(?:^|\s)retries=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=0&&cH(r,"retries",Math.floor(e))}}return r}(s.readFileSync(e,"utf8"));if(!a){o.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){o.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${a}`});continue}l=a,d=t.platform,("apple"===l?"apple"===d||"ios"===d||"macos"===d:d===l)&&o.push({kind:"run",path:e,metadata:t})}if(0===o.filter(e=>"run"===e.kind).length){let e=a?` for --platform ${a}`:"";throw new O("INVALID_ARGS",`No .ad tests matched${e}.`)}return o}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(i=t.meta?.requestId,(i?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,n=rC.expandHome(t??".agent-device/test-artifacts",r);return p.join(n,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),I=[],b=Date.now(),A=0;for(let e of g){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await cY({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(o=t.flags?.timeoutMs,l=e.metadata.timeoutMs,"number"==typeof o?o:l),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(I.push(i),t.flags?.failFast===!0)break}let S=(d=g.length,u=I,c=Date.now()-b,e=u.filter(e=>"passed"===e.status).length,m=(f=u.filter(e=>"failed"===e.status)).length,h=u.filter(e=>"skipped"===e.status).length,w=e+m,{total:d,executed:w,passed:e,failed:m,skipped:h,notRun:Math.max(0,d-w-h),durationMs:c,failures:f,tests:u});return{ok:!0,data:S}}catch(t){let e=k(t);return{ok:!1,error:{code:e.code,message:e.message}}}}async function cY(e){var t,r;let a,n,{entry:i,sessionName:o,suiteInvocationId:l,caseIndex:d,cwd:u,requestId:c,retries:f,timeoutMs:m,suiteArtifactsDir:h,runReplay:w,cleanupSession:g}=e,y=Date.now(),v=p.join(h,(t=i.path,(0===(n=u?p.relative(u,t):p.basename(t)).length||n.startsWith("..")?p.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",b=0;for(let e=0;e<=f;e+=1){b=e+1;let t=function(e,t,r,a,n=0){let i=p.basename(r,p.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${i?`-${i}`:""}:attempt-${n+1}`}(o,l,i.path,d,e),n=p.join(v,`attempt-${b}`);r=i.path,s.mkdirSync(n,{recursive:!0}),s.copyFileSync(r,p.join(n,"replay.ad"));let u=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:n,attemptIndex:i}=e;return eW(`${t??r}:test:${n+1}:${p.basename(a)}:attempt:${i+1}`,r)}({requestId:c,suiteInvocationId:l,filePath:i.path,caseIndex:d,attemptIndex:e}),h=await cJ({filePath:i.path,sessionName:t,requestId:u,timeoutMs:m,platform:i.metadata.platform,runReplay:w,cleanupSession:g});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:i,attemptArtifactsDir:o}=e,l=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(t)];t.ok||"string"!=typeof t.error.logPath||l.push(t.error.logPath);let d=function(e,t){let r=[],a=new Map;for(let n of e){if(!function(e){try{return s.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=p.extname(e),a=r?e.slice(0,-r.length):e,n=t.get(e)??0;return(t.set(e,n+1),0===n)?e:`${a}-${n+1}${r}`}(p.basename(n),a),i=p.join(t,e);p.resolve(n)!==p.resolve(i)&&s.copyFileSync(n,i),r.push(i)}return r}(l,o),u=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${i}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;u.push(`replayed: ${e}`,`healed: ${r}`)}else u.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&u.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&u.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&u.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&u.push("timeoutMode: cooperative");d.length>0&&u.push(`copiedArtifacts: ${d.map(e=>p.basename(e)).join(", ")}`);let c=p.join(o,"result.txt"),f=`${u.join("\n")}
43
+ `;s.writeFileSync(c,f),t.ok||s.writeFileSync(p.join(o,"failure.txt"),f)}({response:h,filePath:i.path,sessionName:t,attempts:b,maxAttempts:f+1,attemptArtifactsDir:n}),a=h,I=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:i.path,session:I,status:"passed",durationMs:A,attempts:b,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let S=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:i.path,session:I,status:"failed",durationMs:A,attempts:b,artifactsDir:v,error:S}}function cZ(e,t){let r=t.toLowerCase();return e.find(e=>{let t=(e.label??"").toLowerCase(),a=(e.value??"").toLowerCase(),n=(e.identifier??"").toLowerCase();return t.includes(r)||a.includes(r)||n.includes(r)})??null}function cQ(e,t){let r=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);return r&&c0(r)?r:function(e,t){if(!e.rect)return;let r=e.rect.y+e.rect.height/2,a=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);if(!t||!c0(t))continue;let n=Math.abs(e.rect.y+e.rect.height/2-r);(!a||n<a.distance)&&(a={label:t,distance:n})}return a?.label}(e,t)??(r&&c0(r)?r:void 0)}function c0(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function c1(e){let t=[],r=[];for(let a of e){let e=a.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let n=c2(a.type??""),i=[a.label,a.value,a.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0),o=!!i&&c0(i);if(("group"===n||"ioscontentgroup"===n)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);r.push({...a,depth:s})}return r}function c2(e){let t=e.trim().replace(/XCUIElementType/gi,"");t.startsWith("AX")&&(t=t.slice(2));let r=Math.max((t=t.toLowerCase()).lastIndexOf("."),t.lastIndexOf("/"));return -1!==r&&(t=t.slice(r+1)),t}function c3(e,t){let r=c2(e);return!r||("android"===t?r.includes("edittext")||r.includes("autocompletetextview"):r.includes("textfield")||r.includes("securetextfield")||r.includes("searchfield")||r.includes("textview")||r.includes("textarea")||"search"===r)}function c4(e,t){if(t.hittable)return t;let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(t.hittable)return t;r=t}return null}function c5(e){return[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").filter(e=>e.length>0)[0]??""}let c8=new Set(["id","role","text","label","value","appname","windowtitle"]),c6=new Set(["visible","hidden","editable","selected","enabled","hittable"]),c9=new Set([...c8,...c6]);function c7(e){let t=e.trim();if(!t)throw new O("INVALID_ARGS","Selector expression cannot be empty");let r=function(e){let t=[],r="",a=null;for(let n=0;n<e.length;n+=1){let i=e[n];if(('"'===i||"'"===i)&&!po(e,n)){a=pn(a,i),r+=i;continue}if(!a&&"|"===i&&"|"===e[n+1]){let a=r.trim();if(!a)throw new O("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);t.push(a),r="",n+=1;continue}r+=i}let n=r.trim();if(!n)throw new O("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);return t.push(n),t}(t);if(0===r.length)throw new O("INVALID_ARGS","Selector expression cannot be empty");return{raw:t,selectors:r.map(e=>(function(e){let t=e.trim();if(!t)throw new O("INVALID_ARGS","Selector segment cannot be empty");let r=function(e){let t=[],r="",a=null;for(let n=0;n<e.length;n+=1){let i=e[n];if(('"'===i||"'"===i)&&!po(e,n)){a=pn(a,i),r+=i;continue}if(!a&&/\s/.test(i)){r.trim()&&t.push(r.trim()),r="";continue}r+=i}if(a)throw new O("INVALID_ARGS",`Unclosed quote in selector: ${e}`);return r.trim()&&t.push(r.trim()),t}(t);if(0===r.length)throw new O("INVALID_ARGS",`Invalid selector segment: ${e}`);return{raw:t,terms:r.map(pa)}})(e))}}function pe(e){try{return c7(e)}catch{return null}}function pt(e,t={}){if(0===e.length)return null;let r=t.preferTrailingValue??!1,a=0,n=[];for(;a<e.length&&function(e){let t=e.trim();if(!t)return!1;if("||"===t)return!0;let r=t.indexOf("=");if(-1!==r){let e=t.slice(0,r).trim().toLowerCase();return c9.has(e)}return c9.has(t.toLowerCase())}(e[a]);){a+=1;let t=e.slice(0,a).join(" ").trim();t&&pe(t)&&n.push(a)}if(0===n.length)return null;let i=n[n.length-1];if(r){for(let t=n.length-1;t>=0;t-=1)if(n[t]<e.length){i=n[t];break}}let o=e.slice(0,i).join(" ").trim();return o?{selectorExpression:o,rest:e.slice(i)}:null}function pr(e){let t=e[0]??"",r=pt(e.slice(1),{preferTrailingValue:"text"===t});return{predicate:t,split:r}}function pa(e){let t=e.trim();if(!t)throw new O("INVALID_ARGS","Empty selector term");let r=t.indexOf("=");if(-1===r){let r=t.toLowerCase();if(!c6.has(r))throw new O("INVALID_ARGS",`Invalid selector term "${e}", expected key=value`);return{key:r,value:!0}}let a=t.slice(0,r).trim().toLowerCase(),n=t.slice(r+1).trim();if(!c9.has(a))throw new O("INVALID_ARGS",`Unknown selector key: ${a}`);if(!n)throw new O("INVALID_ARGS",`Missing selector value for key: ${a}`);if(c6.has(a)){let e,t="true"===(e=pi(n).toLowerCase())||"false"!==e&&null;if(null===t)throw new O("INVALID_ARGS",`Invalid boolean value for ${a}: ${n}`);return{key:a,value:t}}return{key:a,value:pi(n)}}function pn(e,t){return e?e===t?null:e:t}function pi(e){let t=e.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\(["'])/g,"$1"):t}function po(e,t){let r=0;for(let a=t-1;a>=0&&"\\"===e[a];a-=1)r+=1;return r%2==1}function ps(e,t,r){return t.terms.every(t=>(function(e,t,r){switch(t.key){case"id":return pu(e.identifier,String(t.value));case"role":return pu(c2(e.type??""),String(t.value));case"label":return pu(e.label,String(t.value));case"value":return pu(e.value,String(t.value));case"text":return pu(c5(e),String(t.value));case"appname":return pu(e.appName,String(t.value));case"windowtitle":return pu(e.windowTitle,String(t.value));case"visible":return pl(e)===!!t.value;case"hidden":return!pl(e)==!!t.value;case"editable":return pd(e,r)===!!t.value;case"selected":return!0===e.selected==!!t.value;case"enabled":return!1!==e.enabled==!!t.value;case"hittable":return!0===e.hittable==!!t.value;default:return!1}})(e,t,r))}function pl(e){return!0===e.hittable||!!e.rect&&e.rect.width>0&&e.rect.height>0}function pd(e,t){return c3(e.type??"",t)&&!1!==e.enabled}function pu(e,t){return pc(e??"")===pc(t)}function pc(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function pp(e,t,r){let a=r.requireRect??!1,n=r.requireUnique??!0,i=[];for(let o=0;o<t.selectors.length;o+=1){let s=t.selectors[o],l=function(e,t,r,a){let n=0,i=null,o=null,s=!1;for(let l of e){if(a&&!l.rect||!ps(l,t,r))continue;if(n+=1,i??=l,!o){o=l;continue}let e=function(e,t){let r=e.depth??0,a=t.depth??0;if(r!==a)return r>a?1:-1;let n=ph(e),i=ph(t);return n!==i?n<i?1:-1:0}(l,o);e>0?(o=l,s=!1):0===e&&(s=!0)}return{count:n,firstNode:i,disambiguated:s?null:o}}(e,s,r.platform,a);if(i.push({selector:s.raw,matches:l.count}),0!==l.count&&l.firstNode){if(n&&1!==l.count){if(!r.disambiguateAmbiguous||!l.disambiguated)continue;return{node:l.disambiguated,selector:s,selectorIndex:o,matches:l.count,diagnostics:i}}return{node:l.firstNode,selector:s,selectorIndex:o,matches:l.count,diagnostics:i}}}return null}function pf(e,t,r){let a=r.requireRect??!1,n=[];for(let i=0;i<t.selectors.length;i+=1){let o=t.selectors[i],s=function(e,t,r,a){let n=0;for(let i of e)(!a||i.rect)&&ps(i,t,r)&&(n+=1);return n}(e,o,r.platform,a);if(n.push({selector:o.raw,matches:s}),s>0)return{selectorIndex:i,selector:o,matches:s,diagnostics:n}}return null}function pm(e,t,r){if(0===t.length)return`Selector did not match: ${e.raw}`;let a=t.map(e=>`${e.selector} -> ${e.matches}`).join(", ");return r.unique??!0?`Selector did not resolve uniquely (${a})`:`Selector did not match (${a})`}function ph(e){return e.rect?e.rect.width*e.rect.height:1/0}function pw(e,t,r={}){let a=[],n=c2(e.type??""),i=py(e.identifier),o=py(e.label),s=py(e.value),l=py(c5(e)),d="fill"===r.action;i&&a.push(`id=${pg(i)}`),n&&o&&a.push(d?`role=${pg(n)} label=${pg(o)} editable=true`:`role=${pg(n)} label=${pg(o)}`),o&&a.push(d?`label=${pg(o)} editable=true`:`label=${pg(o)}`),s&&a.push(d?`value=${pg(s)} editable=true`:`value=${pg(s)}`),l&&l!==o&&l!==s&&a.push(d?`text=${pg(l)} editable=true`:`text=${pg(l)}`),n&&d&&!a.some(e=>e.includes("editable=true"))&&a.push(`role=${pg(n)} editable=true`);let u=rw(a);return 0===u.length&&n&&u.push(d?`role=${pg(n)} editable=true`:`role=${pg(n)}`),0===u.length&&pl(e)&&u.push("visible=true"),u}function pg(e){return JSON.stringify(e)}function py(e){if(!e)return null;let t=e.trim();return t||null}function pv(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=pt(r?e.slice(0,-1):e.slice());return!a||a.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:a.selectorExpression,selectorTimeout:r?t:null}}async function pI(e){let{action:t,sessionName:r,logPath:a,sessionStore:n}=e;if(!(rb(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let i=n.get(r);if(!i)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),rb(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=pr(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=pv(e.positionals??[]);r&&t.push(r)}return rw(t).filter(e=>e.trim().length>0)})(t).map(e=>pe(e)).filter(e=>null!==e);if(0===o.length)return null;let s=rb(t.command)||"fill"===t.command,l=rb(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await pb(i,t,a,s,n);for(let e of o){let r=pp(d.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=pw(r.node,i.device.platform,{action:rb(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(rb(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=rh(t);if(!e)continue;return{...t,positionals:[a,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,a]}}if("is"===t.command){let{predicate:e,split:r}=pr(t.positionals);if(!e)continue;let n=r?.rest.join(" ").trim()??"",i=[e,a];return"text"===e&&n.length>0&&i.push(n),{...t,positionals:i}}if("wait"===t.command){let{selectorTimeout:e}=pv(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function pb(e,t,r,a,n){let i=await l7(e.device,"snapshot",[],t.flags?.out,{...db(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=i?.nodes??[],s={nodes:e_(t.flags?.snapshotRaw?o:c1(o)),truncated:i?.truncated,createdAt:Date.now(),backend:i?.backend};return e.snapshot=s,n.set(e.name,e),s}let pA=["platform","target","device","udid","serial","verbose","out"];async function pS(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e,o=t.positionals?.[0];if(!o)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay requires a path"}};let l="",d=new Set;try{l=rC.expandHome(o,t.meta?.cwd);let e=s.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay accepts .ad script files. JSON replay payloads are no longer supported."}};let c=function(e){let t=[];for(let r of e.split(/\r?\n/)){let e=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let r=function(e){let t=[],r=0;for(;r<e.length;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let a=r+1,n=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!n)break;n="\\"===t&&!n,"\\"!==t&&(n=!1),a+=1}if(a>=e.length)throw new O("INVALID_ARGS",`Invalid replay script line: ${e}`);let i=e.slice(r,a+1);t.push(JSON.parse(i)),r=a+1;continue}let a=r;for(;a<e.length&&!/\s/.test(e[a]);)a+=1;t.push(e.slice(r,a)),r=a}return t}(t);if(0===r.length)return null;let[a,...n]=r;if("context"===a)return null;let i={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){i.positionals=[];for(let e=0;e<n.length;e+=1){let t=n[e];if("-i"===t){i.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){i.flags.snapshotCompact=!0;continue}if("--raw"===t){i.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<n.length){let t=Number(n[e+1]);Number.isFinite(t)&&t>=0&&(i.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<n.length){i.flags.snapshotScope=n[e+1],e+=1;continue}if("--backend"===t&&e+1<n.length){e+=1;continue}}return i}if("open"===a){let e=function(e){var t;let r=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}r.push(t)}let n=rE(r);return{positionals:n.positionals,flags:a,runtime:(t=n.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?n.flags:void 0}}(n);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i.runtime=e.runtime,i}if("runtime"===a){let e=rE(n);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i}if(rb(a)){let e=rk(a,n);if(Object.assign(i.flags,e.flags),0===e.positionals.length)return i;let t=e.positionals[0];if(t.startsWith("@"))return i.positionals=[t],e.positionals[1]&&(i.result={refLabel:e.positionals[1]}),i;let r=e.positionals[0],o=e.positionals[1];return cW(r)&&cW(o)&&e.positionals.length>=2?i.positionals=[r,o]:i.positionals=[e.positionals.join(" ")],i}if("fill"===a){let e=rk(a,n);if(Object.assign(i.flags,e.flags),e.positionals.length<2)return i.positionals=e.positionals,i;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(i.positionals=[t,e.positionals.slice(2).join(" ")],i.result={refLabel:e.positionals[1]}):i.positionals=[t,e.positionals[1]],i):(i.positionals=[t,e.positionals.slice(1).join(" ")],i)}if("get"===a){if(n.length<2)return i.positionals=n,i;let e=n[0],t=n[1];return t.startsWith("@")?(i.positionals=[e,t],n[2]&&(i.result={refLabel:n[2]})):i.positionals=[e,n.slice(1).join(" ")],i}if("swipe"===a||"type"===a){let e=rk(a,n);return Object.assign(i.flags,e.flags),i.positionals=e.positionals,i}if("record"===a){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t];if("--hide-touches"===r){i.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<n.length){let e=Number(n[t+1]);Number.isFinite(e)&&(i.flags.fps=Math.floor(e)),t+=1;continue}e.push(r)}return i.positionals=e,i}if("screenshot"===a){let e=[];for(let t of n){if("--fullscreen"===t){i.flags.screenshotFullscreen=!0;continue}e.push(t)}return i.positionals=e,i}return i.positionals=n,i}(r);e&&t.push(e)}return t}(e),p=t.flags?.replayUpdate===!0,f=0;for(let e=0;e<c.length;e+=1){let o=c[e];if(!o||"replay"===o.command)continue;let s=await pN({req:t,sessionName:r,action:o,invoke:i});if(s.ok){px(s).forEach(e=>d.add(e));continue}if(!p)return p_(s,o,e,l,[...d]);let u=await pI({action:o,sessionName:r,logPath:a,sessionStore:n});if(!u)return p_(s,o,e,l,[...d]);if(c[e]=u,!(s=await pN({req:t,sessionName:r,action:u,invoke:i})).ok)return p_(s,u,e,l,[...d]);px(s).forEach(e=>d.add(e)),f+=1}return p&&f>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${rN(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",rS(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return rL(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(r_(r));return rD(t,e.flags),t.join(" ")}if("record"===e.command)return rM(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(rS(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}for(let r of e.positionals??[])t.push(rS(r));return rx(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
44
+ `,i=`${e}.tmp-${process.pid}-${Date.now()}`;s.writeFileSync(i,n),s.renameSync(i,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:f,session:r,artifactPaths:[...d]}}}catch(t){let e=k(t);return{ok:!1,error:{code:e.code,message:e.message,details:d.size>0?{artifactPaths:[...d]}:void 0}}}}async function pN(e){let{req:t,sessionName:r,action:a,invoke:n}=e;return await n({token:t.token,session:r,command:a.command,positionals:a.positionals??[],flags:function(e,t){let r={...t??{}},a=e??{};for(let e of pA)void 0===r[e]&&void 0!==a[e]&&(r[e]=a[e]);return r}(t.flags,a.flags),runtime:a.runtime,meta:t.meta})}function p_(e,t,r,a,n=[]){let i;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${i=(t.positionals??[]).map(e=>rS(e)),[t.command,...i].join(" ")}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:a,step:o,action:t.command,positionals:t.positionals??[],artifactPaths:n}}}}function px(e){if(!e.ok||!e.data)return[];let t=[];if("string"==typeof e.data.path&&t.push(e.data.path),"string"==typeof e.data.outPath&&t.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let r of e.data.artifacts){if(!r||"object"!=typeof r)continue;let e="string"==typeof r.localPath?r.localPath:void 0,a="string"==typeof r.path?r.path:void 0;e?t.push(e):a&&t.push(a)}return[...new Set(t.filter(e=>(function(e){try{return s.statSync(e).isFile()}catch{return!1}})(e)))]}async function pD(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e;return"replay"===t.command?await pS({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}):"test"===t.command?await cX({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await pS({req:{...t,command:"replay",session:r,positionals:[e],flags:void 0===o?t.flags:{...t.flags??{},platform:o},meta:s?{...t.meta??{},requestId:s}:t.meta},sessionName:r,logPath:a,sessionStore:n,invoke:async e=>{var t;return t=await i(e),l&&px(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{n.get(e)&&await uj({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:n})}}):null}let pM=new Set(["session_list","ensure-simulator","devices","apps"]),pk=new Set(["boot","appstate"]),pE=new Set(["perf","logs","network"]),pO=new Set(["replay","test"]);async function pL(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,command:i,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=n.get(r),u=t.flags??{},c=dU(i,d,u);if(c)return c;let p=await dj({session:d,flags:u,ensureReady:!0});if(!dI(i,p))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${i} is not supported on this device`}};let f=await l7(p,i,o,t.flags?.out,{...db(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,f,p):d;n.recordAction(e,{command:i,positionals:s??o,flags:t.flags??{},result:f??{}}),e!==d&&n.set(r,e)}return{ok:!0,data:f??{}}}async function pC(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,i=n.get(r),o=t.flags??{},s=dU("clipboard",i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return{ok:!1,error:{code:"INVALID_ARGS",message:"clipboard requires a subcommand: read or write"}};let d=await dj({session:i,flags:o,ensureReady:!0});if(!dI("clipboard",d))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"clipboard is not supported on this device"}};let u=await l7(d,"clipboard",t.positionals??[],t.flags?.out,{...db(a,t.flags,i?.appBundleId,i?.trace?.outPath)});return i&&n.recordAction(i,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function pP(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e;if(pM.has(t.command))return await u2({req:t,sessionName:r,sessionStore:n});if("runtime"===t.command)return await um({req:t,sessionName:r,sessionStore:n});if(pk.has(t.command))return await u6({req:t,sessionName:r,sessionStore:n});if("clipboard"===t.command)return await pC({req:t,sessionName:r,logPath:a,sessionStore:n});if("keyboard"===t.command){let e=n.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i||"ios"!==(t.flags??{}).platform?await pL({req:t,sessionName:r,logPath:a,sessionStore:n,command:"keyboard",positionals:t.positionals??[]}):{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first."}}}if(pE.has(t.command))return await cT({req:t,sessionName:r,sessionStore:n});if("install"===t.command||"reinstall"===t.command)return await uz({req:t,command:t.command,sessionName:r,sessionStore:n,deployOps:"install"===t.command?uW:uH});if("install_source"===t.command)return await dP({req:t,sessionName:r,sessionStore:n});if("release_materialized_paths"===t.command)return await dT({req:t});if("push"===t.command){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await pL({req:t,sessionName:r,logPath:a,sessionStore:n,command:"push",positionals:[i,"file"===(e=lU(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>rC.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):{ok:!1,error:{code:"INVALID_ARGS",message:"push requires <bundle|package> <payload.json|inline-json>"}}}return"trigger-app-event"===t.command?await pL({req:t,sessionName:r,logPath:a,sessionStore:n,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await uk(e.device,r,e.appBundleId,uM)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await uU({req:t,sessionName:r,logPath:a,sessionStore:n}):pO.has(t.command)?await pD({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}):"batch"===t.command?await uK(t,r,i):"close"===t.command?await uj({req:t,sessionName:r,logPath:a,sessionStore:n}):null}function pR(e,t){let r=es(e.type??"Element"),a=Y(e,r),n=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),r,a,n,i,o].join("|")}function pT(e,t){return t.flatten?e.map(e=>({text:ex(e,0,!1),comparable:pR(e,0)})):en(e).map(e=>({text:e.text,comparable:pR(e.node,e.depth)}))}function p$(e,t){return e.get(t)??0}async function pF(e){let t=ub(e.session);if(t&&"android"===e.device.platform)return await pG(e,t);let r=await pU(e);return uA(e.session),{snapshot:pj(r,e.flags),analysis:r.analysis}}async function pU(e){let{device:t,session:r,flags:a,outPath:n,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await lO(r?.surface);return pq({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&r?.surface&&"app"!==r.surface?pq(await oY(r.surface,{bundleId:"menubar"===r.surface?r.appBundleId:void 0}),{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o}):await l7(t,"snapshot",[],n,{...db(i,{...a,snapshotScope:o},r?.appBundleId,r?.trace?.outPath)})}async function pG(e,t){let r=await pV(e),a=pB(r,t,e.flags),n=0;for(let i of uv){if(!a)break;await new Promise(e=>setTimeout(e,i)),r=await pV(e),n+=1,a=pB(r,t,e.flags)}return a||uA(e.session),{snapshot:r.snapshot,analysis:r.data.analysis,freshness:n>0||a?{action:t.action,retryCount:n,staleAfterRetries:!!a,reason:a??void 0}:void 0}}async function pV(e){let t=await pU(e);return{data:t,snapshot:pj(t,e.flags)}}function pB(e,t,r){let a=r?.snapshotInteractiveOnly===!0,n=e.data.analysis;return a&&0===e.snapshot.nodes.length&&n&&n.rawNodeCount>=12?"empty-interactive":u_(t.baselineCount,e.snapshot.nodes.length)?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&uS(t.action)&&function(e,t){if(!e||0===e.length)return!1;let r=Math.max(e.length,t.length);if(r<12)return!1;let a=uN(t),n=Math.min(e.length,a.length),i=0;for(let t=0;t<n;t+=1)e[t]===a[t]&&(i+=1);let o=Math.max(0,a.length-e.length),s=Math.max(0,e.length-a.length),l=Math.max(3,Math.floor(.15*r));return i>=Math.floor(.9*r)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function pj(e,t){let r=e?.nodes??[],a=em(t?.snapshotRaw?r:c1(r));return{nodes:e_(t?.snapshotScope&&e?.backend!=="macos-helper"?pH(a,t.snapshotScope):a),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function pq(e,t){var r,a;let n=e.nodes??[];return t.snapshotScope&&(n=pH(n,t.snapshotScope)),t.snapshotInteractiveOnly&&(n=function(e){if(0===e.length)return e;let t=new Map;for(let r of e)t.set(r.index,r);let r=new Set;for(let a of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(a))continue;let e=a;for(;e&&!r.has(e.index);)r.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===r.size?e:pW(e.filter(e=>r.has(e.index)))}(n)),"number"==typeof t.snapshotDepth&&(r=n,a=t.snapshotDepth,n=pW(r.filter(e=>(e.depth??0)<=a))),{...e,nodes:n}}function pH(e,t){let r=cZ(e_(e),t);if(!r)return[];let a=e.findIndex(e=>e.index===r.index);if(-1===a)return[];let n=e[a]?.depth??0,i=[];for(let t=a;t<e.length;t+=1){let r=e[t];if(!r)continue;let o=r.depth??0;if(t>a&&o<=n)break;i.push(r)}return pW(i,n)}function pW(e,t=0){let r=new Map;for(let[t,a]of e.entries())r.set(a.index,t);return e.map((e,a)=>({...e,index:a,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?r.get(e.parentIndex):void 0}))}function pz(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"Ref scope requires an existing snapshot in session."}}};let r=eh(e.trim());if(!r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref scope: ${e}`}}};let a=ec(t.snapshot.nodes,r),n=a?cQ(a,t.snapshot.nodes):void 0;return n?{ok:!0,scope:n}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${e} not found or has no label`}}}}async function pJ(e,t,r){let a=e.get(t),n=a?.device??await l9(r??{});return a||await dS(n),{session:a,device:n}}async function pK(e,t,r){let a=!e&&"ios"===t.platform;try{return await r()}finally{a&&await ro(t.id)}}function pX(e,t,r,a){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:a})}function pY(e){let{session:t,sessionName:r,device:a,snapshot:n,appBundleId:i}=e;return t?{...t,snapshot:n}:{name:r,device:a,createdAt:Date.now(),appBundleId:i,snapshot:n,actions:[]}}function pZ(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}async function pQ(e){let{parsed:t,req:r,sessionName:a,logPath:n,sessionStore:i,session:o,device:s}=e;if("sleep"===t.kind)return await new Promise(e=>setTimeout(e,t.durationMs)),pX(i,o,r,{waitedMs:t.durationMs}),{ok:!0,data:{waitedMs:t.durationMs}};if(!dI("wait",s))return uq("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===t.kind)return await p0({device:s,logPath:n,parsed:t,req:r,session:o,sessionName:a,sessionStore:i});let l=function(e,t){if("ref"===e.kind){if(!t?.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"Ref wait requires an existing snapshot in session."}}};let r=eh(e.rawRef);if(!r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref: ${e.rawRef}`}}};let a=ec(t.snapshot.nodes,r),n=a?cQ(a,t.snapshot.nodes):void 0;return n?{ok:!0,text:n,timeoutMs:e.timeoutMs}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${e.rawRef} not found or has no label`}}}}return e.text?{ok:!0,text:e.text,timeoutMs:e.timeoutMs}:{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires text"}}}}(t,o);return l.ok?await p1({device:s,logPath:n,req:r,session:o,sessionStore:i,text:l.text,timeoutMs:l.timeoutMs}):l.response}async function p0(e){let{device:t,logPath:r,parsed:a,req:n,session:i,sessionName:o,sessionStore:s}=e,l=a.timeoutMs??1e4,d=Date.now();for(;Date.now()-d<l;){let e=pf((await p2({device:t,logPath:r,req:n,session:i,sessionName:o,sessionStore:s})).nodes,a.selector,{platform:t.platform});if(e)return p3(s,i,n,{selector:e.selector.raw,waitedMs:Date.now()-d});await new Promise(e=>setTimeout(e,300))}return uq("COMMAND_FAILED",`wait timed out for selector: ${a.selectorExpression}`)}async function p1(e){let{device:t,logPath:r,req:a,session:n,sessionStore:i,text:o,timeoutMs:s}=e,l=s??1e4,d=Date.now();for(;Date.now()-d<l;){if("macos"===t.platform&&n?.surface&&"app"!==n.surface){if(cZ((await p2({device:t,logPath:r,req:a,session:n,sessionName:n?.name??a.session??"default",sessionStore:i})).nodes,o))return p3(i,n,a,{text:o,waitedMs:Date.now()-d})}else if(tN(t.platform)){let e=await rf(t,{command:"findText",text:o,appBundleId:n?.appBundleId},{verbose:a.flags?.verbose,logPath:r,traceLogPath:n?.trace?.outPath,requestId:a.meta?.requestId});if(e?.found)return pX(i,n,a,{text:o,waitedMs:Date.now()-d}),{ok:!0,data:{text:o,waitedMs:Date.now()-d}}}else if("android"===t.platform&&cZ((await p2({device:t,logPath:r,req:a,session:n,sessionName:n?.name??a.session??"default",sessionStore:i})).nodes,o))return pX(i,n,a,{text:o,waitedMs:Date.now()-d}),{ok:!0,data:{text:o,waitedMs:Date.now()-d}};await new Promise(e=>setTimeout(e,300))}return uq("COMMAND_FAILED",`wait timed out for text: ${o}`)}async function p2(e){let{device:t,logPath:r,req:a,session:n,sessionName:i,sessionStore:o}=e,{snapshot:s}=await pF({device:t,session:n,flags:{...a.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:a.flags?.out,logPath:r});return n&&(n.snapshot=s,o.set(i,n)),s}function p3(e,t,r,a){return pX(e,t,r,a),{ok:!0,data:a}}async function p4(e){let{req:t,logPath:r,sessionStore:a,session:n,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=n?"frontmost-app"===n.surface?{surface:"frontmost-app"}:{bundleId:n.appBundleId,surface:n.surface}:{};if(!dI("alert",i))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"alert is not supported on this device"}};if("macos"===i.platform){let e=async()=>await oX("wait"===o?"get":o,s);if("wait"===o){let r=pZ(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<r;){try{let r=await e();return pX(a,n,t,r),{ok:!0,data:r}}catch{}await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"alert wait timed out"}}}let r="accept"===o||"dismiss"===o?o:"get";if("accept"===r||"dismiss"===r){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await oX(r,s);return pX(a,n,t,e),{ok:!0,data:e}}catch(r){e=r;let t=String(r?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await new Promise(e=>setTimeout(e,300))}throw p5(e)}let i=await oX("get",s);return pX(a,n,t,i),{ok:!0,data:i}}if("wait"===o){let e=pZ(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await rf(i,{command:"alert",action:"get",appBundleId:n?.appBundleId},{verbose:t.flags?.verbose,logPath:r,traceLogPath:n?.trace?.outPath,requestId:t.meta?.requestId});return pX(a,n,t,e),{ok:!0,data:e}}catch{}await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"alert wait timed out"}}}let l="accept"===o||"dismiss"===o?o:"get",d={verbose:t.flags?.verbose,logPath:r,traceLogPath:n?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,r=Date.now();for(;Date.now()-r<2e3;){try{let e=await rf(i,{command:"alert",action:l,appBundleId:n?.appBundleId},d);return pX(a,n,t,e),{ok:!0,data:e}}catch(r){e=r;let t=String(r?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await new Promise(e=>setTimeout(e,300))}throw p5(e)}let u=await rf(i,{command:"alert",action:l,appBundleId:n?.appBundleId},d);return pX(a,n,t,u),{ok:!0,data:u}}function p5(e){if(!(e instanceof O))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new O(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}async function p8(e){let{req:t,logPath:r,sessionStore:a,session:n,device:i,parsed:o}=e,{setting:s,state:l,permissionTarget:d}=o;if(!dI("settings",i))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"settings is not supported on this device"}};if("macos"===i.platform&&!j(s))return{ok:!1,error:{code:"INVALID_ARGS",message:ea(s)}};let u=n?.appBundleId,c="permission"===s?[s,l,d??"",t.positionals?.[3]??"",u??""]:[s,l,u??""],p=await l7(i,"settings",c,t.flags?.out,{...db(r,t.flags,u,n?.trace?.outPath)});return pX(a,n,t,p??{setting:s,state:l}),{ok:!0,data:p??{setting:s,state:l}}}let p6=new Set(["snapshot","diff","wait","alert","settings"]);async function p9(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,i=t.command;if(!p6.has(i))return null;if("snapshot"===i){let{session:e,device:i}=await pJ(n,r,t.flags);if(!dI("snapshot",i))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"snapshot is not supported on this device"}};let o=pz(t.flags?.snapshotScope,e);return o.ok?await pK(e,i,async()=>{let s=await pF({device:i,session:e,flags:t.flags,outPath:t.flags?.out,logPath:a,snapshotScope:o.scope}),l=p7({capture:s,flags:t.flags,session:e}),d=function(e){var t;let{nodes:r,backend:a,snapshotRaw:n}=e;if(n||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:r.length,totalNodeCount:r.length,reasons:[]};let i=ei(r),o=new Set;return i.hiddenCount>0&&o.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:r.length,reasons:[...o]}}({nodes:s.snapshot.nodes,backend:s.snapshot.backend,snapshotRaw:t.flags?.snapshotRaw}),u=pY({session:e,sessionName:r,device:i,snapshot:s.snapshot,appBundleId:e?.appBundleId});return pX(n,u,t,{nodes:s.snapshot.nodes.length,truncated:s.snapshot.truncated??!1}),n.set(r,u),{ok:!0,data:{nodes:s.snapshot.nodes,truncated:s.snapshot.truncated??!1,visibility:d,...l.length>0?{warnings:l}:{},appName:u.appBundleId?u.appName??u.appBundleId:void 0,appBundleId:u.appBundleId}}}):o.response}if("diff"===i)return t.positionals?.[0]!=="snapshot"?{ok:!1,error:{code:"INVALID_ARGS",message:"diff currently supports only: diff snapshot"}}:await fe({req:t,sessionName:r,logPath:a,sessionStore:n});if("wait"===i){let{session:e,device:i}=await pJ(n,r,t.flags),o=function(e){if(0===e.length)return null;let t=pZ(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=pZ(e[e.length-1]);return{kind:"text",text:(null!==t?e.slice(1,-1).join(" "):e.slice(1).join(" ")).trim(),timeoutMs:t}}if(e[0].startsWith("@")){let t=pZ(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let r=pZ(e[e.length-1]),a=pt(null!==r?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=pe(a.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:a.selectorExpression,timeoutMs:r}}return{kind:"text",text:(null!==r?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:r}}(t.positionals??[]);if(!o)return{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires a duration or text"}};let s=()=>pQ({parsed:o,req:t,sessionName:r,logPath:a,sessionStore:n,session:e,device:i});return"sleep"===o.kind?await s():await pK(e,i,s)}if("alert"===i){let{session:e,device:i}=await pJ(n,r,t.flags);return await pK(e,i,async()=>await p4({req:t,logPath:a,sessionStore:n,session:e,device:i}))}if("settings"===i){let e,i,o,s=(e=t.positionals?.[0]?.toLowerCase(),i=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&i&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:i,permissionTarget:o}}:{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:z}}});if(!s.ok)return s.response;let{session:l,device:d}=await pJ(n,r,t.flags);return await pK(l,d,async()=>await p8({req:t,logPath:a,sessionStore:n,session:l,device:d,parsed:s.parsed}))}return null}function p7(e){let{capture:t,flags:r,session:a}=e,n=[],i=t.analysis,o=r?.snapshotInteractiveOnly===!0;"android"===t.snapshot.backend&&o&&0===t.snapshot.nodes.length&&i&&i.rawNodeCount>=12&&(n.push(`Interactive snapshot is empty after filtering ${i.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof r?.snapshotDepth&&i.maxDepth>=r.snapshotDepth+2&&n.push(`Interactive output is empty at depth ${r.snapshotDepth}; retry without -d.`));let s=a?.snapshot;return!t.freshness&&s&&Date.now()-s.createdAt<=2e3&&u_(s.nodes.length,t.snapshot.nodes.length)&&n.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once."),t.freshness?.staleAfterRetries&&"android"===t.snapshot.backend&&("stuck-route"===t.freshness.reason?n.push(`Recent ${t.freshness.action} was followed by a nearly identical snapshot after ${t.freshness.retryCount} automatic retr${1===t.freshness.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`):"sharp-drop"===t.freshness.reason&&n.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.")),rw(n)}async function fe(e){let{req:t,sessionName:r,logPath:a,sessionStore:n}=e,{session:i,device:o}=await pJ(n,r,t.flags);if(!dI("diff",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"diff is not supported on this device"}};let s=pz(t.flags?.snapshotScope,i);if(!s.ok)return s.response;let l=t.flags?.snapshotInteractiveOnly===!0;return await pK(i,o,async()=>{let e=await pF({device:o,session:i,flags:t.flags,outPath:t.flags?.out,logPath:a,snapshotScope:s.scope}),d=e.snapshot,u=p7({capture:e,flags:t.flags,session:i});if(!i?.snapshot){let e=function(e,t={}){return pT(e,t).length}(d.nodes,{flatten:l}),a=pY({session:i,sessionName:r,device:o,snapshot:d,appBundleId:i?.appBundleId});return pX(n,a,t,{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:e}}),n.set(r,a),{ok:!0,data:{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:e},lines:[],...u.length>0?{warnings:u}:{}}}}let c=function(e,t,r={}){let a=function(e,t){let r=e.length,a=t.length,n=r+a,i=new Map,o=[];i.set(1,0);for(let s=0;s<=n;s+=1){o.push(new Map(i));for(let n=-s;n<=s;n+=2){let l=n===-s||n!==s&&p$(i,n-1)<p$(i,n+1)?p$(i,n+1):p$(i,n-1)+1,d=l-n;for(;l<r&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(n,l),l>=r&&d>=a)return function(e,t,r,a,n){let i=[],o=a,s=n;for(let a=e.length-1;a>=0;a-=1){let n=e[a],l=o-s,d=l===-a||l!==a&&p$(n,l-1)<p$(n,l+1)?l+1:l-1,u=p$(n,d),c=u-d;for(;o>u&&s>c;)i.push({kind:"unchanged",text:r[s-1].text}),o-=1,s-=1;if(0===a)break;o===u?(i.push({kind:"added",text:r[c].text}),s=c):(i.push({kind:"removed",text:t[u].text}),o=u)}return i.reverse(),i}(o,e,t,r,a)}}return[]}(pT(e,r),pT(t,r)),n={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(n.additions+=1),"removed"===e.kind&&(n.removals+=1),"unchanged"===e.kind&&(n.unchanged+=1);return{summary:n,lines:a}}(i.snapshot.nodes,d.nodes,{flatten:l}),p={...i,snapshot:d};return pX(n,p,t,{mode:"snapshot",baselineInitialized:!1,summary:c.summary}),n.set(r,p),{ok:!0,data:{mode:"snapshot",baselineInitialized:!1,summary:c.summary,lines:c.lines,...u.length>0?{warnings:u}:{}}}})}function ft(e,t,r,a={}){let n=fa(r);if(!n)return{matches:[],score:0};let i=0,o=[];for(let r of e){if(a.requireRect&&!r.rect)continue;let e=function(e,t,r){switch(t){case"role":return function(e,t){let r=function(e){let t=e.trim();return t?t=(t.split(".").pop()??t).replace(/XCUIElementType/gi,"").toLowerCase():""}(e??"");return r?r===t?2:+!!r.includes(t):0}(e.type,r);case"label":return fr(e.label,r);case"value":return fr(e.value,r);case"id":return fr(e.identifier,r);default:return Math.max(fr(e.label,r),fr(e.value,r),fr(e.identifier,r))}}(r,t,n);if(!(e<=0)){if(e>i){i=e,o.length=0,o.push(r);continue}e===i&&o.push(r)}}return{matches:o,score:i}}function fr(e,t){let r=fa(e??"");return r?r===t?2:+!!r.includes(t):0}function fa(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function fn(e){let{session:t,refInput:r,fallbackLabel:a,requireRect:n,invalidRefMessage:i,notFoundMessage:o}=e;if(!t.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"No snapshot in session. Run snapshot first."}}};let s=eh(r);if(!s)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:i}}};let l=ec(t.snapshot.nodes,s);return((!l||n&&!l.rect)&&a.length>0&&(l=cZ(t.snapshot.nodes,a)),l&&(!n||l.rect))?{ok:!0,target:{ref:s,node:l,snapshotNodes:t.snapshot.nodes}}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:o}}}}function fi(e){let t=fo(e);if(!t)return null;let r=eA(t);return Number.isFinite(r.x)&&Number.isFinite(r.y)?r:null}function fo(e){if(!e)return null;let t=Number(e.x),r=Number(e.y),a=Number(e.width),n=Number(e.height);return Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(a)&&Number.isFinite(n)&&!(a<0)&&!(n<0)?{x:t,y:r,width:a,height:n}:null}async function fs(e){let{session:t,refInput:r,fallbackLabel:a,commandLabel:n,promoteToHittableAncestor:i,invalidRefMessage:o,missingBoundsMessage:s,invalidBoundsMessage:l,reqFlags:d,sessionStore:u,contextFromFlags:c,captureSnapshotForSession:p,resolveRefTarget:f}=e,m=f({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:o,notFoundMessage:s});if(!m.ok)return{ok:!1,response:m.response};let{ref:h}=m.target,w=i?fl(m.target.snapshotNodes,m.target.node):m.target.node,g=m.target.snapshotNodes,y=fi(w.rect);if(!y){let e=await p(t,d,u,c,{interactiveOnly:!0}),r=ec(e.nodes,h),n=a.length>0?cZ(e.nodes,a):null,o=r&&i?fl(e.nodes,r):r,s=n&&i?fl(e.nodes,n):n,l=fi(s?.rect),f=fi(o?.rect)?o:l?s:o??s,m=fi(f?.rect);f&&m&&(w=f,g=e.nodes,y=m)}if(!y)return{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:l}}};let v=w.rect?er(w,g):null;return w.rect&&v&&!B(w,g)?{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${r} is off-screen and not safe to ${n}`,hint:`Run scrollintoview ${r}, then retry ${n} with the returned currentRef or a fresh snapshot.`,details:{reason:"offscreen_ref",ref:h,rect:w.rect,viewport:v}}}}:{ok:!0,target:{ref:h,node:w,snapshotNodes:g,point:y}}}function fl(e,t){let r=function(e,t){let r=fo(t.rect);if(!r)return null;let a=t,n=new Set;for(;!n.has(a.ref);){n.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=fo(e.rect);return!!t&&fd(t,r)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(r?.rect&&fi(r.rect))return r;let a=c4(e,t);return a?.rect&&fi(a.rect)?!function(e,t,r){var a,n,i,o;let s,l,d,u=fo(e.rect),c=fo(t.rect);if(!u||!c)return!1;let p=function(e,t){let r=eA(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>fo(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let n=a.filter(e=>J(e,r.x,r.y));return ef(n.length>0?n:a)}(r,u);return!!p&&(a=c,n=p,s=(i=a,o=n,Math.max(0,Math.min(i.x+i.width,o.x+o.width)-Math.max(i.x,o.x))*Math.max(0,Math.min(i.y+i.height,o.y+o.height)-Math.max(i.y,o.y))),l=a.width*a.height,d=n.width*n.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!fd(u,c)}(t,a,e)?a:t:t}function fd(e,t){return .5>=Math.abs(e.x-t.x)&&.5>=Math.abs(e.y-t.y)&&.5>=Math.abs(e.width-t.width)&&.5>=Math.abs(e.height-t.height)}async function fu(e){let{device:t,node:r,flags:a,appBundleId:n,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=et(r),d=fi(r.rect);if(!d)return l;try{let e=await l7(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,n,i),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return U({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:o,platform:t.platform}}),l}catch(e){return U({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:r.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}async function fc(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return uq("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:p}=function(e){let t="any",r=0;["text","label","value","role","id"].includes(e[0])&&(t=e[0],r=1);let a=e[r]??"",n=e.slice(r+1);if(0===n.length)return{locator:t,query:a,action:"click"};let i=n[0].toLowerCase();if("get"===i){let e=n[1]?.toLowerCase();if("text"===e)return{locator:t,query:a,action:"get_text"};if("attrs"===e)return{locator:t,query:a,action:"get_attrs"};throw new O("INVALID_ARGS","find get only supports text or attrs")}if("wait"===i)return{locator:t,query:a,action:"wait",timeoutMs:pZ(n[1])??void 0};if("exists"===i)return{locator:t,query:a,action:"exists"};if("click"===i)return{locator:t,query:a,action:"click"};if("focus"===i)return{locator:t,query:a,action:"focus"};if("fill"===i)return{locator:t,query:a,action:"fill",value:n.slice(1).join(" ")};if("type"===i)return{locator:t,query:a,action:"type",value:n.slice(1).join(" ")};throw new O("INVALID_ARGS",`Unsupported find action: ${n[0]}`)}(s);if(!d)return uq("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return uq("INVALID_ARGS","find accepts only one of --first or --last");let f=n.get(r);if(!f&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return uq("SESSION_NOT_FOUND","No active session. Run open first.");let m=f?.device??await l9(t.flags??{});f||await dS(m);let h="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,g=0,y=null,v=async()=>{let e=Date.now();if(y&&e-g<750&&!ub(f))return{nodes:y};let{snapshot:i}=await pF({device:m,session:f,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:h}),o=i.nodes;return g=e,y=o,f&&(f.snapshot=i,n.set(r,f)),{nodes:o,truncated:i.truncated,backend:i.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:n,invoke:i,session:f,device:m,command:o,locator:l,query:d};if("wait"===u)return fp(I,v,l,d,p);let{nodes:b}=await v(),A=ft(b,l,d,{requireRect:w});if(w&&A.matches.length>1)if(t.flags?.findFirst)A.matches=[A.matches[0]];else{if(!t.flags?.findLast){var S,N,_;let e;return S=A.matches,N=l,_=d,e=S.slice(0,8).map(e=>{let t=c5(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),{ok:!1,error:{code:"AMBIGUOUS_MATCH",message:`find matched ${S.length} elements for ${N} "${_}". Use a more specific locator or selector.`,details:{locator:N,query:_,matches:S.length,candidates:e}}}}A.matches=[A.matches[A.matches.length-1]]}let x=A.matches[0]??null;if(!x)return uq("COMMAND_FAILED","find did not match any element");let D="click"===u||"focus"===u||"fill"===u||"type"===u?c4(b,x)??x:x,M=`@${D.ref}`,k={node:x,resolvedNode:D,ref:M,nodes:b,actionFlags:{...t.flags??{},noRecord:!0}},E={exists:()=>ff(I),get_text:()=>fm(I,k),get_attrs:()=>fh(I,k),click:()=>fw(I,k),fill:()=>fg(I,k,c),focus:()=>fy(I,k),type:()=>fv(I,k,c)}[u];return E?E():null}async function fp(e,t,r,a,n){let{req:i,sessionStore:o,session:s,command:l}=e,d=n??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(ft(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:i.positionals??[],flags:i.flags??{},result:{found:!0,waitedMs:Date.now()-u}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-u}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"find wait timed out"}}}async function ff(e){let{req:t,sessionStore:r,session:a,command:n}=e;return a&&r.recordAction(a,{command:n,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function fm(e,t){let{req:r,sessionStore:a,session:n,command:i,device:o,logPath:s}=e,l=await fu({device:o,node:t.node,flags:r.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:(e,t,r)=>db(s,e,t,r)});return n&&a.recordAction(n,{command:i,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get text",text:l}}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function fh(e,t){let{req:r,sessionStore:a,session:n,command:i}=e;return n&&a.recordAction(n,{command:i,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function fw(e,t){let{req:r,sessionName:a,sessionStore:n,session:i,invoke:o,command:s,locator:l,query:d}=e,u=await o({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let c=t.resolvedNode.rect?eA(t.resolvedNode.rect):null,p={ref:t.ref,locator:l,query:d};return c&&(p.x=c.x,p.y=c.y),i&&n.recordAction(i,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:p}}async function fg(e,t,r){let{req:a,sessionName:n,sessionStore:i,session:o,invoke:s,command:l}=e;if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"find fill requires text"}};let d=await s({token:a.token,session:n,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&i.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function fy(e,t){let{req:r,sessionStore:a,session:n,device:i,command:o,logPath:s}=e,l=t.node.rect?eA(t.node.rect):null;if(!l)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};let d=await l7(i,"focus",[String(l.x),String(l.y)],r.flags?.out,{...db(s,r.flags,n?.appBundleId,n?.trace?.outPath)});return n&&a.recordAction(n,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function fv(e,t,r){let{req:a,sessionStore:n,session:i,device:o,command:s,logPath:l}=e;if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"find type requires text"}};let d=t.node.rect?eA(t.node.rect):null;if(!d)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};await l7(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...db(l,a.flags,i?.appBundleId,i?.trace?.outPath)});let u=await l7(o,"type",[r],a.flags?.out,{...db(l,a.flags,i?.appBundleId,i?.trace?.outPath)});return i&&n.recordAction(i,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let fI=`
45
45
  import Foundation
46
46
  import AVFoundation
47
47
 
@@ -65,11 +65,11 @@ Task {
65
65
 
66
66
  semaphore.wait()
67
67
  exit(exitCode)
68
- `.trim();async function fb(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,i=0;for(let t=0;t<n;t+=1){let t=0;try{t=s.statSync(e).size}catch{t=0}if(t>0&&t===r){if((i+=1)>=2)return}else i=0;r=t,await new Promise(e=>setTimeout(e,a))}}async function fA(e){try{var t,r;let a,n=await $("swift",["-",e],{stdin:fI,allowFailure:!0,timeoutMs:1e4});if(0===n.exitCode)return!0;if(t=n.stderr,r=n.stdout,a=`${t}
69
- ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return fN(e);return!1}catch(t){if(t instanceof W&&"TOOL_MISSING"===t.code)return fN(e);throw t}}async function fS(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await fA(e))return;await new Promise(e=>setTimeout(e,r))}}function fN(e){try{let t=s.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=s.openSync(e,"r");try{let e=s.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>s.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),i=e.toString("latin1",4,8);if(a.push(i),1===n){let e=Buffer.alloc(8);if(8>s.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{s.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function f_(e){let t=p.parse(e);return p.join(t.dir,`${t.name}.gesture-telemetry.json`)}function fx(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function fD(e){var t,r,a;let n,i,{recording:o,trimStartMs:l}=e,d=(n=f_((t={videoPath:o.outPath,events:o.gestureEvents,trimStartMs:l}).videoPath),i={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?fx(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):fx(r))},s.writeFileSync(n,JSON.stringify(i,null,2)),n);return o.telemetryPath=d,d}function fM(e){let t=p.dirname(w(import.meta.url)),r=[w(new URL(`./${e}`,import.meta.url)),p.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),p.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),p.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(s.existsSync(e))return e;throw new W("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure ios-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}function fk(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}async function fE(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await fb(t),await fS(t);let i=s.mkdtempSync(p.join(u.tmpdir(),"agent-device-record-overlay-")),o=p.join(i,`input${p.extname(t)||".mp4"}`),l=p.join(i,p.basename(t)),d=p.join(i,"home"),c=p.join(i,"module-cache");s.copyFileSync(t,o),s.mkdirSync(d,{recursive:!0}),s.mkdirSync(c,{recursive:!0});try{await $("xcrun",["swift",r,"--input",o,"--output",l,...a],{timeoutMs:12e4,env:{...process.env,HOME:d,CLANG_MODULE_CACHE_PATH:c}}),await fS(l),s.copyFileSync(l,t)}catch(a){let e=a instanceof W?a:new W("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new W("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{s.rmSync(i,{recursive:!0,force:!0})}}async function fO(e){let{videoPath:t,trimStartMs:r}=e;r>0&&await fE({videoPath:t,scriptPath:a??=fM("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(r)],commandDescription:"Failed to trim the start of the iOS recording"})}async function fL(e){let{videoPath:t,telemetryPath:a,targetLabel:n="recording"}=e;await fE({videoPath:t,scriptPath:r??=fM("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${n}`})}function fC(e){return e instanceof Error?e.message:String(e)}function fP(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function fR(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","ps","-o","pid=","-p",r],{allowFailure:!0});return 0===a.exitCode&&a.stdout.split(/\s+/).map(e=>e.trim()).includes(r)}async function fT(e,t,r){for(let a=0;a<40;a+=1){if(!await fR(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await fR(e,t,r)}async function f$(e,t,r){let a,n=0;for(let i=0;i<20;i+=1){let i=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===i.exitCode?i.stdout.trim():"";if(o.length>0&&o===a){if((n+=1)>=4)return}else n=0;a=o,await new Promise(e=>setTimeout(e,250))}}async function fF(e,t,r,a){for(let n=0;n<8;n+=1){let i=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===i.exitCode?Number(i.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await fR(e,t,a))break;if(n+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function fU(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:i}=e;for(let e=0;e<2;e+=1){try{s.rmSync(i,{force:!0})}catch{}let o=await r.runCmd("adb",["-s",a,"pull",n,i],{allowFailure:!0});if(0!==o.exitCode)t=fP(o,"adb pull");else{await r.waitForStableFile(i,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(i);if(ep({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:i,attempt:e+1,fileSize:(()=>{try{return s.statSync(i).size}catch{return 0}})(),playable:t}}),t)return;ep({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:i,attempt:e+1}})}e<1&&await new Promise(e=>setTimeout(e,750))}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function fG(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function fV(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return ep({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:t,remotePid:r,exitCode:a.exitCode,stdout:a.stdout.trim(),stderr:a.stderr.trim()}}),!(0!==a.exitCode&&await fR(e,t,r))&&await fT(e,t,r)}async function fB(e){var t;let r,{deps:a,device:n,recordingBase:i}=e,o="failed to start recording: Android screenrecord did not begin producing frames";for(let e of(t=Date.now(),r=`agent-device-recording-${t}.mp4`,[`/sdcard/${r}`,`/data/local/tmp/${r}`])){let t=await a.runCmd("adb",["-s",n.id,"shell",`screenrecord ${e} >/dev/null 2>&1 & echo $!`],{allowFailure:!0});if(0!==t.exitCode){o=`failed to start recording: ${fP(t,"adb shell screenrecord")}`;continue}let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!r){o="failed to start recording: adb did not return a valid Android screenrecord pid",await fG(a,n.id,e);continue}if(ep({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:r}}),await fF(a,n.id,e,r))return{platform:"android",remotePath:e,remotePid:r,...i,startedAt:Date.now()};o="failed to start recording: Android screenrecord did not begin producing frames",await fV(a,n.id,r),await fG(a,n.id,e)}return{ok:!1,error:{code:"COMMAND_FAILED",message:o}}}async function fj(e){let t,r,{deps:a,device:n,recording:i}=e;ep({level:"debug",phase:"record_stop_android_enter",data:{deviceId:n.id,remotePath:i.remotePath,remotePid:i.remotePid}});let o=await a.runCmd("adb",["-s",n.id,"shell","kill","-2",i.remotePid],{allowFailure:!0});if(ep({level:"debug",phase:"record_stop_android_signal",data:{deviceId:n.id,remotePath:i.remotePath,remotePid:i.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await fR(a,n.id,i.remotePid)&&!await fV(a,n.id,i.remotePid)&&(t=`failed to stop recording: ${fP(o,"adb shell kill")}`):await fT(a,n.id,i.remotePid)||await fV(a,n.id,i.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${i.remotePid} did not exit`),!t){await f$(a,n.id,i.remotePath);let e=await fU({deps:a,deviceId:n.id,remotePath:i.remotePath,outPath:i.outPath});if(e)return await s(),{ok:!1,error:{code:"COMMAND_FAILED",message:e}};if(fD({recording:i}),i.showTouches&&i.telemetryPath){let e=fk();if(e)i.overlayWarning=e;else try{await a.overlayRecordingTouches({videoPath:i.outPath,telemetryPath:i.telemetryPath,targetLabel:"Android recording"})}catch(e){i.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}}if(await s(),t)return{ok:!1,error:{code:"COMMAND_FAILED",message:t}};if(r)return{ok:!1,error:{code:"COMMAND_FAILED",message:r}};return null;async function s(){let e=await a.runCmd("adb",["-s",n.id,"shell","rm","-f",i.remotePath],{allowFailure:!0});ep({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:n.id,remotePath:i.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${fP(e,"adb shell rm")}`)}}function fq(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function fH(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function fW(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i}=e,o=fq(r);if(o)try{await i.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},fH(t,n,r))}catch(e){ep({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:fC(e)}})}}async function fz(e){let t,r,{req:a,activeSession:n,sessionStore:i,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,p=`agent-device-recording-${Date.now()}.mp4`,f=`tmp/${p}`,m=fH(a,s,n),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:p,fps:d,appBundleId:c},m);try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(a){var w,g;if(!fC(a).toLowerCase().includes("recording already in progress"))return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${fC(a)}`}};ep({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:n.name,error:fC(a)}});let e=(w=o.id,g=n.name,i.toArray().find(e=>e.name!==g&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===w&&e.recording?.platform==="ios-device-runner"));if(e)return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: recording already in progress in session '${e.name}'`}};try{await l.runIosRunnerCommand(o,{command:"recordStop",appBundleId:c},m)}catch{}try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(e){return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${fC(e)}`}}}}return{platform:"ios-device-runner",remotePath:f,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function fJ(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await i.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,appBundleId:l},fH(t,n,r))}catch(e){return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${fC(e)}`}}}return{platform:"macos-runner",...s}}async function fK(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i,recording:o}=e,s=fq(r);try{await i.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},fH(t,n,r))}catch(e){ep({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:fC(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of tq)if(0===(l=await i.runCmd("xcrun",["devicectl","device","copy","from","--device",a.id,"--source",o.remotePath,"--destination",o.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==l.exitCode){let e=l.stderr.trim()||l.stdout.trim()||`devicectl exited with code ${l.exitCode}`;return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to copy recording from device: ${e}`}}}let d="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);d>0&&await i.trimRecordingStart({videoPath:o.outPath,trimStartMs:d});let u=fD({recording:o,trimStartMs:d});if(o.showTouches){let e=fk();if(e)o.overlayWarning=e;else try{await i.overlayRecordingTouches({videoPath:o.outPath,telemetryPath:u,targetLabel:"iOS recording"})}catch(e){o.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}return null}async function fX(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i,recording:o}=e,s=fq(r);try{await i.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},fH(t,n,r))}catch(e){ep({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:fC(e)}})}let l=fD({recording:o});if(o.showTouches){let e=fk();if(e)o.overlayWarning=e;else try{await i.overlayRecordingTouches({videoPath:o.outPath,telemetryPath:l,targetLabel:"macOS recording"})}catch(e){o.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}return null}async function fY(e){for(let t=0;t<2;t+=1){try{if(s.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await new Promise(e=>setTimeout(e,250))}return Date.now()}async function fZ(e){let t,r,{req:a,activeSession:n,device:i,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await fW({req:a,activeSession:n,device:i,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",tt(i,["io",i.id,"recordVideo",d]),{allowFailure:!0}),p=await fY(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(i,{command:"uptime",appBundleId:fq(n)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:n.trace?.outPath}),d=Date.now();t=Math.round((e+d)/2),r="number"==typeof l.currentUptimeMs?l.currentUptimeMs:void 0}catch{}return{platform:"ios",child:u,wait:c,...l,startedAt:p,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function fQ(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:i,device:o,logPath:l,deps:d}=e;if(i.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"recording already in progress"}};let u=r.flags?.fps;if(void 0!==u&&(!Number.isInteger(u)||u<1||u>120))return{ok:!1,error:{code:"INVALID_ARGS",message:"fps must be an integer between 1 and 120"}};if(!dI("record",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"record is not supported on this device"}};let c=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,f=rC.expandHome(c,r.meta?.cwd),m={outPath:f,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(s.mkdirSync(p.dirname(f),{recursive:!0}),s.rmSync(f,{force:!0}),"ios"===o.platform&&"device"===o.kind){let e=fq(i);if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"record on physical iOS devices requires an active app session; run open <app> first"}};t=await fz({req:r,activeSession:i,sessionStore:n,device:o,logPath:l,deps:d,fpsFlag:u,recordingBase:m,appBundleId:e})}else if("macos"===o.platform){let e=fq(i);if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"record on macOS requires an active app session; run open <app> first"}};t=await fJ({req:r,activeSession:i,device:o,logPath:l,deps:d,fpsFlag:u,recordingBase:m,appBundleId:e})}else t="ios"===o.platform?await fZ({req:r,activeSession:i,device:o,logPath:l,deps:d,recordingBase:m,resolvedOut:f}):await fB({deps:d,device:o,recordingBase:m});return"ok"in t?t:(i.recording=t,n.set(a,i),n.recordAction(i,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??c,showTouches:t.showTouches}})}async function f0(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await fj({deps:t,device:r,recording:a});a.child.kill("SIGINT");let n=await a.wait;if(0!==n.exitCode)return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to stop recording: ${fP(n,"simctl recordVideo")}`}};let i=fD({recording:a});if(a.showTouches){let e=fk();if(e)a.overlayWarning=e;else try{await t.overlayRecordingTouches({videoPath:a.outPath,telemetryPath:i,targetLabel:"iOS recording"})}catch(e){a.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}return null}async function f1(e){var t;let r,{req:a,activeSession:n,device:i,logPath:o,deps:s}=e;if(!n.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"no active recording"}};let l=n.recording,d=l.invalidatedReason;n.recording=void 0;let u="ios-device-runner"===l.platform?await fK({req:a,activeSession:n,device:i,logPath:o,deps:s,recording:l}):"macos-runner"===l.platform?await fX({req:a,activeSession:n,device:i,logPath:o,deps:s,recording:l}):await f0({deps:s,device:i,recording:l});return u||(d?{ok:!1,error:{code:"COMMAND_FAILED",message:d}}:(r=[{field:"outPath",path:(t=l).outPath,localPath:t.clientOutPath,fileName:p.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return f_(e.clientOutPath)}(t),fileName:p.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function f2(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,i={runCmd:$,runCmdBackground:P,runIosRunnerCommand:rf,waitForStableFile:fb,isPlayableVideo:fA,trimRecordingStart:fO,overlayRecordingTouches:fL},o=a.get(r),s=o?.device??await l9(t.flags??{});o||await dS(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return{ok:!1,error:{code:"INVALID_ARGS",message:"record requires start|stop"}};if("start"===d)return fQ({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:n,deps:i});let u=await f1({req:t,activeSession:l,device:s,logPath:n,deps:i});return u.ok&&a.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:u.data?.outPath,showTouches:u.data?.showTouches}}),u}async function f3(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,i=t.command;if("record"===i)return f2({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===i){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return uq("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return uq("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return uq("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=rC.expandHome(e);return s.mkdirSync(p.dirname(r),{recursive:!0}),s.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return uq("INVALID_ARGS","no active trace");let o=n.trace.outPath;if(t.positionals?.[1]){let e=rC.expandHome(t.positionals[1]);s.mkdirSync(p.dirname(e),{recursive:!0}),s.existsSync(o)?s.renameSync(o,e):s.appendFileSync(e,""),o=e}return n.trace=void 0,a.recordAction(n,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:o}}),{ok:!0,data:{trace:"stopped",outPath:o}}}return null}function f4(e){return"number"==typeof e.gestureClockOriginAtMs&&"number"==typeof e.gestureClockOriginUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureClockOriginAtMs+(e.gestureStartUptimeMs-e.gestureClockOriginUptimeMs)-e.recordingStartedAt):"number"==typeof e.runnerStartedAtUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureStartUptimeMs-e.runnerStartedAtUptimeMs):"number"==typeof e.gestureStartUptimeMs&&"number"==typeof e.gestureEndUptimeMs?Math.max(0,e.fallbackFinishedAtMs-(e.gestureEndUptimeMs-e.gestureStartUptimeMs)-e.recordingStartedAt):Math.max(0,e.fallbackStartedAtMs-e.recordingStartedAt)}let f5=new WeakMap;function f8(e){if(!e)return;let t=f5.get(e);if(t)return t;let r=function(e){let t=function(e){let t=e.filter(e=>(function(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("application")||t.includes("window")})(e.type)&&f6(e.rect)).map(e=>e.rect).sort((e,t)=>(t?.width??0)*(t?.height??0)-(e?.width??0)*(e?.height??0))[0];if(t)return t;let r=e.map(e=>e.rect).filter(f6);if(0===r.length)return;let a=Math.max(...r.map(e=>e.x+e.width)),n=Math.max(...r.map(e=>e.y+e.height));if(!(a<=0)&&!(n<=0))return{x:0,y:0,width:a,height:n}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return f5.set(e,r),r}function f6(e){return!!e&&e.width>0&&e.height>0}let f9={referenceWidth:1e3,referenceHeight:1e3};function f7(e,t,r,a,n={},i=Date.now(),o=Date.now()){var s,l,d;let u,c,p=e.recording;if(!p)return;let f={...n,...a??{}},m=ma(f.effectiveDurationMs)??ma(f.durationMs),h={recordingStartedAt:p.startedAt,gestureClockOriginAtMs:p.gestureClockOriginAtMs,gestureClockOriginUptimeMs:p.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===p.platform?p.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:ma(f.gestureStartUptimeMs),gestureEndUptimeMs:ma(f.gestureEndUptimeMs),fallbackStartedAtMs:i,fallbackFinishedAtMs:o},w="number"==typeof(s={gestureStartUptimeMs:ma(f.gestureStartUptimeMs),gestureEndUptimeMs:ma(f.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:i,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),g="ios"===e.device.platform&&void 0===ma(f.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=mn(ma(t.count),1)??1,r=!0===t.doubleTap,a=mn(ma(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,f)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return f4(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:w}):f4(h),y=(l=e.snapshot,u=ma((d=f).referenceWidth),c=ma(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:f8(l)),v=function(e,t,r,a,n,i){switch(e){case"click":case"press":return function(e,t,r,a){let n=mi(t,e);if(!n)return[];let{x:i,y:o}=n,s=mn(ma(t.count),1)??1,l=mn(ma(t.intervalMs),0)??0,d=!0===t.doubleTap,u=mn(ma(t.holdMs),1),c=[];for(let e=0;e<s;e+=1){let t=r+e*l;if(void 0!==u&&u>0){c.push(mt(t,i,o,u,a));continue}c.push(me(t,i,o,a)),d&&c.push(me(t+90,i,o,a))}return c}(t,r,a,i);case"fill":case"focus":return function(e,t,r,a){let n=mi(t,e);if(!n)return[];let{x:i,y:o}=n;return[me(r,i,o,a)]}(t,r,a,i);case"longpress":return function(e,t,r,a,n){let i=mi(t,e);if(!i)return[];let{x:o,y:s}=i;return[mt(r,o,s,ms(a,[ma(t.durationMs),ma(e[2])],800),n)]}(t,r,a,n,i);case"scroll":return function(e,t,r,a,n){let i=mo(t,e),o=mr(t.contentDirection)??mr(t.direction);if(!i||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=i,c=ms(a,[],250),p=ma(t.amount)??ma(e[1]),f=ma(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...n,durationMs:c,contentDirection:o,...void 0!==p?{amount:p}:{},...void 0!==f?{pixels:f}:{}}]}(t,r,a,n,i);case"swipe":return function(e,t,r,a,n){let i=mo(t,e);if(!i)return[];let{x1:o,y1:s,x2:l,y2:d}=i,u=ms(a,[ma(t.effectiveDurationMs),ma(t.durationMs),ma(e[4])],250),c=mn(ma(t.count),1)??1,p=mn(ma(t.pauseMs),0)??0,f="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===f&&e%2==1,a=t?l:o,i=t?d:s,c=t?o:l,h=t?s:d,w=r+e*(u+p);if("back-swipe"===function(e,t,r,a,n){if(!n||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let i=.08*n.referenceWidth;return e<=i&&r>e||e>=n.referenceWidth-i&&r<e?"back-swipe":"swipe"}(a,i,c,h,n)){m.push({kind:"back-swipe",tMs:w,x:a,y:i,x2:c,y2:h,...n,durationMs:u,edge:function(e,t,r){if(r){let t=.08*r.referenceWidth;if(e<=t)return"left";if(e>=r.referenceWidth-t)return"right"}return t>=e?"left":"right"}(a,c,n)});continue}m.push({kind:"swipe",tMs:w,x:a,y:i,x2:c,y2:h,...n,durationMs:u})}return m}(t,r,a,n,i);case"pinch":return function(e,t,r,a,n){let i=mi(t,e,1),o=ma(t.scale)??ma(e[0]);if(!i||void 0===o||o<=0)return[];let{x:s,y:l}=i;return[{kind:"pinch",tMs:r,x:s,y:l,...n,scale:o,durationMs:ms(a,[],280)}]}(t,r,a,n,i);default:return[]}}(t,r,f,g,w,y);0!==v.length&&(p.gestureEvents.push(...v),ep({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:g,gestureDurationMs:w,kinds:v.map(e=>e.kind)}}))}function me(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function mt(e,t,r,a,n){return{kind:"longpress",tMs:e,x:t,y:r,...n,durationMs:a}}function mr(e){if("string"!=typeof e)return;let t=e.trim().toLowerCase();switch(t){case"up":case"down":case"left":case"right":return t;default:return}}function ma(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"!=typeof e||0===e.trim().length)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function mn(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function mi(e,t,r=0){let a=ma(e.x)??ma(t[r]),n=ma(e.y)??ma(t[r+1]);if(void 0!==a&&void 0!==n)return{x:a,y:n}}function mo(e,t){let r=ma(e.x1)??ma(t[0]),a=ma(e.y1)??ma(t[1]),n=ma(e.x2)??ma(t[2]),i=ma(e.y2)??ma(t[3]);if(void 0!==r&&void 0!==a&&void 0!==n&&void 0!==i)return{x1:r,y1:a,x2:n,y2:i}}function ms(e,t,r){return mn(e,1)??t.map(e=>mn(e,1)).find(e=>void 0!==e)??r}function ml(e){var t,r,a;let n,i,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,n="string"==typeof t?.ref?t.ref:void 0,i="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:n?i&&"primary"!==i?`Clicked ${i} @${n} (${r}, ${a})`:`Tapped @${n} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...ec(c)}}async function md(e){let{session:t,sessionStore:r,requestCommand:a,requestPositionals:n,flags:i,contextFromFlags:o,interactionCommand:s,interactionPositionals:l,outPath:d,afterDispatch:u,buildPayloads:c}=e,p=await mu({session:t,flags:i,contextFromFlags:o,command:s,positionals:l,outPath:d});await u?.(p.data);let{result:f,responseData:m=f}=await c(p.data);return function(e){let{session:t,sessionStore:r,command:a,positionals:n,flags:i,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:n,flags:i??{},result:o}),uS(a)&&uI(t,a),f7(t,a,n,o,i??{},l,d),{ok:!0,data:s}}({session:t,sessionStore:r,command:a,positionals:n,flags:i,result:f,responseData:m,actionStartedAt:p.actionStartedAt,actionFinishedAt:p.actionFinishedAt})}async function mu(e){let{session:t,flags:r,contextFromFlags:a,command:n,positionals:i,outPath:o}=e,s=Date.now(),l={...a(r,t.appBundleId,t.trace?.outPath)},d=await l7(t.device,n,i,o,l);return{data:d&&"object"==typeof d?d:void 0,actionStartedAt:s,actionFinishedAt:Date.now()}}async function mc(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await ij(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=f8(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=f8(await i(t,r,a,n,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function mp(e){try{return await mc(e)}catch(t){ep({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function mf(e){return f8({nodes:e,createdAt:0})}function mm(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`}}}async function mh(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r),d=t.command,u="click"===d?"click":"press";if(!l)return uq("SESSION_NOT_FOUND","No active session. Run open first.");let c=mm(l,u);if(c)return c;if(!dI("press",l.device))return uq("UNSUPPORTED_OPERATION","press is not supported on this device");let p=lL(t.flags),f="primary"===p?{}:{button:p};if("primary"!==p){let e=lC({commandLabel:u,platform:l.device.platform,button:p,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return uq(e.code,e.message,e.details)}let m=function(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}(t.positionals??[]);if(m)return md({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[String(m.x),String(m.y)],flags:t.flags,contextFromFlags:n,interactionCommand:"press",interactionPositionals:[String(m.x),String(m.y)],outPath:t.flags?.out,afterDispatch:async()=>{await mw(l,"coordinate tap")},buildPayloads:async e=>{let r=await mp({session:l,flags:t.flags,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i}),o=ml({data:e,fallbackX:m.x,fallbackY:m.y,referenceFrame:r,extra:f});return{result:o,responseData:o}}});let h="click",w=t.positionals?.[0]??"";if(w.startsWith("@")){let e=s("press",t.flags);if(e)return e;let r=t.positionals.length>1?t.positionals.slice(1).join(" ").trim():"",c=await fs({session:l,refInput:w,fallbackLabel:r,commandLabel:u,promoteToHittableAncestor:!0,invalidRefMessage:`${u} requires a ref like @e2`,missingBoundsMessage:`Ref ${w} not found or has no bounds`,invalidBoundsMessage:`Ref ${w} not found or has invalid bounds`,reqFlags:t.flags,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o});if(!c.ok)return c.response;let{ref:p,node:m,snapshotNodes:g,point:y}=c.target,v=cQ(m,g),I=pw(m,l.device.platform,{action:h}),{x:b,y:A}=y;return md({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"press",interactionPositionals:[String(b),String(A)],outPath:t.flags?.out,afterDispatch:async()=>{await mw(l,`@${p}`)},buildPayloads:e=>{let t=ml({data:e,fallbackX:b,fallbackY:A,referenceFrame:mf(g),extra:{ref:p,refLabel:v,selectorChain:I,...f}});return{result:t,responseData:t}}})}let g=(t.positionals??[]).join(" ").trim();if(!g)return{ok:!1,error:{code:"INVALID_ARGS",message:`${u} requires @ref, selector expression, or x y coordinates`}};let y=c7(g),v=await i(l,t.flags,a,n,{interactiveOnly:!0}),I=await ed("selector_resolve",()=>pp(v.nodes,y,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:d});if(!I||!I.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:pm(y,I?.diagnostics??[],{unique:!0})}};let b=fl(v.nodes,I.node),A=fi(b.rect);if(!A)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Selector ${I.selector.raw} resolved to invalid bounds`}};let{x:S,y:N}=A,_=pw(b,l.device.platform,{action:h}),x=cQ(b,v.nodes);return md({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"press",interactionPositionals:[String(S),String(N)],outPath:t.flags?.out,afterDispatch:async()=>{await mw(l,I.selector.raw)},buildPayloads:e=>{let t=ml({data:e,fallbackX:S,fallbackY:N,referenceFrame:mf(v.nodes),extra:{selector:I.selector.raw,selectorChain:_,refLabel:x,...f}});return{result:t,responseData:t}}})}async function mw(e,t){if("android"!==e.device.platform||!e.appBundleId)return;let r=await nJ(e.device),a=r.package?.trim();if(a&&a!==e.appBundleId){var n;if("com.android.settings"===(n=a)||"com.android.systemui"===n||"com.google.android.permissioncontroller"===n||n.includes("launcher"))throw new W("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${a}. The tap likely escaped the app.`,{expectedPackage:e.appBundleId,foregroundPackage:a,activity:r.activity,hint:"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."})}}async function mg(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r);if(l){let e=mm(l,"fill");if(e)return e}if(l&&!dI("fill",l.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"fill is not supported on this device"}};if(t.positionals?.[0]?.startsWith("@")){if(!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let e=s("fill",t.flags);if(e)return e;let r=t.positionals.length>=3?t.positionals[1]:"",d=t.positionals.length>=3?t.positionals.slice(2).join(" "):t.positionals.slice(1).join(" ");if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after ref"}};let u=await fs({session:l,refInput:t.positionals[0],fallbackLabel:r,commandLabel:"fill",promoteToHittableAncestor:!1,invalidRefMessage:"fill requires a ref like @e2",missingBoundsMessage:`Ref ${t.positionals[0]} not found or has no bounds`,invalidBoundsMessage:`Ref ${t.positionals[0]} not found or has invalid bounds`,reqFlags:t.flags,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o});if(!u.ok)return u.response;let{ref:c,node:p,snapshotNodes:f,point:m}=u.target,h=p.type??"",w=h&&!c3(h,l.device.platform)?`fill target ${t.positionals[0]} resolved to "${h}", attempting fill anyway.`:void 0,g=cQ(p,f),y=pw(p,l.device.platform,{action:"fill"}),{x:v,y:I}=m;return md({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"fill",interactionPositionals:[String(v),String(I),d],outPath:t.flags?.out,buildPayloads:e=>{let t=ml({data:e,fallbackX:v,fallbackY:I,referenceFrame:mf(f),extra:{ref:c,refLabel:g,selectorChain:y,text:d}}),r={...e??{ref:c,x:v,y:I}};return w&&(t.warning=w,r.warning=w),{result:t,responseData:r}}})}if(!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let d=pt(t.positionals??[],{preferTrailingValue:!0});if(d){if(0===d.rest.length)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let e=d.rest.join(" ").trim();if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let r=c7(d.selectorExpression),o=await i(l,t.flags,a,n,{interactiveOnly:!0}),s=await ed("selector_resolve",()=>pp(o.nodes,r,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:t.command});if(!s||!s.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:pm(r,s?.diagnostics??[],{unique:!0})}};let u=s.node,c=s.node.rect,p=u.type??"",f=p&&!c3(p,l.device.platform)?`fill target ${s.selector.raw} resolved to "${p}", attempting fill anyway.`:void 0,{x:m,y:h}=eS(c),w=pw(u,l.device.platform,{action:"fill"});return md({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"fill",interactionPositionals:[String(m),String(h),e],outPath:t.flags?.out,buildPayloads:t=>{let r=ml({data:t,fallbackX:m,fallbackY:h,referenceFrame:mf(o.nodes),extra:{text:e,selector:s.selector.raw,selectorChain:w,refLabel:cQ(u,o.nodes)}});return f&&(r.warning=f),{result:r,responseData:r}}})}return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires x y text, @ref text, or selector text"}}}async function my(e){switch(e.req.command){case"press":case"click":return await mh(e);case"fill":return await mg(e);default:return null}}let mv=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function mI(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,a]of mv)void 0!==e[r]&&t.push(a);return t}(t);return 0===r.length?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} @ref does not support ${r.join(", ")}.`}}}async function mb(e,t,r,a,n){let i={...t??{},snapshotInteractiveOnly:n.interactiveOnly,snapshotCompact:n.interactiveOnly},o=a(i,e.appBundleId,e.trace?.outPath),{snapshot:s}=await pF({device:e.device,session:e,flags:i,outPath:i.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}async function mA(e){let{command:t,selectorExpression:r,session:a,flags:n,sessionStore:i,contextFromFlags:o,interactiveOnly:s,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}=e,c=c7(r),p=await mb(a,n,i,o,{interactiveOnly:s}),f=await ed("selector_resolve",()=>pp(p.nodes,c,{platform:a.device.platform,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}),{command:t});return f&&(!l||f.node.rect)?{ok:!0,chain:c,snapshot:p,resolved:f}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:pm(c,f?.diagnostics??[],{unique:d})}}}}async function mS(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n}=e,i=t.positionals?.[0];if("text"!==i&&"attrs"!==i)return{ok:!1,error:{code:"INVALID_ARGS",message:"get only supports text or attrs"}};let o=a.get(r);if(!o)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!dI("get",o.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"get is not supported on this device"}};let s=t.positionals?.[1]??"";if(s.startsWith("@")){let e=mI("get",t.flags);if(e)return e;let r=fn({session:o,refInput:s,fallbackLabel:t.positionals.length>2?t.positionals.slice(2).join(" ").trim():"",requireRect:!1,invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${s} not found`});if(!r.ok)return r.response;let{ref:l,node:d}=r.target,u=pw(d,o.device.platform,{action:"get"});if("attrs"===i)return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{ref:l,selectorChain:u}}),{ok:!0,data:{ref:l,node:d}};let c=await fu({device:o.device,node:d,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:n});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{ref:l,text:c,refLabel:mN(c),selectorChain:u}}),{ok:!0,data:{ref:l,text:c,node:d}}}let l=t.positionals.slice(1).join(" ").trim();if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"get requires @ref or selector expression"}};let d=await mA({command:t.command,selectorExpression:l,session:o,flags:t.flags,sessionStore:a,contextFromFlags:n,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:"text"===i});if(!d.ok)return d.response;let{resolved:u}=d,c=u.node,p=pw(c,o.device.platform,{action:"get"});if("attrs"===i)return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{selector:u.selector.raw,selectorChain:p}}),{ok:!0,data:{selector:u.selector.raw,node:c}};let f=await fu({device:o.device,node:c,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:n});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{text:f,refLabel:mN(f),selector:u.selector.raw,selectorChain:p}}),{ok:!0,data:{selector:u.selector.raw,text:f,node:c}}}function mN(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function m_(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function mx(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n}=e,i=(t.positionals?.[0]??"").toLowerCase();if(!["visible","hidden","exists","editable","selected","text"].includes(i))return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires predicate: visible|hidden|exists|editable|selected|text"}};let o=a.get(r);if(!o)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!dI("is",o.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"is is not supported on this device"}};let{split:s}=pr(t.positionals);if(!s)return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires a selector expression"}};let l=s.rest.join(" ").trim();if("text"===i&&!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"is text requires expected text value"}};if("text"!==i&&s.rest.length>0)return{ok:!1,error:{code:"INVALID_ARGS",message:`is ${i} does not accept trailing values`}};let d=c7(s.selectorExpression);if("exists"===i){let e=pf((await mb(o,t.flags,a,n,{interactiveOnly:!1})).nodes,d,{platform:o.device.platform});return e?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:i,selector:e.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,matches:e.matches}}),{ok:!0,data:{predicate:i,pass:!0,selector:e.selector.raw,matches:e.matches}}):{ok:!1,error:{code:"COMMAND_FAILED",message:pm(d,[],{unique:!1})}}}let u=await mA({command:"is",selectorExpression:s.selectorExpression,session:o,flags:t.flags,sessionStore:a,contextFromFlags:n,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!u.ok)return u.response;let{resolved:c}=u,p=function(e){let{predicate:t,node:r,nodes:a,expectedText:n,platform:i}=e,o=c5(r),s=pd(r,i),l=!0===r.selected,d="text"===t?pl(r):function(e,t){if(!0===e.hittable)return!0;if(m_(e.rect))return k(e,t);if(e.rect)return!1;let r=function(e,t){let r=new Map(t.map(e=>[e.index,e])),a=e,n=new Set;for(;"number"==typeof a.parentIndex&&!n.has(a.index);){n.add(a.index);let e=r.get(a.parentIndex);if(!e)break;if(function(e){let t=c2(e.type??"");return!(t.includes("application")||t.includes("window")||t.includes("scrollview")||t.includes("tableview")||t.includes("collectionview"))&&"table"!==t&&"list"!==t&&"listview"!==t&&(!0===e.hittable||m_(e.rect))}(e))return e;a=e}return null}(e,t);return!!r&&(!0===r.hittable||!!m_(r.rect)&&k(r,t))}(r,a),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=s;break;case"selected":u=l;break;case"text":u=o===(n??"")}let c="text"===t?`expected="${n??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:i,node:c.node,nodes:u.snapshot.nodes,expectedText:l,platform:o.device.platform});return p.pass?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:i,selector:c.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,text:"text"===i?p.actualText:void 0}}),{ok:!0,data:{predicate:i,pass:!0,selector:c.selector.raw}}):{ok:!1,error:{code:"COMMAND_FAILED",message:`is ${i} failed for selector ${c.selector.raw}: ${p.details}`}}}function mD(e,t){var r,a;let n=Math.max(1,t.height),i=Math.max(1,t.width),o=t.y,s=t.y+n,l=t.x,d=t.x+i,u=s-.25*n,c=Math.max(8,.1*i),p=e.y+e.height/2,f=e.x+e.width/2;if(p>=o+.25*n&&p<=u)return null;let m=Math.round((r=f,a=l+c,Math.min(d-c,Math.max(a,r)))),h=Math.round(o+.86*n),w=Math.round(o+.14*n);return p>u?{x:m,startY:h,endY:w,direction:"down"}:{x:m,startY:w,endY:h,direction:"up"}}async function mM(e){let t,r,{req:a,sessionName:n,sessionStore:i,contextFromFlags:o}=e,s=i.get(n);if(!s)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!dI("scrollintoview",s.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"scrollintoview is not supported on this device"}};let l=a.positionals?.[0]??"";if(!l.startsWith("@"))return null;let d=mI("scrollintoview",a.flags);if(d)return d;let u=a.positionals&&a.positionals.length>1?a.positionals.slice(1).join(" ").trim():"",c=function(e,t,r){let a=fn({session:e,refInput:t,fallbackLabel:r,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${t} not found or has no bounds`});if(!a.ok){let{response:e}=a;return e.ok||"COMMAND_FAILED"!==e.error.code?{ok:!1,response:e}:{ok:!1,response:mE(t,0,{message:e.error.message})}}return mk(t,0,a.target)}(s,l,u);if(!c.ok)return c.response;let{ref:p}=c.state,{currentRef:f,node:m,snapshotNodes:h,viewportRect:w}=c.state,g=cQ(m,h),y=pw(m,s.device.platform,{action:"get"}),v=u||g||m.label||"";if(!mD(m.rect,w)){let e=mO({ref:p,currentRef:f,attempts:0,alreadyVisible:!0});return i.recordAction(s,{command:a.command,positionals:a.positionals??[],flags:a.flags??{},result:{refLabel:g,selectorChain:y,...e}}),{ok:!0,data:e}}let I=a.flags?.maxScrolls??48,b=0,A=0,S=B(m.rect,w);for(;b<I;){let e=mD(m.rect,w);if(!e)break;t=e.direction,r=await l7(s.device,"swipe",[String(e.x),String(e.startY),String(e.x),String(e.endY),"16"],a.flags?.out,{...o(a.flags,s.appBundleId,s.trace?.outPath),count:1,pauseMs:0,pattern:"one-way"}),b+=1,await mb(s,a.flags,i,o,{interactiveOnly:!0});let n=function(e){let{session:t,targetInput:r,fallbackLabel:a,attempts:n,ref:i,selectorChain:o,platform:s}=e;if(t.snapshot){let e=function(e,t,r,a){for(let r of t){let t=pp(e,c7(r),{platform:a,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(t?.node.rect)return t.node}return r?cZ(e,r):null}(t.snapshot.nodes,o,a,s);if(e)return mk(r,n,{ref:i,node:e,snapshotNodes:t.snapshot.nodes},{currentRef:e.ref})}let l=fn({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${r} not found or has no bounds`});if(!l.ok){let{response:e}=l;return e.ok||"COMMAND_FAILED"!==e.error.code?{ok:!1,response:e}:{ok:!1,response:mE(r,n,{message:`scrollintoview lost track of ${r} after ${n} scroll${1===n?"":"s"}`,ref:i})}}return mk(r,n,l.target,{ref:i,currentRef:l.target.node.ref,missingBoundsMessage:`scrollintoview lost bounds for ${r} after ${n} scroll${1===n?"":"s"}`})}({session:s,targetInput:l,fallbackLabel:v,attempts:b,ref:p,selectorChain:y,platform:s.device.platform});if(!n.ok)return n.response;({currentRef:f,node:m,snapshotNodes:h,viewportRect:w}=n.state);let d=B(m.rect,w);if(0===d)break;if(d>=S){if((A+=1)>=2)return mE(l,b,{message:`scrollintoview made no progress toward ${l} after ${b} scroll${1===b?"":"s"}`,ref:p,stalled:!0})}else A=0;S=d}if(B(m.rect,w)>0)return mE(l,b,{message:`scrollintoview reached --max-scrolls=${I} before ${l} entered view`,ref:p,maxScrolls:I});let N=mO({data:r,ref:p,currentRef:f,attempts:b,direction:t});return i.recordAction(s,{command:a.command,positionals:a.positionals??[],flags:a.flags??{},result:{refLabel:g,selectorChain:y,...N}}),{ok:!0,data:N}}function mk(e,t,r,a={}){let{ref:n,currentRef:i,missingBoundsMessage:o}=a,s=r.node;if(!s.rect)return{ok:!1,response:mE(e,t,{message:o??`Ref ${e} not found or has no bounds`,ref:n??r.ref})};let l=ee(r.snapshotNodes,s.rect);return l?{ok:!0,state:{ref:n??r.ref,currentRef:i??r.node.ref,node:s,snapshotNodes:r.snapshotNodes,viewportRect:l}}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`scrollintoview could not infer viewport for ${e}`}}}}function mE(e,t,r={}){let{message:a,...n}=r;return{ok:!1,error:{code:"COMMAND_FAILED",message:"string"==typeof a?a:`scrollintoview could not find ${e}`,details:{reason:"not_found",attempts:t,...n}}}}function mO(e){let{data:t,ref:r,currentRef:a,attempts:n,alreadyVisible:i,direction:o}=e;return{...t??{},ref:r,currentRef:a,attempts:n,...i?{alreadyVisible:i}:{},...o?{direction:o}:{},...ec(`Scrolled into view: @${r}`)}}async function mL(e){let t=await my({...e,captureSnapshotForSession:mb,resolveRefTarget:fn,refSnapshotFlagGuardResponse:mI});if(t)return t;switch(e.req.command){case"get":return await mS(e);case"is":return await mx(e);case"scrollintoview":return await mM(e);default:return null}}function mC(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function mP(e){let{req:t,leaseRegistry:r}=e,a=mC(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}function mR(e,t){if(!t)return[];let r=[],a=e.device,n=t.platform;if(n&&!t_(a.platform,n)&&r.push({key:"platform",value:t.platform}),t.target&&t.target!==(a.target??"mobile")&&r.push({key:"target",value:t.target}),t.udid&&("ios"!==a.platform||t.udid!==a.id)&&r.push({key:"udid",value:t.udid}),t.serial&&("android"!==a.platform||t.serial!==a.id)&&r.push({key:"serial",value:t.serial}),t.device&&t.device.trim().toLowerCase()!==a.name.trim().toLowerCase()&&r.push({key:"device",value:t.device}),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),n=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==n)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=e9(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function mT(e){return`${function(e){switch(e){case"iosSimulatorDeviceSet":return"--ios-simulator-device-set";case"androidDeviceAllowlist":return"--android-device-allowlist";default:return`--${e}`}}(e.key)}=${e.value}`}let m$=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"],mF=/\bis(?:n't| not)\s+responding\b/i,mU=/^close app$/i;async function mG(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await mV(t),r=function(e){if(mH(e))return e.find(e=>{let t=mq(e);return t.length>0&&mU.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:n}=eS(r.rect),i=await $("adb",aK(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(n))]),{allowFailure:!0});if(0!==i.exitCode)return ep({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:i.exitCode,stdout:i.stdout.trim(),stderr:i.stderr.trim()}}),"failed";if(!await mB(t))return ep({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await nX(t.device,t.appBundleId),!await mj(t,t.appBundleId)))return ep({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return ep({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:n}}),"recovered"}catch(e){return ep({level:"warn",phase:"android_blocking_dialog_recovery_failed",data:{session:t.name,deviceId:t.device.id,error:e instanceof Error?e.message:String(e)}}),"failed"}}async function mV(e){return e_(c1((await ib(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function mB(e){for(let t=0;t<12;t+=1){if(!mH(await mV(e)))return!0;await mW(500)}return!mH(await mV(e))}async function mj(e,t){for(let r=0;r<12;r+=1){if((await nJ(e.device)).package===t)return!0;await mW(500)}return(await nJ(e.device)).package===t}function mq(e){let t=[e.label,e.identifier];return"string"==typeof e.value&&e.value.trim().length>0&&t.push(e.value),t.filter(e=>"string"==typeof e&&e.trim().length>0).join(" ").trim()}function mH(e){return e.some(e=>{let t=mq(e);return t.length>0&&mF.test(t)})}function mW(e){return new Promise(t=>setTimeout(t,e))}let mz=[255,59,48,255],mJ=[255,214,10,255],mK=[0,0,0,255],mX={e:["01110","10000","11110","10000","10000","10001","01110"],0:["01110","10001","10011","10101","11001","10001","01110"],1:["00100","01100","00100","00100","00100","00100","01110"],2:["01110","10001","00001","00010","00100","01000","11111"],3:["11110","00001","00001","01110","00001","00001","11110"],4:["00010","00110","01010","10010","11111","00010","00010"],5:["11111","10000","10000","11110","00001","00001","11110"],6:["01110","10000","10000","11110","10001","10001","01110"],7:["11111","00001","00010","00100","01000","01000","01000"],8:["01110","10001","10001","01110","10001","10001","01110"],9:["01110","10001","10001","01111","00001","00001","01110"]};async function mY(e){let t=D(await d.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let n=function(e){let t=null;for(let r of e)mQ(r)&&m4(r.rect)&&(!t||m5(r.rect)>m5(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,n=-1/0;for(let i of e)i.rect&&m4(i.rect)&&(t=Math.min(t,i.rect.x),r=Math.min(r,i.rect.y),a=Math.max(a,i.rect.x+i.rect.width),n=Math.max(n,i.rect.y+i.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||n<=r?null:{x:t,y:r,width:a-t,height:n-r}}(e.filter(e=>{var t;return m4(e.rect)&&!("image"===c2((t=e).type??"")&&!m0(t.label))}))}(e.nodes),i=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(m1)||m2(e.identifier);return mZ(e)?t:t&&function(e){let t=c2(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let o=function(e,t){if(function(e){return mZ(e)&&!mQ(e)}(t)&&m4(t.rect))return t;let r=function(e,t){let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){;a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(mZ(t)&&!mQ(t)&&m4(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&m4(r.rect))return r;if(t.hittable&&m4(t.rect)&&!mQ(t))return t;let a=c4(e,t);return a?.rect&&m4(a.rect)&&!mQ(a)?a:null}(e.nodes,a);if(!o?.rect||!m4(o.rect))continue;let s=function(e,t,r){let a=m3(e);if(e.ref!==t.ref&&a)return a;let n=function(e,t){let r=null;for(let a of t){if(a.ref===e.ref||!function(e,t,r){let a=e;for(;void 0!==a.parentIndex;){let e=r[a.parentIndex];if(!e)break;if(e.ref===t.ref)return!0;a=e}return!1}(a,e,t))continue;let n=m3(a);if(!n)continue;let i=function(e){let t=0;return c2(e.type??"").includes("text")&&(t+=2),m1(e.label)&&(t+=2),m1(e.value)&&(t+=1),t}(a);(!r||i>r.score)&&(r={label:n,score:i})}return r?.label}(t,r);return n||(m3(t)??cQ(t,r))}(a,o,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),mZ(t)&&(a+=3),mZ(e)&&(a+=2),r&&(a+=2),m2(t.identifier)&&(a+=1),m0(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return m9({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,a);let n=r/e.width,i=a/e.height;return m9({x:Math.round((t.x-e.x)*n),y:Math.round((t.y-e.y)*i),width:Math.max(1,Math.round(t.width*n)),height:Math.max(1,Math.round(t.height*i))},r,a)}(n,o.rect,t,r);if(!m4(d))continue;let u=i.get(o.ref);(!u||l>u.score)&&i.set(o.ref,{ref:o.ref,label:s,rect:o.rect,overlayRect:d,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>m5(e.overlayRect)-m5(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(m8(e.overlayRect,r.overlayRect)||m8(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}m5(r.overlayRect)<m5(t[e].overlayRect)&&(t[e]=r)}return t})([...i.values()]).sort((e,t)=>{if(t.score!==e.score)return t.score-e.score;let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:m6(e.ref,t.ref)}).slice(0,a.maxRefs??24).sort((e,t)=>{let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:m6(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:eS(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,n;(function(e,t,r){for(let a=0;a<2;a+=1)he(e,t.x,t.x+t.width-1,t.y+a,r),he(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),ht(e,t.x+a,t.y,t.y+t.height-1,r),ht(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(n=e).overlayRect,mz),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),n=m7(t.x,0,Math.max(0,e.width-a)),i=t.y-11-2,o=i>=0?i:m7(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,n){for(let i=0;i<11;i+=1)for(let o=0;o<a;o+=1)hr(e,t+o,r+i,n)})(e,n,o,a,mJ),function(e,t,r,a,n){let i=t;for(let t of a.toLowerCase()){let a=mX[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&hr(e,i+o,r+t,n);i+=6}}(e,n+3,o+2,r,mK)}(a,n.overlayRect,n.ref)}return await d.writeFile(e.screenshotPath,_.sync.write(t)),r}function mZ(e){let t=[e.type,e.role,e.subrole].map(e=>c2(e??"")).join(" ");return t.includes("button")||t.includes("link")||t.includes("menu")||t.includes("tab")||t.includes("textfield")||t.includes("searchfield")||t.includes("securetextfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("cell")}function mQ(e){let t=[e.type,e.role,e.subrole].map(e=>c2(e??"")).join(" ");return t.includes("application")||t.includes("window")}function m0(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function m1(e){var t;let r;return!!m0(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function m2(e){var t;return"string"==typeof e&&!!m1(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function m3(e){let t=[e.label,e.value].find(m1);return t?t.trim():m2(e.identifier)?e.identifier.trim():void 0}function m4(e){return!!(e&&e.width>0&&e.height>0)}function m5(e){return e.width*e.height}function m8(e,t){return t.x>=e.x&&t.y>=e.y&&t.x+t.width<=e.x+e.width&&t.y+t.height<=e.y+e.height}function m6(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function m9(e,t,r){let a=m7(e.x,0,Math.max(0,t-1)),n=m7(e.y,0,Math.max(0,r-1)),i=Math.max(1,t-a),o=Math.max(1,r-n);return{x:a,y:n,width:m7(e.width,1,i),height:m7(e.height,1,o)}}function m7(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function he(e,t,r,a,n){for(let i=t;i<=r;i+=1)hr(e,i,a,n)}function ht(e,t,r,a,n){for(let i=r;i<=a;i+=1)hr(e,t,i,n)}function hr(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let n=(e.width*r+t)*4;e.data[n]=a[0],e.data[n+1]=a[1],e.data[n+2]=a[2],e.data[n+3]=a[3]}let ha=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),hn=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),hi=new Set(hn),ho=new Map;function hs(e,t,r,a){let n=es().requestId;return{...db(e,t,r,a,n),requestId:n}}async function hl(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||dG(e.flags))try{let t=await l9(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function hd(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,leaseRegistry:i,invoke:o,contextFromFlags:s}=e,l=await mP({req:t,leaseRegistry:i});if(l)return l;let d=await pP({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o});if(d)return d;let u=await p9({req:t,sessionName:r,logPath:a,sessionStore:n});if(u)return u;let c=await f3({req:t,sessionName:r,sessionStore:n,logPath:a});if(c)return c;let p=await fc({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o});if(p)return p;let f=await mL({req:t,sessionName:r,sessionStore:n,contextFromFlags:s});return f||null}async function hu(e){var t;let r,a,n,i,o,s,l,{req:d,session:u,logPath:c,sessionStore:p}=e,f=d.command;if(!dI(f,u.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${f} is not supported on this device`}};if("android"===u.device.platform&&u.recording&&"record"!==f&&"failed"===await mG({session:u}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:m,resolvedOut:h,recordedPositionals:w,recordedFlags:g}=(r=(t=d).command,a=t.positionals??[],n=t.flags?.out,i="screenshot"===r&&a[0]?[rC.expandHome(a[0],t.meta?.cwd),...a.slice(1)]:a,o="screenshot"===r&&n?rC.expandHome(n,t.meta?.cwd):n,s="screenshot"===r?i:a,l="screenshot"===r&&o?{...t.flags??{},out:o}:t.flags??{},{resolvedPositionals:i,resolvedOut:o,recordedPositionals:s,recordedFlags:l}),y=Date.now(),v={...hs(c,d.flags,u.appBundleId,u.trace?.outPath),surface:u.surface},I=await l7(u.device,f,m,h,{...v});return"screenshot"===f&&d.flags?.overlayRefs&&"string"==typeof I?.path&&await hc(u,I,c),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:n,recordedPositionals:i,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let n=f8(e.snapshot),i={...a??{}},o=mr(i.direction)??mr(r[0]);if(!o)return a;let s=ma(i.amount)??ma(r[1]),l=ma(i.pixels),d=mo(i,[]),u=ma(i.referenceWidth),c=ma(i.referenceHeight),p=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:n??f9;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...i,x1:d.x1,y1:d.y1,x2:d.x2,y2:d.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==l?{pixels:l}:{},referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight,durationMs:250};let f=is({direction:o,amount:s,pixels:l,referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight});return{...i,x1:f.x1,y1:f.y1,x2:f.x2,y2:f.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==f.pixels?{pixels:f.pixels}:{},referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight,durationMs:250}}(t,a,n,s);f7(t,a,n,c,u,l,d),r.recordAction(t,{command:a,positionals:i,flags:o,result:s??{}})}({session:u,sessionStore:p,command:f,resolvedPositionals:m,recordedPositionals:w,recordedFlags:g,data:I,actionStartedAt:y,actionFinishedAt:Date.now(),flags:d.flags??{}}),uS(f)&&uI(u,f),{ok:!0,data:I??{}}}async function hc(e,t,r){let a=pj(await pU({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let n=await mY({screenshotPath:t.path,snapshot:a});t.overlayRefs=n}function hp(e){s.existsSync(e)&&s.unlinkSync(e)}function hf(e){if(!s.existsSync(e))return null;try{let t=JSON.parse(s.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function hm(e){let t=hf(e);if(!t||t.pid===process.pid)try{s.existsSync(e)&&s.unlinkSync(e)}catch{}}function hh(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:hw,infoPath:hg,lockPath:hy,logPath:hv,sessionsDir:hI}=eI(process.env.AGENT_DEVICE_STATE_DIR),hb=eA(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var hA=hI;if(s.existsSync(hA))for(let e of s.readdirSync(hA,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=p.join(hA,e.name,rP);if(s.existsSync(t))try{let e=rR(s.readFileSync(t,"utf8"));if(e&&function(e){let t,r=ey(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=M(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{r$(t)}}let hS=new rC(hI),hN=new aj({maxActiveSimulatorLeases:hh(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:hh(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:hh(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:hh(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),h_=eo(),hx=i.randomBytes(24).toString("hex"),hD=ey(process.pid)??void 0,hM=X(),hk=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:n,trackDownloadableArtifact:i}=e;async function o(e){let s=!!(e.meta?.debug||e.flags?.verbose);return await ev({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:s,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:ea(new W("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=en(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=O(r);if(r&&!a)throw new W("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new W("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let n=e.session||"default";return n.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${n}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);ep({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let s=r.command,l=mC(r);hn.has(s)||r.meta?.sessionIsolation!=="tenant"||n.assertLeaseAdmission({tenantId:l.tenantId,runId:l.runId,leaseId:l.leaseId,backend:l.leaseBackend});let d=function(e,t){var r;let a,n=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==n||t.has(n))return n;let i=t.toArray();return 1===i.length?i[0].name:n}(r,a),u=hi.has(s)?null:await hl(r,d,a),c=async()=>{let e=a.get(d);e&&(!function(e){var t,r;let a,n=e.recording;if(!n||"ios"!==e.device.platform)return;let i=(t=e.device.id,(a=re.get(t))?{sessionId:a.sessionId,alive:!!(r=a.child.pid)&&eg(r)}:null);if(!n.runnerSessionId){i?.alive&&(n.runnerSessionId=i.sessionId);return}if(!i?.alive){n.invalidatedReason??="iOS runner session exited during recording";return}i.sessionId!==n.runnerSessionId&&(n.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(d,e));let l=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},n=t?mR(t,a):function(e,t,r){var a,n;let i=[];if(void 0!==e.platform&&t&&(a=e.platform,n=t,a&&n&&a!==n&&("apple"===a?!tN(n):"apple"!==n||!tN(a)))&&i.push({key:"platform",value:e.platform}),"open"===r)return i;for(let t of m$){let r=e[t];"string"==typeof r&&r.trim().length>0&&i.push({key:t,value:r})}return i}(a,e.meta?.lockPlatform,e.command);if(0===n.length)return!t&&e.meta?.lockPlatform&&void 0===a.platform&&(a.platform=e.meta.lockPlatform),{...e,flags:a};if("strip"===r)return t?(function(e,t){for(let r of t)delete e[r.key]}(a,n),a.platform=t.device.platform):function(e,t){for(let t of m$)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new W("INVALID_ARGS",`${e.command} cannot override session lock policy with ${n.map(mT).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),u=e=>(function(e,t,r){let a=es();if(!t.ok){ep({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=eb({force:!0})??void 0;return{ok:!1,error:ea(new W(t.error.code,t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return ep({level:"info",phase:"request_success"}),eb(),{ok:!0,data:function(e,t,r){var a,n;let i;if(!t)return t;let o=(a=e,n=t,i=Array.isArray(n.artifacts)?[...n.artifacts]:[],"screenshot"!==a.command||i.some(e=>e?.field==="path")||"string"!=typeof n.path||i.push({field:"path",path:n.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:p.basename(a.meta?.clientArtifactPaths?.path??n.path)}),i.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===o.length?t:{...t,artifacts:o.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(l,e,i);if(e?.recording?.invalidatedReason&&"record"!==s&&"close"!==s)return u({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||l.meta?.lockPolicy||ha.has(s)||function(e,t){let r=mR(e,t);if(0!==r.length){var a;let t,n,i;throw new W("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,n=a.device.name.trim(),i=a.device.id,`${t} device "${n}" (${i})`)} and cannot be used with ${r.map(mT).join(", ")}. Use a different --session name or close this session first.`)}}(e,l.flags);let c=await hd({req:l,sessionName:d,logPath:t,sessionStore:a,leaseRegistry:n,invoke:o,contextFromFlags:(e,r,n)=>({...hs(t,e,r,n),surface:a.get(d)?.surface})});if(c)return u(c);let f=a.get(d);if(!f)return u({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await hu({req:l,session:f,sessionName:d,logPath:t,sessionStore:a});return u(m)};if(!u)return await c();return await tS(ho,u,c)}catch(r){ep({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=es(),t=eb({force:!0})??void 0;return{ok:!1,error:ea(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return o}({logPath:hv,token:hx,sessionStore:hS,leaseRegistry:hN,trackDownloadableArtifact:function(e){let t=i.randomUUID(),r=setTimeout(()=>{af(t)},9e5);return r.unref(),ap.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){s.existsSync(e)||s.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return s.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let i=hf(t);if(i?.pid&&i.pid!==process.pid&&L(i.pid,i.processStartTime))return!1;try{s.unlinkSync(t)}catch{}return n()}(hw,hy,{pid:process.pid,version:h_,startedAt:Date.now(),processStartTime:hD})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===hb||"dual"===hb){let t=f.createServer(e=>{let t="",r=0,a=new Set,n=!1,i=()=>{if(!n&&0!==r){for(let e of(n=!0,a))eJ(e);ep({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await rs(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){ep({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:r}})}})()}};e.setEncoding("utf8"),e.on("close",i),e.on("error",i),e.on("data",async n=>{let i=(t+=n).indexOf("\n");for(;-1!==i;){let n,o,s=t.slice(0,i).trim();if(t=t.slice(i+1),0===s.length){i=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eW(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),ez(o),eX(o))throw eZ();n=await hk(e)}catch(e){n={ok:!1,error:ea(e)}}finally{r-=1,o&&(a.delete(o),eK(o))}e.destroyed||e.write(`${JSON.stringify(n)}
70
- `),i=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new W("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===hb||"dual"===hb){let e=await aT({handleRequest:hk,token:hx});r.push(e),t=await new Promise((t,r)=>{e.once("error",r),e.listen(0,"127.0.0.1",()=>{e.off("error",r);let a=e.address();"object"==typeof a&&a?.port?t(a.port):r(new W("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:hx,version:h_,codeSignature:hM,processStartTime:hD},s.existsSync(hw)||s.mkdirSync(hw,{recursive:!0}),s.writeFileSync(hv,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",s.writeFileSync(hg,JSON.stringify({port:a.socketPort,httpPort:a.httpPort,transport:n,token:a.token,pid:process.pid,version:a.version,codeSignature:a.codeSignature,processStartTime:a.processStartTime,stateDir:hw},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
68
+ `.trim();async function fb(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,i=0;for(let t=0;t<n;t+=1){let t=0;try{t=s.statSync(e).size}catch{t=0}if(t>0&&t===r){if((i+=1)>=2)return}else i=0;r=t,await new Promise(e=>setTimeout(e,a))}}async function fA(e){try{var t,r;let a,n=await F("swift",["-",e],{stdin:fI,allowFailure:!0,timeoutMs:1e4});if(0===n.exitCode)return!0;if(t=n.stderr,r=n.stdout,a=`${t}
69
+ ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return fN(e);return!1}catch(t){if(t instanceof O&&"TOOL_MISSING"===t.code)return fN(e);throw t}}async function fS(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await fA(e))return;await new Promise(e=>setTimeout(e,r))}}function fN(e){try{let t=s.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=s.openSync(e,"r");try{let e=s.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>s.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),i=e.toString("latin1",4,8);if(a.push(i),1===n){let e=Buffer.alloc(8);if(8>s.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{s.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function f_(e){let t=p.parse(e);return p.join(t.dir,`${t.name}.gesture-telemetry.json`)}function fx(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function fD(e){var t,r,a;let n,i,{recording:o,trimStartMs:l}=e,d=(n=f_((t={videoPath:o.outPath,events:o.gestureEvents,trimStartMs:l}).videoPath),i={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?fx(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):fx(r))},s.writeFileSync(n,JSON.stringify(i,null,2)),n);return o.telemetryPath=d,d}function fM(e){let t=p.dirname(w(import.meta.url)),r=[w(new URL(`./${e}`,import.meta.url)),p.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),p.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),p.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(s.existsSync(e))return e;throw new O("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure ios-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}function fk(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}async function fE(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await fb(t),await fS(t);let i=s.mkdtempSync(p.join(u.tmpdir(),"agent-device-record-overlay-")),o=p.join(i,`input${p.extname(t)||".mp4"}`),l=p.join(i,p.basename(t)),d=p.join(i,"home"),c=p.join(i,"module-cache");s.copyFileSync(t,o),s.mkdirSync(d,{recursive:!0}),s.mkdirSync(c,{recursive:!0});try{await F("xcrun",["swift",r,"--input",o,"--output",l,...a],{timeoutMs:12e4,env:{...process.env,HOME:d,CLANG_MODULE_CACHE_PATH:c}}),await fS(l),s.copyFileSync(l,t)}catch(a){let e=a instanceof O?a:new O("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new O("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{s.rmSync(i,{recursive:!0,force:!0})}}async function fO(e){let{videoPath:t,trimStartMs:r}=e;r>0&&await fE({videoPath:t,scriptPath:a??=fM("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(r)],commandDescription:"Failed to trim the start of the iOS recording"})}async function fL(e){let{videoPath:t,telemetryPath:a,targetLabel:n="recording"}=e;await fE({videoPath:t,scriptPath:r??=fM("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${n}`})}function fC(e){return e instanceof Error?e.message:String(e)}function fP(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function fR(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","ps","-o","pid=","-p",r],{allowFailure:!0});return 0===a.exitCode&&a.stdout.split(/\s+/).map(e=>e.trim()).includes(r)}async function fT(e,t,r){for(let a=0;a<40;a+=1){if(!await fR(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await fR(e,t,r)}async function f$(e,t,r){let a,n=0;for(let i=0;i<20;i+=1){let i=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===i.exitCode?i.stdout.trim():"";if(o.length>0&&o===a){if((n+=1)>=4)return}else n=0;a=o,await new Promise(e=>setTimeout(e,250))}}async function fF(e,t,r,a){for(let n=0;n<8;n+=1){let i=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===i.exitCode?Number(i.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await fR(e,t,a))break;if(n+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function fU(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:i}=e;for(let e=0;e<2;e+=1){try{s.rmSync(i,{force:!0})}catch{}let o=await r.runCmd("adb",["-s",a,"pull",n,i],{allowFailure:!0});if(0!==o.exitCode)t=fP(o,"adb pull");else{await r.waitForStableFile(i,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(i);if(U({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:i,attempt:e+1,fileSize:(()=>{try{return s.statSync(i).size}catch{return 0}})(),playable:t}}),t)return;U({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:i,attempt:e+1}})}e<1&&await new Promise(e=>setTimeout(e,750))}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function fG(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function fV(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return U({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:t,remotePid:r,exitCode:a.exitCode,stdout:a.stdout.trim(),stderr:a.stderr.trim()}}),!(0!==a.exitCode&&await fR(e,t,r))&&await fT(e,t,r)}async function fB(e){var t;let r,{deps:a,device:n,recordingBase:i}=e,o="failed to start recording: Android screenrecord did not begin producing frames";for(let e of(t=Date.now(),r=`agent-device-recording-${t}.mp4`,[`/sdcard/${r}`,`/data/local/tmp/${r}`])){let t=await a.runCmd("adb",["-s",n.id,"shell",`screenrecord ${e} >/dev/null 2>&1 & echo $!`],{allowFailure:!0});if(0!==t.exitCode){o=`failed to start recording: ${fP(t,"adb shell screenrecord")}`;continue}let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!r){o="failed to start recording: adb did not return a valid Android screenrecord pid",await fG(a,n.id,e);continue}if(U({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:r}}),await fF(a,n.id,e,r))return{platform:"android",remotePath:e,remotePid:r,...i,startedAt:Date.now()};o="failed to start recording: Android screenrecord did not begin producing frames",await fV(a,n.id,r),await fG(a,n.id,e)}return{ok:!1,error:{code:"COMMAND_FAILED",message:o}}}async function fj(e){let t,r,{deps:a,device:n,recording:i}=e;U({level:"debug",phase:"record_stop_android_enter",data:{deviceId:n.id,remotePath:i.remotePath,remotePid:i.remotePid}});let o=await a.runCmd("adb",["-s",n.id,"shell","kill","-2",i.remotePid],{allowFailure:!0});if(U({level:"debug",phase:"record_stop_android_signal",data:{deviceId:n.id,remotePath:i.remotePath,remotePid:i.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await fR(a,n.id,i.remotePid)&&!await fV(a,n.id,i.remotePid)&&(t=`failed to stop recording: ${fP(o,"adb shell kill")}`):await fT(a,n.id,i.remotePid)||await fV(a,n.id,i.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${i.remotePid} did not exit`),!t){await f$(a,n.id,i.remotePath);let e=await fU({deps:a,deviceId:n.id,remotePath:i.remotePath,outPath:i.outPath});if(e)return await s(),{ok:!1,error:{code:"COMMAND_FAILED",message:e}};if(fD({recording:i}),i.showTouches&&i.telemetryPath){let e=fk();if(e)i.overlayWarning=e;else try{await a.overlayRecordingTouches({videoPath:i.outPath,telemetryPath:i.telemetryPath,targetLabel:"Android recording"})}catch(e){i.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}}if(await s(),t)return{ok:!1,error:{code:"COMMAND_FAILED",message:t}};if(r)return{ok:!1,error:{code:"COMMAND_FAILED",message:r}};return null;async function s(){let e=await a.runCmd("adb",["-s",n.id,"shell","rm","-f",i.remotePath],{allowFailure:!0});U({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:n.id,remotePath:i.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${fP(e,"adb shell rm")}`)}}function fq(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function fH(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function fW(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i}=e,o=fq(r);if(o)try{await i.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},fH(t,n,r))}catch(e){U({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:fC(e)}})}}async function fz(e){let t,r,{req:a,activeSession:n,sessionStore:i,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,p=`agent-device-recording-${Date.now()}.mp4`,f=`tmp/${p}`,m=fH(a,s,n),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:p,fps:d,appBundleId:c},m);try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(a){var w,g;if(!fC(a).toLowerCase().includes("recording already in progress"))return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${fC(a)}`}};U({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:n.name,error:fC(a)}});let e=(w=o.id,g=n.name,i.toArray().find(e=>e.name!==g&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===w&&e.recording?.platform==="ios-device-runner"));if(e)return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: recording already in progress in session '${e.name}'`}};try{await l.runIosRunnerCommand(o,{command:"recordStop",appBundleId:c},m)}catch{}try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(e){return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${fC(e)}`}}}}return{platform:"ios-device-runner",remotePath:f,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function fJ(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await i.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,appBundleId:l},fH(t,n,r))}catch(e){return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${fC(e)}`}}}return{platform:"macos-runner",...s}}async function fK(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i,recording:o}=e,s=fq(r);try{await i.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},fH(t,n,r))}catch(e){U({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:fC(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of tq)if(0===(l=await i.runCmd("xcrun",["devicectl","device","copy","from","--device",a.id,"--source",o.remotePath,"--destination",o.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==l.exitCode){let e=l.stderr.trim()||l.stdout.trim()||`devicectl exited with code ${l.exitCode}`;return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to copy recording from device: ${e}`}}}let d="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);d>0&&await i.trimRecordingStart({videoPath:o.outPath,trimStartMs:d});let u=fD({recording:o,trimStartMs:d});if(o.showTouches){let e=fk();if(e)o.overlayWarning=e;else try{await i.overlayRecordingTouches({videoPath:o.outPath,telemetryPath:u,targetLabel:"iOS recording"})}catch(e){o.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}return null}async function fX(e){let{req:t,activeSession:r,device:a,logPath:n,deps:i,recording:o}=e,s=fq(r);try{await i.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},fH(t,n,r))}catch(e){U({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:fC(e)}})}let l=fD({recording:o});if(o.showTouches){let e=fk();if(e)o.overlayWarning=e;else try{await i.overlayRecordingTouches({videoPath:o.outPath,telemetryPath:l,targetLabel:"macOS recording"})}catch(e){o.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}return null}async function fY(e){for(let t=0;t<2;t+=1){try{if(s.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await new Promise(e=>setTimeout(e,250))}return Date.now()}async function fZ(e){let t,r,{req:a,activeSession:n,device:i,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await fW({req:a,activeSession:n,device:i,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",tt(i,["io",i.id,"recordVideo",d]),{allowFailure:!0}),p=await fY(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(i,{command:"uptime",appBundleId:fq(n)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:n.trace?.outPath}),d=Date.now();t=Math.round((e+d)/2),r="number"==typeof l.currentUptimeMs?l.currentUptimeMs:void 0}catch{}return{platform:"ios",child:u,wait:c,...l,startedAt:p,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function fQ(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:i,device:o,logPath:l,deps:d}=e;if(i.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"recording already in progress"}};let u=r.flags?.fps;if(void 0!==u&&(!Number.isInteger(u)||u<1||u>120))return{ok:!1,error:{code:"INVALID_ARGS",message:"fps must be an integer between 1 and 120"}};if(!dI("record",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"record is not supported on this device"}};let c=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,f=rC.expandHome(c,r.meta?.cwd),m={outPath:f,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(s.mkdirSync(p.dirname(f),{recursive:!0}),s.rmSync(f,{force:!0}),"ios"===o.platform&&"device"===o.kind){let e=fq(i);if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"record on physical iOS devices requires an active app session; run open <app> first"}};t=await fz({req:r,activeSession:i,sessionStore:n,device:o,logPath:l,deps:d,fpsFlag:u,recordingBase:m,appBundleId:e})}else if("macos"===o.platform){let e=fq(i);if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"record on macOS requires an active app session; run open <app> first"}};t=await fJ({req:r,activeSession:i,device:o,logPath:l,deps:d,fpsFlag:u,recordingBase:m,appBundleId:e})}else t="ios"===o.platform?await fZ({req:r,activeSession:i,device:o,logPath:l,deps:d,recordingBase:m,resolvedOut:f}):await fB({deps:d,device:o,recordingBase:m});return"ok"in t?t:(i.recording=t,n.set(a,i),n.recordAction(i,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??c,showTouches:t.showTouches}})}async function f0(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await fj({deps:t,device:r,recording:a});a.child.kill("SIGINT");let n=await a.wait;if(0!==n.exitCode)return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to stop recording: ${fP(n,"simctl recordVideo")}`}};let i=fD({recording:a});if(a.showTouches){let e=fk();if(e)a.overlayWarning=e;else try{await t.overlayRecordingTouches({videoPath:a.outPath,telemetryPath:i,targetLabel:"iOS recording"})}catch(e){a.overlayWarning=`failed to overlay recording touches: ${fC(e)}`}}return null}async function f1(e){var t;let r,{req:a,activeSession:n,device:i,logPath:o,deps:s}=e;if(!n.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"no active recording"}};let l=n.recording,d=l.invalidatedReason;n.recording=void 0;let u="ios-device-runner"===l.platform?await fK({req:a,activeSession:n,device:i,logPath:o,deps:s,recording:l}):"macos-runner"===l.platform?await fX({req:a,activeSession:n,device:i,logPath:o,deps:s,recording:l}):await f0({deps:s,device:i,recording:l});return u||(d?{ok:!1,error:{code:"COMMAND_FAILED",message:d}}:(r=[{field:"outPath",path:(t=l).outPath,localPath:t.clientOutPath,fileName:p.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return f_(e.clientOutPath)}(t),fileName:p.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function f2(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,i={runCmd:F,runCmdBackground:C,runIosRunnerCommand:rf,waitForStableFile:fb,isPlayableVideo:fA,trimRecordingStart:fO,overlayRecordingTouches:fL},o=a.get(r),s=o?.device??await l9(t.flags??{});o||await dS(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return{ok:!1,error:{code:"INVALID_ARGS",message:"record requires start|stop"}};if("start"===d)return fQ({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:n,deps:i});let u=await f1({req:t,activeSession:l,device:s,logPath:n,deps:i});return u.ok&&a.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:u.data?.outPath,showTouches:u.data?.showTouches}}),u}async function f3(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,i=t.command;if("record"===i)return f2({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===i){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return uq("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return uq("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return uq("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=rC.expandHome(e);return s.mkdirSync(p.dirname(r),{recursive:!0}),s.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return uq("INVALID_ARGS","no active trace");let o=n.trace.outPath;if(t.positionals?.[1]){let e=rC.expandHome(t.positionals[1]);s.mkdirSync(p.dirname(e),{recursive:!0}),s.existsSync(o)?s.renameSync(o,e):s.appendFileSync(e,""),o=e}return n.trace=void 0,a.recordAction(n,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:o}}),{ok:!0,data:{trace:"stopped",outPath:o}}}return null}function f4(e){return"number"==typeof e.gestureClockOriginAtMs&&"number"==typeof e.gestureClockOriginUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureClockOriginAtMs+(e.gestureStartUptimeMs-e.gestureClockOriginUptimeMs)-e.recordingStartedAt):"number"==typeof e.runnerStartedAtUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureStartUptimeMs-e.runnerStartedAtUptimeMs):"number"==typeof e.gestureStartUptimeMs&&"number"==typeof e.gestureEndUptimeMs?Math.max(0,e.fallbackFinishedAtMs-(e.gestureEndUptimeMs-e.gestureStartUptimeMs)-e.recordingStartedAt):Math.max(0,e.fallbackStartedAtMs-e.recordingStartedAt)}let f5=new WeakMap;function f8(e){if(!e)return;let t=f5.get(e);if(t)return t;let r=function(e){let t=function(e){let t=e.filter(e=>(function(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("application")||t.includes("window")})(e.type)&&f6(e.rect)).map(e=>e.rect).sort((e,t)=>(t?.width??0)*(t?.height??0)-(e?.width??0)*(e?.height??0))[0];if(t)return t;let r=e.map(e=>e.rect).filter(f6);if(0===r.length)return;let a=Math.max(...r.map(e=>e.x+e.width)),n=Math.max(...r.map(e=>e.y+e.height));if(!(a<=0)&&!(n<=0))return{x:0,y:0,width:a,height:n}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return f5.set(e,r),r}function f6(e){return!!e&&e.width>0&&e.height>0}let f9={referenceWidth:1e3,referenceHeight:1e3};function f7(e,t,r,a,n={},i=Date.now(),o=Date.now()){var s,l,d;let u,c,p=e.recording;if(!p)return;let f={...n,...a??{}},m=ma(f.effectiveDurationMs)??ma(f.durationMs),h={recordingStartedAt:p.startedAt,gestureClockOriginAtMs:p.gestureClockOriginAtMs,gestureClockOriginUptimeMs:p.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===p.platform?p.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:ma(f.gestureStartUptimeMs),gestureEndUptimeMs:ma(f.gestureEndUptimeMs),fallbackStartedAtMs:i,fallbackFinishedAtMs:o},w="number"==typeof(s={gestureStartUptimeMs:ma(f.gestureStartUptimeMs),gestureEndUptimeMs:ma(f.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:i,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),g="ios"===e.device.platform&&void 0===ma(f.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=mn(ma(t.count),1)??1,r=!0===t.doubleTap,a=mn(ma(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,f)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return f4(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:w}):f4(h),y=(l=e.snapshot,u=ma((d=f).referenceWidth),c=ma(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:f8(l)),v=function(e,t,r,a,n,i){switch(e){case"click":case"press":return function(e,t,r,a){let n=mi(t,e);if(!n)return[];let{x:i,y:o}=n,s=mn(ma(t.count),1)??1,l=mn(ma(t.intervalMs),0)??0,d=!0===t.doubleTap,u=mn(ma(t.holdMs),1),c=[];for(let e=0;e<s;e+=1){let t=r+e*l;if(void 0!==u&&u>0){c.push(mt(t,i,o,u,a));continue}c.push(me(t,i,o,a)),d&&c.push(me(t+90,i,o,a))}return c}(t,r,a,i);case"fill":case"focus":return function(e,t,r,a){let n=mi(t,e);if(!n)return[];let{x:i,y:o}=n;return[me(r,i,o,a)]}(t,r,a,i);case"longpress":return function(e,t,r,a,n){let i=mi(t,e);if(!i)return[];let{x:o,y:s}=i;return[mt(r,o,s,ms(a,[ma(t.durationMs),ma(e[2])],800),n)]}(t,r,a,n,i);case"scroll":return function(e,t,r,a,n){let i=mo(t,e),o=mr(t.contentDirection)??mr(t.direction);if(!i||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=i,c=ms(a,[],250),p=ma(t.amount)??ma(e[1]),f=ma(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...n,durationMs:c,contentDirection:o,...void 0!==p?{amount:p}:{},...void 0!==f?{pixels:f}:{}}]}(t,r,a,n,i);case"swipe":return function(e,t,r,a,n){let i=mo(t,e);if(!i)return[];let{x1:o,y1:s,x2:l,y2:d}=i,u=ms(a,[ma(t.effectiveDurationMs),ma(t.durationMs),ma(e[4])],250),c=mn(ma(t.count),1)??1,p=mn(ma(t.pauseMs),0)??0,f="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===f&&e%2==1,a=t?l:o,i=t?d:s,c=t?o:l,h=t?s:d,w=r+e*(u+p);if("back-swipe"===function(e,t,r,a,n){if(!n||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let i=.08*n.referenceWidth;return e<=i&&r>e||e>=n.referenceWidth-i&&r<e?"back-swipe":"swipe"}(a,i,c,h,n)){m.push({kind:"back-swipe",tMs:w,x:a,y:i,x2:c,y2:h,...n,durationMs:u,edge:function(e,t,r){if(r){let t=.08*r.referenceWidth;if(e<=t)return"left";if(e>=r.referenceWidth-t)return"right"}return t>=e?"left":"right"}(a,c,n)});continue}m.push({kind:"swipe",tMs:w,x:a,y:i,x2:c,y2:h,...n,durationMs:u})}return m}(t,r,a,n,i);case"pinch":return function(e,t,r,a,n){let i=mi(t,e,1),o=ma(t.scale)??ma(e[0]);if(!i||void 0===o||o<=0)return[];let{x:s,y:l}=i;return[{kind:"pinch",tMs:r,x:s,y:l,...n,scale:o,durationMs:ms(a,[],280)}]}(t,r,a,n,i);default:return[]}}(t,r,f,g,w,y);0!==v.length&&(p.gestureEvents.push(...v),U({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:g,gestureDurationMs:w,kinds:v.map(e=>e.kind)}}))}function me(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function mt(e,t,r,a,n){return{kind:"longpress",tMs:e,x:t,y:r,...n,durationMs:a}}function mr(e){if("string"!=typeof e)return;let t=e.trim().toLowerCase();switch(t){case"up":case"down":case"left":case"right":return t;default:return}}function ma(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"!=typeof e||0===e.trim().length)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function mn(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function mi(e,t,r=0){let a=ma(e.x)??ma(t[r]),n=ma(e.y)??ma(t[r+1]);if(void 0!==a&&void 0!==n)return{x:a,y:n}}function mo(e,t){let r=ma(e.x1)??ma(t[0]),a=ma(e.y1)??ma(t[1]),n=ma(e.x2)??ma(t[2]),i=ma(e.y2)??ma(t[3]);if(void 0!==r&&void 0!==a&&void 0!==n&&void 0!==i)return{x1:r,y1:a,x2:n,y2:i}}function ms(e,t,r){return mn(e,1)??t.map(e=>mn(e,1)).find(e=>void 0!==e)??r}function ml(e){var t,r,a;let n,i,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,n="string"==typeof t?.ref?t.ref:void 0,i="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:n?i&&"primary"!==i?`Clicked ${i} @${n} (${r}, ${a})`:`Tapped @${n} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...ep(c)}}async function md(e){let{session:t,sessionStore:r,requestCommand:a,requestPositionals:n,flags:i,contextFromFlags:o,interactionCommand:s,interactionPositionals:l,outPath:d,afterDispatch:u,buildPayloads:c}=e,p=await mu({session:t,flags:i,contextFromFlags:o,command:s,positionals:l,outPath:d});await u?.(p.data);let{result:f,responseData:m=f}=await c(p.data);return function(e){let{session:t,sessionStore:r,command:a,positionals:n,flags:i,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:n,flags:i??{},result:o}),uS(a)&&uI(t,a),f7(t,a,n,o,i??{},l,d),{ok:!0,data:s}}({session:t,sessionStore:r,command:a,positionals:n,flags:i,result:f,responseData:m,actionStartedAt:p.actionStartedAt,actionFinishedAt:p.actionFinishedAt})}async function mu(e){let{session:t,flags:r,contextFromFlags:a,command:n,positionals:i,outPath:o}=e,s=Date.now(),l={...a(r,t.appBundleId,t.trace?.outPath)},d=await l7(t.device,n,i,o,l);return{data:d&&"object"==typeof d?d:void 0,actionStartedAt:s,actionFinishedAt:Date.now()}}async function mc(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await ij(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=f8(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=f8(await i(t,r,a,n,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function mp(e){try{return await mc(e)}catch(t){U({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function mf(e){return f8({nodes:e,createdAt:0})}function mm(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`}}}async function mh(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r),d=t.command,u="click"===d?"click":"press";if(!l)return uq("SESSION_NOT_FOUND","No active session. Run open first.");let c=mm(l,u);if(c)return c;if(!dI("press",l.device))return uq("UNSUPPORTED_OPERATION","press is not supported on this device");let p=lL(t.flags),f="primary"===p?{}:{button:p};if("primary"!==p){let e=lC({commandLabel:u,platform:l.device.platform,button:p,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return uq(e.code,e.message,e.details)}let m=function(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}(t.positionals??[]);if(m)return md({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[String(m.x),String(m.y)],flags:t.flags,contextFromFlags:n,interactionCommand:"press",interactionPositionals:[String(m.x),String(m.y)],outPath:t.flags?.out,afterDispatch:async()=>{await mw(l,"coordinate tap")},buildPayloads:async e=>{let r=await mp({session:l,flags:t.flags,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i}),o=ml({data:e,fallbackX:m.x,fallbackY:m.y,referenceFrame:r,extra:f});return{result:o,responseData:o}}});let h="click",w=t.positionals?.[0]??"";if(w.startsWith("@")){let e=s("press",t.flags);if(e)return e;let r=t.positionals.length>1?t.positionals.slice(1).join(" ").trim():"",c=await fs({session:l,refInput:w,fallbackLabel:r,commandLabel:u,promoteToHittableAncestor:!0,invalidRefMessage:`${u} requires a ref like @e2`,missingBoundsMessage:`Ref ${w} not found or has no bounds`,invalidBoundsMessage:`Ref ${w} not found or has invalid bounds`,reqFlags:t.flags,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o});if(!c.ok)return c.response;let{ref:p,node:m,snapshotNodes:g,point:y}=c.target,v=cQ(m,g),I=pw(m,l.device.platform,{action:h}),{x:b,y:A}=y;return md({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"press",interactionPositionals:[String(b),String(A)],outPath:t.flags?.out,afterDispatch:async()=>{await mw(l,`@${p}`)},buildPayloads:e=>{let t=ml({data:e,fallbackX:b,fallbackY:A,referenceFrame:mf(g),extra:{ref:p,refLabel:v,selectorChain:I,...f}});return{result:t,responseData:t}}})}let g=(t.positionals??[]).join(" ").trim();if(!g)return{ok:!1,error:{code:"INVALID_ARGS",message:`${u} requires @ref, selector expression, or x y coordinates`}};let y=c7(g),v=await i(l,t.flags,a,n,{interactiveOnly:!0}),I=await T("selector_resolve",()=>pp(v.nodes,y,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:d});if(!I||!I.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:pm(y,I?.diagnostics??[],{unique:!0})}};let b=fl(v.nodes,I.node),A=fi(b.rect);if(!A)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Selector ${I.selector.raw} resolved to invalid bounds`}};let{x:S,y:N}=A,_=pw(b,l.device.platform,{action:h}),x=cQ(b,v.nodes);return md({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"press",interactionPositionals:[String(S),String(N)],outPath:t.flags?.out,afterDispatch:async()=>{await mw(l,I.selector.raw)},buildPayloads:e=>{let t=ml({data:e,fallbackX:S,fallbackY:N,referenceFrame:mf(v.nodes),extra:{selector:I.selector.raw,selectorChain:_,refLabel:x,...f}});return{result:t,responseData:t}}})}async function mw(e,t){if("android"!==e.device.platform||!e.appBundleId)return;let r=await nJ(e.device),a=r.package?.trim();if(a&&a!==e.appBundleId){var n;if("com.android.settings"===(n=a)||"com.android.systemui"===n||"com.google.android.permissioncontroller"===n||n.includes("launcher"))throw new O("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${a}. The tap likely escaped the app.`,{expectedPackage:e.appBundleId,foregroundPackage:a,activity:r.activity,hint:"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."})}}async function mg(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r);if(l){let e=mm(l,"fill");if(e)return e}if(l&&!dI("fill",l.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"fill is not supported on this device"}};if(t.positionals?.[0]?.startsWith("@")){if(!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let e=s("fill",t.flags);if(e)return e;let r=t.positionals.length>=3?t.positionals[1]:"",d=t.positionals.length>=3?t.positionals.slice(2).join(" "):t.positionals.slice(1).join(" ");if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after ref"}};let u=await fs({session:l,refInput:t.positionals[0],fallbackLabel:r,commandLabel:"fill",promoteToHittableAncestor:!1,invalidRefMessage:"fill requires a ref like @e2",missingBoundsMessage:`Ref ${t.positionals[0]} not found or has no bounds`,invalidBoundsMessage:`Ref ${t.positionals[0]} not found or has invalid bounds`,reqFlags:t.flags,sessionStore:a,contextFromFlags:n,captureSnapshotForSession:i,resolveRefTarget:o});if(!u.ok)return u.response;let{ref:c,node:p,snapshotNodes:f,point:m}=u.target,h=p.type??"",w=h&&!c3(h,l.device.platform)?`fill target ${t.positionals[0]} resolved to "${h}", attempting fill anyway.`:void 0,g=cQ(p,f),y=pw(p,l.device.platform,{action:"fill"}),{x:v,y:I}=m;return md({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"fill",interactionPositionals:[String(v),String(I),d],outPath:t.flags?.out,buildPayloads:e=>{let t=ml({data:e,fallbackX:v,fallbackY:I,referenceFrame:mf(f),extra:{ref:c,refLabel:g,selectorChain:y,text:d}}),r={...e??{ref:c,x:v,y:I}};return w&&(t.warning=w,r.warning=w),{result:t,responseData:r}}})}if(!l)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let d=pt(t.positionals??[],{preferTrailingValue:!0});if(d){if(0===d.rest.length)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let e=d.rest.join(" ").trim();if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let r=c7(d.selectorExpression),o=await i(l,t.flags,a,n,{interactiveOnly:!0}),s=await T("selector_resolve",()=>pp(o.nodes,r,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:t.command});if(!s||!s.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:pm(r,s?.diagnostics??[],{unique:!0})}};let u=s.node,c=s.node.rect,p=u.type??"",f=p&&!c3(p,l.device.platform)?`fill target ${s.selector.raw} resolved to "${p}", attempting fill anyway.`:void 0,{x:m,y:h}=eA(c),w=pw(u,l.device.platform,{action:"fill"});return md({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:n,interactionCommand:"fill",interactionPositionals:[String(m),String(h),e],outPath:t.flags?.out,buildPayloads:t=>{let r=ml({data:t,fallbackX:m,fallbackY:h,referenceFrame:mf(o.nodes),extra:{text:e,selector:s.selector.raw,selectorChain:w,refLabel:cQ(u,o.nodes)}});return f&&(r.warning=f),{result:r,responseData:r}}})}return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires x y text, @ref text, or selector text"}}}async function my(e){switch(e.req.command){case"press":case"click":return await mh(e);case"fill":return await mg(e);default:return null}}let mv=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function mI(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,a]of mv)void 0!==e[r]&&t.push(a);return t}(t);return 0===r.length?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} @ref does not support ${r.join(", ")}.`}}}async function mb(e,t,r,a,n){let i={...t??{},snapshotInteractiveOnly:n.interactiveOnly,snapshotCompact:n.interactiveOnly},o=a(i,e.appBundleId,e.trace?.outPath),{snapshot:s}=await pF({device:e.device,session:e,flags:i,outPath:i.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}async function mA(e){let{command:t,selectorExpression:r,session:a,flags:n,sessionStore:i,contextFromFlags:o,interactiveOnly:s,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}=e,c=c7(r),p=await mb(a,n,i,o,{interactiveOnly:s}),f=await T("selector_resolve",()=>pp(p.nodes,c,{platform:a.device.platform,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}),{command:t});return f&&(!l||f.node.rect)?{ok:!0,chain:c,snapshot:p,resolved:f}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:pm(c,f?.diagnostics??[],{unique:d})}}}}async function mS(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n}=e,i=t.positionals?.[0];if("text"!==i&&"attrs"!==i)return{ok:!1,error:{code:"INVALID_ARGS",message:"get only supports text or attrs"}};let o=a.get(r);if(!o)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!dI("get",o.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"get is not supported on this device"}};let s=t.positionals?.[1]??"";if(s.startsWith("@")){let e=mI("get",t.flags);if(e)return e;let r=fn({session:o,refInput:s,fallbackLabel:t.positionals.length>2?t.positionals.slice(2).join(" ").trim():"",requireRect:!1,invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${s} not found`});if(!r.ok)return r.response;let{ref:l,node:d}=r.target,u=pw(d,o.device.platform,{action:"get"});if("attrs"===i)return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{ref:l,selectorChain:u}}),{ok:!0,data:{ref:l,node:d}};let c=await fu({device:o.device,node:d,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:n});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{ref:l,text:c,refLabel:mN(c),selectorChain:u}}),{ok:!0,data:{ref:l,text:c,node:d}}}let l=t.positionals.slice(1).join(" ").trim();if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"get requires @ref or selector expression"}};let d=await mA({command:t.command,selectorExpression:l,session:o,flags:t.flags,sessionStore:a,contextFromFlags:n,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:"text"===i});if(!d.ok)return d.response;let{resolved:u}=d,c=u.node,p=pw(c,o.device.platform,{action:"get"});if("attrs"===i)return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{selector:u.selector.raw,selectorChain:p}}),{ok:!0,data:{selector:u.selector.raw,node:c}};let f=await fu({device:o.device,node:c,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:n});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{text:f,refLabel:mN(f),selector:u.selector.raw,selectorChain:p}}),{ok:!0,data:{selector:u.selector.raw,text:f,node:c}}}function mN(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function m_(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function mx(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:n}=e,i=(t.positionals?.[0]??"").toLowerCase();if(!["visible","hidden","exists","editable","selected","text"].includes(i))return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires predicate: visible|hidden|exists|editable|selected|text"}};let o=a.get(r);if(!o)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!dI("is",o.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"is is not supported on this device"}};let{split:s}=pr(t.positionals);if(!s)return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires a selector expression"}};let l=s.rest.join(" ").trim();if("text"===i&&!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"is text requires expected text value"}};if("text"!==i&&s.rest.length>0)return{ok:!1,error:{code:"INVALID_ARGS",message:`is ${i} does not accept trailing values`}};let d=c7(s.selectorExpression);if("exists"===i){let e=pf((await mb(o,t.flags,a,n,{interactiveOnly:!1})).nodes,d,{platform:o.device.platform});return e?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:i,selector:e.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,matches:e.matches}}),{ok:!0,data:{predicate:i,pass:!0,selector:e.selector.raw,matches:e.matches}}):{ok:!1,error:{code:"COMMAND_FAILED",message:pm(d,[],{unique:!1})}}}let u=await mA({command:"is",selectorExpression:s.selectorExpression,session:o,flags:t.flags,sessionStore:a,contextFromFlags:n,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!u.ok)return u.response;let{resolved:c}=u,p=function(e){let{predicate:t,node:r,nodes:a,expectedText:n,platform:i}=e,o=c5(r),s=pd(r,i),l=!0===r.selected,d="text"===t?pl(r):function(e,t){if(!0===e.hittable)return!0;if(m_(e.rect))return B(e,t);if(e.rect)return!1;let r=function(e,t){let r=new Map(t.map(e=>[e.index,e])),a=e,n=new Set;for(;"number"==typeof a.parentIndex&&!n.has(a.index);){n.add(a.index);let e=r.get(a.parentIndex);if(!e)break;if(function(e){let t=c2(e.type??"");return!(t.includes("application")||t.includes("window")||t.includes("scrollview")||t.includes("tableview")||t.includes("collectionview"))&&"table"!==t&&"list"!==t&&"listview"!==t&&(!0===e.hittable||m_(e.rect))}(e))return e;a=e}return null}(e,t);return!!r&&(!0===r.hittable||!!m_(r.rect)&&B(r,t))}(r,a),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=s;break;case"selected":u=l;break;case"text":u=o===(n??"")}let c="text"===t?`expected="${n??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:i,node:c.node,nodes:u.snapshot.nodes,expectedText:l,platform:o.device.platform});return p.pass?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:i,selector:c.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,text:"text"===i?p.actualText:void 0}}),{ok:!0,data:{predicate:i,pass:!0,selector:c.selector.raw}}):{ok:!1,error:{code:"COMMAND_FAILED",message:`is ${i} failed for selector ${c.selector.raw}: ${p.details}`}}}function mD(e,t){var r,a;let n=Math.max(1,t.height),i=Math.max(1,t.width),o=t.y,s=t.y+n,l=t.x,d=t.x+i,u=s-.25*n,c=Math.max(8,.1*i),p=e.y+e.height/2,f=e.x+e.width/2;if(p>=o+.25*n&&p<=u)return null;let m=Math.round((r=f,a=l+c,Math.min(d-c,Math.max(a,r)))),h=Math.round(o+.86*n),w=Math.round(o+.14*n);return p>u?{x:m,startY:h,endY:w,direction:"down"}:{x:m,startY:w,endY:h,direction:"up"}}async function mM(e){let t,r,{req:a,sessionName:n,sessionStore:i,contextFromFlags:o}=e,s=i.get(n);if(!s)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!dI("scrollintoview",s.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"scrollintoview is not supported on this device"}};let l=a.positionals?.[0]??"";if(!l.startsWith("@"))return null;let d=mI("scrollintoview",a.flags);if(d)return d;let u=a.positionals&&a.positionals.length>1?a.positionals.slice(1).join(" ").trim():"",c=function(e,t,r){let a=fn({session:e,refInput:t,fallbackLabel:r,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${t} not found or has no bounds`});if(!a.ok){let{response:e}=a;return e.ok||"COMMAND_FAILED"!==e.error.code?{ok:!1,response:e}:{ok:!1,response:mE(t,0,{message:e.error.message})}}return mk(t,0,a.target)}(s,l,u);if(!c.ok)return c.response;let{ref:p}=c.state,{currentRef:f,node:m,snapshotNodes:h,viewportRect:w}=c.state,g=cQ(m,h),y=pw(m,s.device.platform,{action:"get"}),v=u||g||m.label||"";if(!mD(m.rect,w)){let e=mO({ref:p,currentRef:f,attempts:0,alreadyVisible:!0});return i.recordAction(s,{command:a.command,positionals:a.positionals??[],flags:a.flags??{},result:{refLabel:g,selectorChain:y,...e}}),{ok:!0,data:e}}let I=a.flags?.maxScrolls??48,b=0,A=0,S=Z(m.rect,w);for(;b<I;){let e=mD(m.rect,w);if(!e)break;t=e.direction,r=await l7(s.device,"swipe",[String(e.x),String(e.startY),String(e.x),String(e.endY),"16"],a.flags?.out,{...o(a.flags,s.appBundleId,s.trace?.outPath),count:1,pauseMs:0,pattern:"one-way"}),b+=1,await mb(s,a.flags,i,o,{interactiveOnly:!0});let n=function(e){let{session:t,targetInput:r,fallbackLabel:a,attempts:n,ref:i,selectorChain:o,platform:s}=e;if(t.snapshot){let e=function(e,t,r,a){for(let r of t){let t=pp(e,c7(r),{platform:a,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(t?.node.rect)return t.node}return r?cZ(e,r):null}(t.snapshot.nodes,o,a,s);if(e)return mk(r,n,{ref:i,node:e,snapshotNodes:t.snapshot.nodes},{currentRef:e.ref})}let l=fn({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${r} not found or has no bounds`});if(!l.ok){let{response:e}=l;return e.ok||"COMMAND_FAILED"!==e.error.code?{ok:!1,response:e}:{ok:!1,response:mE(r,n,{message:`scrollintoview lost track of ${r} after ${n} scroll${1===n?"":"s"}`,ref:i})}}return mk(r,n,l.target,{ref:i,currentRef:l.target.node.ref,missingBoundsMessage:`scrollintoview lost bounds for ${r} after ${n} scroll${1===n?"":"s"}`})}({session:s,targetInput:l,fallbackLabel:v,attempts:b,ref:p,selectorChain:y,platform:s.device.platform});if(!n.ok)return n.response;({currentRef:f,node:m,snapshotNodes:h,viewportRect:w}=n.state);let d=Z(m.rect,w);if(0===d)break;if(d>=S){if((A+=1)>=2)return mE(l,b,{message:`scrollintoview made no progress toward ${l} after ${b} scroll${1===b?"":"s"}`,ref:p,stalled:!0})}else A=0;S=d}if(Z(m.rect,w)>0)return mE(l,b,{message:`scrollintoview reached --max-scrolls=${I} before ${l} entered view`,ref:p,maxScrolls:I});let N=mO({data:r,ref:p,currentRef:f,attempts:b,direction:t});return i.recordAction(s,{command:a.command,positionals:a.positionals??[],flags:a.flags??{},result:{refLabel:g,selectorChain:y,...N}}),{ok:!0,data:N}}function mk(e,t,r,a={}){let{ref:n,currentRef:i,missingBoundsMessage:o}=a,s=r.node;if(!s.rect)return{ok:!1,response:mE(e,t,{message:o??`Ref ${e} not found or has no bounds`,ref:n??r.ref})};let l=eo(r.snapshotNodes,s.rect);return l?{ok:!0,state:{ref:n??r.ref,currentRef:i??r.node.ref,node:s,snapshotNodes:r.snapshotNodes,viewportRect:l}}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`scrollintoview could not infer viewport for ${e}`}}}}function mE(e,t,r={}){let{message:a,...n}=r;return{ok:!1,error:{code:"COMMAND_FAILED",message:"string"==typeof a?a:`scrollintoview could not find ${e}`,details:{reason:"not_found",attempts:t,...n}}}}function mO(e){let{data:t,ref:r,currentRef:a,attempts:n,alreadyVisible:i,direction:o}=e;return{...t??{},ref:r,currentRef:a,attempts:n,...i?{alreadyVisible:i}:{},...o?{direction:o}:{},...ep(`Scrolled into view: @${r}`)}}async function mL(e){let t=await my({...e,captureSnapshotForSession:mb,resolveRefTarget:fn,refSnapshotFlagGuardResponse:mI});if(t)return t;switch(e.req.command){case"get":return await mS(e);case"is":return await mx(e);case"scrollintoview":return await mM(e);default:return null}}function mC(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function mP(e){let{req:t,leaseRegistry:r}=e,a=mC(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}function mR(e,t){if(!t)return[];let r=[],a=e.device,n=t.platform;if(n&&!t_(a.platform,n)&&r.push({key:"platform",value:t.platform}),t.target&&t.target!==(a.target??"mobile")&&r.push({key:"target",value:t.target}),t.udid&&("ios"!==a.platform||t.udid!==a.id)&&r.push({key:"udid",value:t.udid}),t.serial&&("android"!==a.platform||t.serial!==a.id)&&r.push({key:"serial",value:t.serial}),t.device&&t.device.trim().toLowerCase()!==a.name.trim().toLowerCase()&&r.push({key:"device",value:t.device}),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),n=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==n)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=e9(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function mT(e){return`${function(e){switch(e){case"iosSimulatorDeviceSet":return"--ios-simulator-device-set";case"androidDeviceAllowlist":return"--android-device-allowlist";default:return`--${e}`}}(e.key)}=${e.value}`}let m$=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"],mF=/\bis(?:n't| not)\s+responding\b/i,mU=/^close app$/i;async function mG(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await mV(t),r=function(e){if(mH(e))return e.find(e=>{let t=mq(e);return t.length>0&&mU.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:n}=eA(r.rect),i=await F("adb",aK(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(n))]),{allowFailure:!0});if(0!==i.exitCode)return U({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:i.exitCode,stdout:i.stdout.trim(),stderr:i.stderr.trim()}}),"failed";if(!await mB(t))return U({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await nX(t.device,t.appBundleId),!await mj(t,t.appBundleId)))return U({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return U({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:n}}),"recovered"}catch(e){return U({level:"warn",phase:"android_blocking_dialog_recovery_failed",data:{session:t.name,deviceId:t.device.id,error:e instanceof Error?e.message:String(e)}}),"failed"}}async function mV(e){return e_(c1((await ib(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function mB(e){for(let t=0;t<12;t+=1){if(!mH(await mV(e)))return!0;await mW(500)}return!mH(await mV(e))}async function mj(e,t){for(let r=0;r<12;r+=1){if((await nJ(e.device)).package===t)return!0;await mW(500)}return(await nJ(e.device)).package===t}function mq(e){let t=[e.label,e.identifier];return"string"==typeof e.value&&e.value.trim().length>0&&t.push(e.value),t.filter(e=>"string"==typeof e&&e.trim().length>0).join(" ").trim()}function mH(e){return e.some(e=>{let t=mq(e);return t.length>0&&mF.test(t)})}function mW(e){return new Promise(t=>setTimeout(t,e))}let mz=[255,59,48,255],mJ=[255,214,10,255],mK=[0,0,0,255],mX={e:["01110","10000","11110","10000","10000","10001","01110"],0:["01110","10001","10011","10101","11001","10001","01110"],1:["00100","01100","00100","00100","00100","00100","01110"],2:["01110","10001","00001","00010","00100","01000","11111"],3:["11110","00001","00001","01110","00001","00001","11110"],4:["00010","00110","01010","10010","11111","00010","00010"],5:["11111","10000","10000","11110","00001","00001","11110"],6:["01110","10000","10000","11110","10001","10001","01110"],7:["11111","00001","00010","00100","01000","01000","01000"],8:["01110","10001","10001","01110","10001","10001","01110"],9:["01110","10001","10001","01111","00001","00001","01110"]};async function mY(e){let t=eN(await d.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let n=function(e){let t=null;for(let r of e)mQ(r)&&m4(r.rect)&&(!t||m5(r.rect)>m5(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,n=-1/0;for(let i of e)i.rect&&m4(i.rect)&&(t=Math.min(t,i.rect.x),r=Math.min(r,i.rect.y),a=Math.max(a,i.rect.x+i.rect.width),n=Math.max(n,i.rect.y+i.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||n<=r?null:{x:t,y:r,width:a-t,height:n-r}}(e.filter(e=>{var t;return m4(e.rect)&&!("image"===c2((t=e).type??"")&&!m0(t.label))}))}(e.nodes),i=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(m1)||m2(e.identifier);return mZ(e)?t:t&&function(e){let t=c2(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let o=function(e,t){if(function(e){return mZ(e)&&!mQ(e)}(t)&&m4(t.rect))return t;let r=function(e,t){let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){;a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(mZ(t)&&!mQ(t)&&m4(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&m4(r.rect))return r;if(t.hittable&&m4(t.rect)&&!mQ(t))return t;let a=c4(e,t);return a?.rect&&m4(a.rect)&&!mQ(a)?a:null}(e.nodes,a);if(!o?.rect||!m4(o.rect))continue;let s=function(e,t,r){let a=m3(e);if(e.ref!==t.ref&&a)return a;let n=function(e,t){let r=null;for(let a of t){if(a.ref===e.ref||!function(e,t,r){let a=e;for(;void 0!==a.parentIndex;){let e=r[a.parentIndex];if(!e)break;if(e.ref===t.ref)return!0;a=e}return!1}(a,e,t))continue;let n=m3(a);if(!n)continue;let i=function(e){let t=0;return c2(e.type??"").includes("text")&&(t+=2),m1(e.label)&&(t+=2),m1(e.value)&&(t+=1),t}(a);(!r||i>r.score)&&(r={label:n,score:i})}return r?.label}(t,r);return n||(m3(t)??cQ(t,r))}(a,o,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),mZ(t)&&(a+=3),mZ(e)&&(a+=2),r&&(a+=2),m2(t.identifier)&&(a+=1),m0(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return m9({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,a);let n=r/e.width,i=a/e.height;return m9({x:Math.round((t.x-e.x)*n),y:Math.round((t.y-e.y)*i),width:Math.max(1,Math.round(t.width*n)),height:Math.max(1,Math.round(t.height*i))},r,a)}(n,o.rect,t,r);if(!m4(d))continue;let u=i.get(o.ref);(!u||l>u.score)&&i.set(o.ref,{ref:o.ref,label:s,rect:o.rect,overlayRect:d,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>m5(e.overlayRect)-m5(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(m8(e.overlayRect,r.overlayRect)||m8(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}m5(r.overlayRect)<m5(t[e].overlayRect)&&(t[e]=r)}return t})([...i.values()]).sort((e,t)=>{if(t.score!==e.score)return t.score-e.score;let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:m6(e.ref,t.ref)}).slice(0,a.maxRefs??24).sort((e,t)=>{let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:m6(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:eA(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,n;(function(e,t,r){for(let a=0;a<2;a+=1)he(e,t.x,t.x+t.width-1,t.y+a,r),he(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),ht(e,t.x+a,t.y,t.y+t.height-1,r),ht(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(n=e).overlayRect,mz),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),n=m7(t.x,0,Math.max(0,e.width-a)),i=t.y-11-2,o=i>=0?i:m7(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,n){for(let i=0;i<11;i+=1)for(let o=0;o<a;o+=1)hr(e,t+o,r+i,n)})(e,n,o,a,mJ),function(e,t,r,a,n){let i=t;for(let t of a.toLowerCase()){let a=mX[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&hr(e,i+o,r+t,n);i+=6}}(e,n+3,o+2,r,mK)}(a,n.overlayRect,n.ref)}return await d.writeFile(e.screenshotPath,_.sync.write(t)),r}function mZ(e){let t=[e.type,e.role,e.subrole].map(e=>c2(e??"")).join(" ");return t.includes("button")||t.includes("link")||t.includes("menu")||t.includes("tab")||t.includes("textfield")||t.includes("searchfield")||t.includes("securetextfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("cell")}function mQ(e){let t=[e.type,e.role,e.subrole].map(e=>c2(e??"")).join(" ");return t.includes("application")||t.includes("window")}function m0(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function m1(e){var t;let r;return!!m0(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function m2(e){var t;return"string"==typeof e&&!!m1(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function m3(e){let t=[e.label,e.value].find(m1);return t?t.trim():m2(e.identifier)?e.identifier.trim():void 0}function m4(e){return!!(e&&e.width>0&&e.height>0)}function m5(e){return e.width*e.height}function m8(e,t){return t.x>=e.x&&t.y>=e.y&&t.x+t.width<=e.x+e.width&&t.y+t.height<=e.y+e.height}function m6(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function m9(e,t,r){let a=m7(e.x,0,Math.max(0,t-1)),n=m7(e.y,0,Math.max(0,r-1)),i=Math.max(1,t-a),o=Math.max(1,r-n);return{x:a,y:n,width:m7(e.width,1,i),height:m7(e.height,1,o)}}function m7(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function he(e,t,r,a,n){for(let i=t;i<=r;i+=1)hr(e,i,a,n)}function ht(e,t,r,a,n){for(let i=r;i<=a;i+=1)hr(e,t,i,n)}function hr(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let n=(e.width*r+t)*4;e.data[n]=a[0],e.data[n+1]=a[1],e.data[n+2]=a[2],e.data[n+3]=a[3]}let ha=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),hn=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),hi=new Set(hn),ho=new Map;function hs(e,t,r,a){let n=P().requestId;return{...db(e,t,r,a,n),requestId:n}}async function hl(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||dG(e.flags))try{let t=await l9(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function hd(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,leaseRegistry:i,invoke:o,contextFromFlags:s}=e,l=await mP({req:t,leaseRegistry:i});if(l)return l;let d=await pP({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o});if(d)return d;let u=await p9({req:t,sessionName:r,logPath:a,sessionStore:n});if(u)return u;let c=await f3({req:t,sessionName:r,sessionStore:n,logPath:a});if(c)return c;let p=await fc({req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o});if(p)return p;let f=await mL({req:t,sessionName:r,sessionStore:n,contextFromFlags:s});return f||null}async function hu(e){var t;let r,a,n,i,o,s,l,{req:d,session:u,logPath:c,sessionStore:p}=e,f=d.command;if(!dI(f,u.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${f} is not supported on this device`}};if("android"===u.device.platform&&u.recording&&"record"!==f&&"failed"===await mG({session:u}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:m,resolvedOut:h,recordedPositionals:w,recordedFlags:g}=(r=(t=d).command,a=t.positionals??[],n=t.flags?.out,i="screenshot"===r&&a[0]?[rC.expandHome(a[0],t.meta?.cwd),...a.slice(1)]:a,o="screenshot"===r&&n?rC.expandHome(n,t.meta?.cwd):n,s="screenshot"===r?i:a,l="screenshot"===r&&o?{...t.flags??{},out:o}:t.flags??{},{resolvedPositionals:i,resolvedOut:o,recordedPositionals:s,recordedFlags:l}),y=Date.now(),v={...hs(c,d.flags,u.appBundleId,u.trace?.outPath),surface:u.surface},I=await l7(u.device,f,m,h,{...v});return"screenshot"===f&&d.flags?.overlayRefs&&"string"==typeof I?.path&&await hc(u,I,c),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:n,recordedPositionals:i,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let n=f8(e.snapshot),i={...a??{}},o=mr(i.direction)??mr(r[0]);if(!o)return a;let s=ma(i.amount)??ma(r[1]),l=ma(i.pixels),d=mo(i,[]),u=ma(i.referenceWidth),c=ma(i.referenceHeight),p=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:n??f9;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...i,x1:d.x1,y1:d.y1,x2:d.x2,y2:d.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==l?{pixels:l}:{},referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight,durationMs:250};let f=is({direction:o,amount:s,pixels:l,referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight});return{...i,x1:f.x1,y1:f.y1,x2:f.x2,y2:f.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==f.pixels?{pixels:f.pixels}:{},referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight,durationMs:250}}(t,a,n,s);f7(t,a,n,c,u,l,d),r.recordAction(t,{command:a,positionals:i,flags:o,result:s??{}})}({session:u,sessionStore:p,command:f,resolvedPositionals:m,recordedPositionals:w,recordedFlags:g,data:I,actionStartedAt:y,actionFinishedAt:Date.now(),flags:d.flags??{}}),uS(f)&&uI(u,f),{ok:!0,data:I??{}}}async function hc(e,t,r){let a=pj(await pU({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let n=await mY({screenshotPath:t.path,snapshot:a});t.overlayRefs=n}function hp(e){s.existsSync(e)&&s.unlinkSync(e)}function hf(e){if(!s.existsSync(e))return null;try{let t=JSON.parse(s.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function hm(e){let t=hf(e);if(!t||t.pid===process.pid)try{s.existsSync(e)&&s.unlinkSync(e)}catch{}}function hh(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:hw,infoPath:hg,lockPath:hy,logPath:hv,sessionsDir:hI}=ev(process.env.AGENT_DEVICE_STATE_DIR),hb=eb(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var hA=hI;if(s.existsSync(hA))for(let e of s.readdirSync(hA,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=p.join(hA,e.name,rP);if(s.existsSync(t))try{let e=rR(s.readFileSync(t,"utf8"));if(e&&function(e){let t,r=ey(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=V(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{r$(t)}}let hS=new rC(hI),hN=new aj({maxActiveSimulatorLeases:hh(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:hh(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:hh(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:hh(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),h_=eu(),hx=i.randomBytes(24).toString("hex"),hD=ey(process.pid)??void 0,hM=G(),hk=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:n,trackDownloadableArtifact:i}=e;async function o(e){let s=!!(e.meta?.debug||e.flags?.verbose);return await L({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:s,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:E(new O("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=el(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=q(r);if(r&&!a)throw new O("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new O("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let n=e.session||"default";return n.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${n}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);U({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let s=r.command,l=mC(r);hn.has(s)||r.meta?.sessionIsolation!=="tenant"||n.assertLeaseAdmission({tenantId:l.tenantId,runId:l.runId,leaseId:l.leaseId,backend:l.leaseBackend});let d=function(e,t){var r;let a,n=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==n||t.has(n))return n;let i=t.toArray();return 1===i.length?i[0].name:n}(r,a),u=hi.has(s)?null:await hl(r,d,a),c=async()=>{let e=a.get(d);e&&(!function(e){var t,r;let a,n=e.recording;if(!n||"ios"!==e.device.platform)return;let i=(t=e.device.id,(a=re.get(t))?{sessionId:a.sessionId,alive:!!(r=a.child.pid)&&eg(r)}:null);if(!n.runnerSessionId){i?.alive&&(n.runnerSessionId=i.sessionId);return}if(!i?.alive){n.invalidatedReason??="iOS runner session exited during recording";return}i.sessionId!==n.runnerSessionId&&(n.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(d,e));let l=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},n=t?mR(t,a):function(e,t,r){var a,n;let i=[];if(void 0!==e.platform&&t&&(a=e.platform,n=t,a&&n&&a!==n&&("apple"===a?!tN(n):"apple"!==n||!tN(a)))&&i.push({key:"platform",value:e.platform}),"open"===r)return i;for(let t of m$){let r=e[t];"string"==typeof r&&r.trim().length>0&&i.push({key:t,value:r})}return i}(a,e.meta?.lockPlatform,e.command);if(0===n.length)return!t&&e.meta?.lockPlatform&&void 0===a.platform&&(a.platform=e.meta.lockPlatform),{...e,flags:a};if("strip"===r)return t?(function(e,t){for(let r of t)delete e[r.key]}(a,n),a.platform=t.device.platform):function(e,t){for(let t of m$)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new O("INVALID_ARGS",`${e.command} cannot override session lock policy with ${n.map(mT).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),u=e=>(function(e,t,r){let a=P();if(!t.ok){U({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=R({force:!0})??void 0;return{ok:!1,error:E(new O(t.error.code,t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return U({level:"info",phase:"request_success"}),R(),{ok:!0,data:function(e,t,r){var a,n;let i;if(!t)return t;let o=(a=e,n=t,i=Array.isArray(n.artifacts)?[...n.artifacts]:[],"screenshot"!==a.command||i.some(e=>e?.field==="path")||"string"!=typeof n.path||i.push({field:"path",path:n.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:p.basename(a.meta?.clientArtifactPaths?.path??n.path)}),i.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===o.length?t:{...t,artifacts:o.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(l,e,i);if(e?.recording?.invalidatedReason&&"record"!==s&&"close"!==s)return u({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||l.meta?.lockPolicy||ha.has(s)||function(e,t){let r=mR(e,t);if(0!==r.length){var a;let t,n,i;throw new O("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,n=a.device.name.trim(),i=a.device.id,`${t} device "${n}" (${i})`)} and cannot be used with ${r.map(mT).join(", ")}. Use a different --session name or close this session first.`)}}(e,l.flags);let c=await hd({req:l,sessionName:d,logPath:t,sessionStore:a,leaseRegistry:n,invoke:o,contextFromFlags:(e,r,n)=>({...hs(t,e,r,n),surface:a.get(d)?.surface})});if(c)return u(c);let f=a.get(d);if(!f)return u({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await hu({req:l,session:f,sessionName:d,logPath:t,sessionStore:a});return u(m)};if(!u)return await c();return await tS(ho,u,c)}catch(r){U({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=P(),t=R({force:!0})??void 0;return{ok:!1,error:E(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return o}({logPath:hv,token:hx,sessionStore:hS,leaseRegistry:hN,trackDownloadableArtifact:function(e){let t=i.randomUUID(),r=setTimeout(()=>{af(t)},9e5);return r.unref(),ap.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){s.existsSync(e)||s.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return s.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let i=hf(t);if(i?.pid&&i.pid!==process.pid&&H(i.pid,i.processStartTime))return!1;try{s.unlinkSync(t)}catch{}return n()}(hw,hy,{pid:process.pid,version:h_,startedAt:Date.now(),processStartTime:hD})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===hb||"dual"===hb){let t=f.createServer(e=>{let t="",r=0,a=new Set,n=!1,i=()=>{if(!n&&0!==r){for(let e of(n=!0,a))eJ(e);U({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await rs(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){U({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:r}})}})()}};e.setEncoding("utf8"),e.on("close",i),e.on("error",i),e.on("data",async n=>{let i=(t+=n).indexOf("\n");for(;-1!==i;){let n,o,s=t.slice(0,i).trim();if(t=t.slice(i+1),0===s.length){i=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eW(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),ez(o),eX(o))throw eZ();n=await hk(e)}catch(e){n={ok:!1,error:E(e)}}finally{r-=1,o&&(a.delete(o),eK(o))}e.destroyed||e.write(`${JSON.stringify(n)}
70
+ `),i=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new O("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===hb||"dual"===hb){let e=await aT({handleRequest:hk,token:hx});r.push(e),t=await new Promise((t,r)=>{e.once("error",r),e.listen(0,"127.0.0.1",()=>{e.off("error",r);let a=e.address();"object"==typeof a&&a?.port?t(a.port):r(new O("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:hx,version:h_,codeSignature:hM,processStartTime:hD},s.existsSync(hw)||s.mkdirSync(hw,{recursive:!0}),s.writeFileSync(hv,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",s.writeFileSync(hg,JSON.stringify({port:a.socketPort,httpPort:a.httpPort,transport:n,token:a.token,pid:process.pid,version:a.version,codeSignature:a.codeSignature,processStartTime:a.processStartTime,stateDir:hw},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
71
71
  `),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${t}
72
- `)}catch(t){let e=j(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
73
- `),r))try{t.close(()=>{})}catch{}hp(hg),hm(hy),process.exit(1);return}let n=!1,i=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},o=async()=>{if(!n){for(let e of(n=!0,await i(),hS.toArray()))hS.writeSessionLog(e);await rl(),hp(hg),hm(hy),process.exit(0)}};process.on("SIGINT",()=>{o()}),process.on("SIGTERM",()=>{o()}),process.on("SIGHUP",()=>{o()}),process.on("uncaughtException",e=>{let t=e instanceof W?e:j(e);process.stderr.write(`Daemon error: ${t.message}
74
- `),o()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof W?t:j(t);process.stderr.write(`Daemon error: ${r.message}
72
+ `)}catch(t){let e=k(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
73
+ `),r))try{t.close(()=>{})}catch{}hp(hg),hm(hy),process.exit(1);return}let n=!1,i=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},o=async()=>{if(!n){for(let e of(n=!0,await i(),hS.toArray()))hS.writeSessionLog(e);await rl(),hp(hg),hm(hy),process.exit(0)}};process.on("SIGINT",()=>{o()}),process.on("SIGTERM",()=>{o()}),process.on("SIGHUP",()=>{o()}),process.on("uncaughtException",e=>{let t=e instanceof O?e:k(e);process.stderr.write(`Daemon error: ${t.message}
74
+ `),o()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof O?t:k(t);process.stderr.write(`Daemon error: ${r.message}
75
75
  `),o()})}();