agent-device 0.11.15 → 0.11.16

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,15 +1,12 @@
1
- let e,t;import r from"node:crypto";import a,{promises as i}from"node:fs";import n from"node:path";import{spawn as o}from"node:child_process";import s from"node:http";import{URL as l,fileURLToPath as d,pathToFileURL as u}from"node:url";import"node:https";import c from"node:os";import f from"node:fs/promises";import{setTimeout as p}from"node:timers/promises";import{PNG as m}from"pngjs";import h from"node:net";import{isApplePlatform as g,normalizePlatformSelector as w,readProcessCommand as v,buildSimctlArgs as y,dispatchCommand as I,resolveAppleSimulatorSetPathForSelector as S,isAgentDeviceDaemonProcess as A,validateAndNormalizeBatchSteps as b,parseSessionSurface as _,centerOfRect as N,attachRefs as x,isFillableType as k,isNodeVisibleInEffectiveViewport as M,resolveDeployResultTarget as D,listIosDeviceApps as P,buttonTag as L,handleSnapshotCommands as R,inferFillText as O,resolveSelectorChain as $,normalizeType as C,buildSelectorChainForNode as E,withSuccessText as T,shutdownSimulator as F,buildScrollGesturePlan as U,decodePng as G,stopIosRunnerSession as V,splitSelectorFromArgs as q,formatSelectorFailure as j,IOS_RUNNER_CONTAINER_BUNDLE_IDS as B,resolveIosDevicectlHint as H,createRequestCanceledError as K,registerRequestAbort as z,resolveSessionIsolationMode as W,errorResponse as J,isNavigationSensitiveAction as Z,findNodeByRef as Y,successText as X,pickLargestRect as Q,uniqueStrings as ee,pruneGroupNodes as et,withKeyedLock as er,getClickButtonValidationError as ea,resolveTargetDevice as ei,normalizeRef as en,parseSerialAllowlist as eo,classifyAndroidAppTarget as es,DEFAULT_BATCH_MAX_STEPS as el,runMacOsAlertAction as ed,extractNodeReadText as eu,stopAllIosRunnerSessions as ec,findSelectorChainMatch as ef,isDeepLinkTarget as ep,contextFromFlags as em,rect_visibility_containsPoint as eh,resolveDaemonCodeSignature as eg,getAndroidScreenSize as ew,getAndroidAppState as ev,isNodeEditable as ey,extractNodeText as eI,isNodeVisible as eS,captureSnapshot as eA,parseSelectorChain as eb,normalizeTenantId as e_,snapshotAndroid as eN,parseTimeout as ex,resolveTimeoutMs as ek,IOS_DEVICECTL_DEFAULT_HINT as eM,buildSnapshotState as eD,resolveClickButton as eP,openAndroidApp as eL,captureSnapshotData as eR,distanceFromSafeViewportBand as eO,splitIsSelectorArgs as e$,isRequestCanceled as eC,resolveRequestTrackingId as eE,adbArgs as eT,resolveRefLabel as eF,resolvePayloadInput as eU,resolveEffectiveViewportRect as eG,abortAllIosRunnerSessions as eV,getRunnerSessionSnapshot as eq,formatAndroidInstalledPackageRequiredMessage as ej,resolveViewportRect as eB,resolveIosSimulatorDeviceSetPath as eH,markRequestCanceled as eK,resolveIosDeviceDeepLinkBundleId as ez,tryParseSelectorChain as eW,runIosRunnerCommand as eJ,resolveUserPath as eZ,ensureDeviceReady as eY,readVersion as eX,readInfoPlistString as eQ,clearRequestCanceled as e0,buildSimctlArgsForDevice as e1,getActiveAndroidSnapshotFreshness as e2,findBestMatchesByLocator as e5,parseXmlDocumentSync as e4,findNearestHittableAncestor as e3,resolveFrontmostMacOsApp as e8,IOS_SIMCTL_LIST_TIMEOUT_MS as e6,findNodeByLabel as e7,matchesPlatformSelector as e9,readProcessStartTime as te,resolveDaemonPaths as tt,resolveAndroidSerialAllowlist as tr,listIosDeviceProcesses as ta,isCommandSupportedOnDevice as ti,markAndroidSnapshotFreshness as tn,resolveDaemonServerMode as to,resolveInstallFromSourceResultTarget as ts,getRequestSignal as tl}from"./760.js";import{asAppError as td,normalizeError as tu,AppError as tc,withDiagnosticsScope as tf,runCmdBackground as tp,getDiagnosticsMeta as tm,flushDiagnosticsToSessionFile as th,withDiagnosticTimer as tg,runCmd as tw,emitDiagnostic as tv}from"./818.js";let ty=/^-?\d+(\.\d+)?$/,tI=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tS=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tA=new Map([["--delay-ms","delayMs"]]);function tb(e){return"click"===e||"press"===e}function t_(e){return"type"===e||"fill"===e}function tN(e){let t=e.trim();return t.startsWith("@")||ty.test(t)?t:JSON.stringify(t)}function tx(e){return JSON.stringify(e)}function tk(e){let t=e.trim();return/\s/.test(t)?JSON.stringify(t):t}function tM(e,t){let r=t.flags??{};if(tb(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}t_(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tD(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",tk(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",tk(t.bundleUrl)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tk(t.launchUrl)))}function tP(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tk(r)),a))e.push(tN(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),t.flags?.hideTouches&&e.push("--hide-touches")}function tL(e,t){let r=[],a={},i=tb(e)?tI:"swipe"===e?tS:t_(e)?tA:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(tb(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(tb(e)&&"--button"===o&&n+1<t.length){let e=t[n+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),n+=1;continue}let s=i?.get(o);if(s&&n+1<t.length){let e=tO(t[n+1]);if(null!==e){a[s]=e,n+=1;continue}}if("swipe"===e&&"--pattern"===o&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(o)}return{positionals:r,flags:a}}function tR(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let i=e[a];if("--platform"===i&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===i&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===i&&a+1<e.length){let t=tO(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===i&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===i&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(i)}return{positionals:t,flags:r}}function tO(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function t$(e,t){for(let r of t.positionals??[])e.push(tN(r));t.flags?.relaunch&&e.push("--relaunch"),tD(e,t.runtime)}class tC{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=tC.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 t={};for(let r of tE)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),tv({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=n.dirname(t);a.existsSync(r)||a.mkdirSync(r,{recursive:!0});let i=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let i of(r.push(`context platform=${e.device.platform} device=${tx(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(tb(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tN(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tN(a)),tM(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tN(r)),tM(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tN(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tN(a)),i&&t.push(tN(i)),tM(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tN(r)),t.push(tN(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tN(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",tN(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tN(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return t$(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tk(r)),tD(t,e.flags),t.join(" ")}if("record"===e.command)return tP(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tN(r));return tM(t,e),t.join(" ")}(i));return`${r.join("\n")}
2
- `}(e,this.buildOptimizedActions(e));a.writeFileSync(t,i)}catch{}}defaultTracePath(e){let t=tC.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return n.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return n.join(this.sessionsDir,tC.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return n.join(this.sessionsDir,tC.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return eZ(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tC.expandHome(e.saveScriptPath);a.existsSync(this.sessionsDir)||a.mkdirSync(this.sessionsDir,{recursive:!0});let t=tC.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return n.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&&(tb(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(tb(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=O(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(tb(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 tE=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw","screenshotFullscreen","relaunch","saveScript","noRecord","fps","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"],tT="app-log.pid";function tF(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 tU(e,t){if(!e)return;let r=n.dirname(e);a.existsSync(r)||a.mkdirSync(r,{recursive:!0});let i={pid:t,startTime:te(t)??void 0,command:v(t)??void 0};a.writeFileSync(e,`${JSON.stringify(i)}
3
- `)}function tG(e){if(e&&a.existsSync(e))try{a.unlinkSync(e)}catch{}}async function tV(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}async function tq(e){await new Promise(t=>setTimeout(t,e))}function tj(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],a="",i=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))i(`${e}
4
- `)},flush:()=>{a&&(i(a),a="")}}}function tB(e,t,r){let a=e.stdout,i=e.stderr;return a&&i?(a.setEncoding("utf8"),i.setEncoding("utf8"),a.on("data",r.writer.onChunk),i.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 tH(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new tc("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tK(e,t){let r=(await tw("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tz(e,t){var r,a;let i;tH(t);let n=await tK(e,t),o=await tw("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 i of(r&&a.add(r),e.split("\n")))if(i.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")],i=[];for(let t of a){let r=t.exec(e),a=r?.[1];a&&/^\d+$/.test(a)&&i.push(a)}return i}(i,t))a.add(e);return[...a]}(o.stdout,t,n);if(0===s.length)return null;let l=(r=o.stdout,a=t,i=new Set(s),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(a))return!0;let n=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!n&&i.has(n)}).join("\n"));return 0===l.trim().length?null:{pid:n,text:l,recoveredPids:s}}async function tW(e,t,r,a,i){let n,s,l="recovering",d=!1,u=(async()=>{try{for(;!d;){let u=await tK(e,t);if(!u){l="recovering",await tq(1e3);continue}let c=o("adb",["-s",e,"logcat","-v","time","--pid",u],{stdio:["ignore","pipe","pipe"]});n=c;let f=tj(r,{redactionPatterns:a});if(s=tB(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&(tU(i,c.pid),l="active"),await s,tG(i),n=void 0,s=void 0,d)break;l="recovering",await tq(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tG(i)}})();return{backend:"android",getState:()=>l,startedAt:Date.now(),wait:u,stop:async()=>{d=!0,n&&!n.killed&&n.kill("SIGINT"),s&&await tV(s),n&&!n.killed&&n.kill("SIGKILL"),await tV(u),tG(i)}}}function tJ(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function tZ(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=y(["spawn",t,"log","show","--style","compact","--info","--predicate",tJ(r)],{simulatorSetPath:i});"number"==typeof a&&Number.isFinite(a)&&a>0?n.push("--start",`@${Math.floor(a/1e3)}`):n.push("--last","5m");let o=await tw("xcrun",n,{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")}
5
- `,recoveredLineCount:s.length}}async function tY(e,t,r,a,i,n){let s="active",l=o("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return y(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tJ(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tj(r,{redactionPatterns:a});"number"==typeof l.pid&&tU(n,l.pid);let u=tB(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(s="failed"),tG(n),e));return{backend:"ios-simulator",getState:()=>s,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tV(u),l.killed||l.kill("SIGKILL"),await tV(u),tG(n)}}}async function tX(e,t,r,a){let i="active",n=o("log",["stream","--style","compact","--predicate",tJ(e)],{stdio:["ignore","pipe","pipe"]}),s=tj(t,{redactionPatterns:r});"number"==typeof n.pid&&tU(a,n.pid);let l=tB(n,t,{endStreamOnClose:!0,writer:s}).then(e=>(0!==e.exitCode&&(i="failed"),tG(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tV(l),n.killed||n.kill("SIGKILL"),await tV(l),tG(a)}}}async function tQ(e,t,r,a){let i="active",n=o("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),s=tj(t,{redactionPatterns:r});"number"==typeof n.pid&&tU(a,n.pid);let l=tB(n,t,{endStreamOnClose:!0,writer:s}).then(e=>(0!==e.exitCode&&(i="failed"),tG(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tV(l),n.killed||n.kill("SIGKILL"),await tV(l),tG(a)}}}let t0=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),t1=/https?:\/\/[^\s"'<>\])]+/i,t2=[/\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 t5(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t3(e)));for(let e of t.entries){let t=t3(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t4(e,t){let r=rn(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=rn(t?.maxPayloadChars,2048,64,16384),o=rn(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,i,n){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=rt(s,["method","httpMethod"]),d=rt(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=t0.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=t1.exec(o),h=d??m?.[0];if(!h)return null;let g=u??t6(o)??void 0;if(!(l||f?.[1]||c?.[1]||void 0!==g||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let w={method:p,url:h,status:g,timestamp:t7(o),packetId:t9(o)??void 0,durationMs:re(o)??void 0,raw:ri(o,n),line:r};if("android"===a&&function(e,t,r){let a=t8(t,r,5),i=e.packetId??a.map(e=>t9(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t8(t,r,12).filter(e=>t9(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>t7(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>t6(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>re(e)).find(e=>"number"==typeof e))}(w,e,t),"headers"===i||"all"===i){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return ra(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=ri(e,n))}if("body"===i||"all"===i){let e=rr(o,s,["requestBody","body","payload","request"]),t=rr(o,s,["responseBody","response"]);e&&(w.requestBody=ri(e,n)),t&&(w.responseBody=ri(t,n))}return w}(d,e,l+e+1,a,i,n);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:o}}}function t3(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function t8(e,t,r){let a=[],i=Math.max(0,t-r),n=Math.min(e.length-1,t+r);for(let t=i;t<=n;t+=1){let r=e[t]?.trim();r&&a.push(r)}return a}function t6(e){for(let t of t2){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function t7(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 t9(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function re(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 rt(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 rr(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return ra(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 ra(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ri(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function rn(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function ro(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 rs(e){let t=n.dirname(e);a.existsSync(t)||a.mkdirSync(t,{recursive:!0}),function(e,t){if(a.existsSync(e)&&!(a.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,i=`${e}.${r}`;a.existsSync(t)&&(a.existsSync(i)&&a.unlinkSync(i),a.renameSync(t,i))}}(e,{maxBytes:ro("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:ro("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function rl(e){var t,r,i,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v}=e,y="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:y,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v},o=rn(t?.maxEntries,25,1,200),s=t?.include??"summary",l=rn(t?.maxPayloadChars,2048,64,16384),d=rn(t?.maxScanLines,4e3,100,2e4),a.existsSync(m)?t4(a.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:d}}),S=[],A=await rd({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tz(u.id,c);if(e){let t=t4(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v});t.entries.length>0&&(I=t5(t,I,h),S.push((r=A,i=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 ${i.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${i.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await rc({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v});e&&(e.dump.entries.length>0?(I=t5(e.dump,I,h),S.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&&S.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===f?S.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===S.length&&("ios"===u.platform&&"simulator"===u.kind?S.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."):S.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&S.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:y,dump:I,notes:S}}async function rd(e){let{device:t,appBundleId:r,appLogPath:i,appLogState:o}=e;if("android"!==t.platform||!r)return null;if(void 0!==o&&"active"!==o)return{reason:"inactive"};if("active"!==o)return null;let s=function(e){let t=function(e){if(!e||!a.existsSync(e))return null;try{return tF(a.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}(n.join(n.dirname(i),tT));if(!s)return null;let l=await tK(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function ru(e,t,r,i){rs(r);let n=a.createWriteStream(r,{flags:"a"}),o=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 tQ(e.id,n,o,i):await tY(e.id,t,n,o,e.simulatorSetPath,i);if("android"===e.platform)return tH(t),await tW(e.id,t,n,o,i);if("macos"===e.platform)return await tX(t,n,o,i);throw n.end(),new tc("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rc(e){let t=await tZ({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t4(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 rf(e){await e.stop(),await tV(e.wait)}async function rp(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 tw("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await tw("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 tw("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 tw("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await tw("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rm(e){let t=n.dirname(e),r=n.basename(e);a.existsSync(t)||a.mkdirSync(t,{recursive:!0}),a.existsSync(e)?a.truncateSync(e,0):a.writeFileSync(e,"","utf8");let i=0;for(let e of a.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let o=e.slice(r.length+1);if(/^\d+$/.test(o))try{a.unlinkSync(n.join(t,e)),i+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:i}}let rh=new Map;function rg(e){let t=rh.get(e);if(t&&(clearTimeout(t.timer),rh.delete(e),t.deleteAfterDownload))try{a.rmSync(t.artifactPath,{force:!0})}catch{}}let rw=new Map;function rv(e,t){let r=rw.get(e);if(!r)throw new tc("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tc("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function ry(e){let t=rw.get(e);t&&(clearTimeout(t.timer),rw.delete(e),a.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rI(e){let t=await rS(e);await tw("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=n.join(e.tempDir,t);if(!a.existsSync(r))throw new tc("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rS(e){let t=await tw("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new tc("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 tc("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(rA),i=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 tc("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new tc("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 tc("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===i||e.startsWith(`${i}/`)))throw new tc("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,o=i;if(n!==o&&!n.startsWith(`${o}/`))throw new tc("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await tw("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new tc("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function rA(e){if(e.includes("\0"))throw new tc("INVALID_ARGS",`Invalid archive entry: ${e}`);if(n.posix.isAbsolute(e))throw new tc("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=n.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new tc("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rb=ek(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function r_(e,t){return new Promise((r,i)=>{let n,o=a.createWriteStream(t),s=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){o.destroy(),a.rmSync(t,{force:!0}),i(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new tc("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rb});s(e),o.destroy(e),u(e)},rb)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new tc("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");s(e),o.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new tc("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",u),o.on("finish",()=>u()),c(),e.pipe(o)})}async function rN(e){let t,r=e.headers["x-artifact-type"],i=e.headers["x-artifact-filename"];if(!r||!i)throw new tc("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new tc("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 tc("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let o=function(e){let t=e.trim(),r=n.basename(t);if(!r||"."===r||".."===r)throw new tc("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(i),s=(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"),a.mkdtempSync(n.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=n.join(s,o);return await r_(e,t),{artifactPath:t,tempDir:s}}let t=n.join(s,"artifact.tar");await r_(e,t);let i=await rI({archivePath:t,tempDir:s,platform:"ios",expectedRootName:o});return a.rmSync(t,{force:!0}),{artifactPath:i,tempDir:s}}catch(e){throw a.rmSync(s,{recursive:!0,force:!0}),e}}let rx=new Set(["agent_device.command","agent-device.command"]),rk=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rM=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rD={"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"},rP=new Set([...rx,...rk,...rM,...Object.keys(rD)]);function rL(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rR(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rO(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function r$(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function rC(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rE(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function rT(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=tu(new tc("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rL(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=tu(new tc(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rL(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=e_(r.tenantId);if(!e){let e=tu(new tc("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rL(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rF(){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=n.isAbsolute(t)?t:n.resolve(t);try{e=await import(u(a).href)}catch(e){throw new tc("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let i=e[r];if("function"!=typeof i)throw new tc("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rU(e){let t=await rF(),{handleRequest:r,token:a}=e;return s.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void rG(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void rV(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||rR(i,rL(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rR(i,rL(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rR(i,rL(a.id??null,-32600,"Invalid Request"),400);if(!rP.has(a.method))return void rR(i,rL(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rR(i,rL(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(rx.has(e))return{token:r$(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(rk.has(e)){let e,a=rC(t,"platform");if("ios"!==a&&"android"!==a)throw new tc("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:r$(t,r),session:rC(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rC(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new tc("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new tc("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 tc("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 tc("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 tc("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new tc("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rE(t,"retentionMs")}}}if(rM.has(e)){let e=rC(t,"materializationId")?.trim();if(!e)throw new tc("INVALID_ARGS","Invalid params: materializationId is required");return{token:r$(t,r),session:rC(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rC(t,"requestId"),materializationId:e}}}let a=rD[e];if(a)return{token:r$(t,r),session:rC(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rC(t,"tenantId")??rC(t,"tenant"),runId:rC(t,"runId"),leaseId:rC(t,"leaseId"),leaseTtlMs:rE(t,"ttlMs"),leaseBackend:rC(t,"backend")}};throw new tc("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rx.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rR(i,rL(a.id??null,-32602,"Invalid params: command is required"),400);o=eE(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},z(o);let d=()=>{i.writableFinished||eK(o)};e.on("aborted",d),i.on("close",d);let u=await rT(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rR(i,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 rR(i,{jsonrpc:"2.0",id:a.id??null,result:c});rR(i,rL(a.id??null,-32e3,c.error.message,c.error),rO(c.error.code))}catch(t){let e=tu(t);rR(i,rL(a.id??null,-32e3,e.message,e),rO(e.code))}finally{e0(o)}})})}async function rG(e,t,a,i){try{var n;let o,s,l=r$({},e.headers),d=rq(l,i);if(d){t.statusCode=rO(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await rT(a,{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 rN(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=r.randomUUID(),(s=setTimeout(()=>{ry(o)},3e5)).unref(),rw.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:f}))}catch(r){let e=tu(r);t.statusCode=rO(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rV(e,t,r,i){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=r$({},e.headers),s=rq(o,i);if(s){t.statusCode=rO(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await rT(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:o,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=rh.get(e);if(!r)throw new tc("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tc("UNAUTHORIZED","Artifact belongs to a different tenant");if(!a.existsSync(r.artifactPath))throw rg(e),new tc("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=a.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=tu(e);t.statusCode=rO(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&rg(n)}),u.pipe(t)}catch(r){let e=tu(r);t.statusCode=rO(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rq(e,t){return t&&e!==t?tu(new tc("UNAUTHORIZED","Invalid token")):null}function rj(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rB(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rH(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";throw new tc("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rK{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=rH(e.backend),a=e_(e.tenantId);if(!a)throw new tc("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rj(e.runId);if(!i)throw new tc("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(a,i,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:r.randomBytes(16).toString("hex"),tenantId:a,runId:i,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=rB(e.leaseId);if(!t)throw new tc("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new tc("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=rB(e.leaseId);if(!t)throw new tc("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=rH(e.backend),r=e_(e.tenantId);if(!r)throw new tc("INVALID_ARGS","tenant isolation requires tenant id.");let a=rj(e.runId);if(!a)throw new tc("INVALID_ARGS","tenant isolation requires run id.");let i=rB(e.leaseId);if(!i)throw new tc("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new tc("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new tc("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 tc("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 tc("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=e_(t),i=rj(r);if(t&&!a)throw new tc("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new tc("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new tc("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rz=ek(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rW=new Map;async function rJ(e){let t=await f.mkdtemp(n.join(c.tmpdir(),"agent-device-materialized-"));try{let a=await rX(e.installablePath,n.join(t,"installable")),i=e.archivePath?await rX(e.archivePath,n.join(t,"archive")):void 0,o=r.randomUUID(),s=e.ttlMs??rz,l=Date.now()+s,d=setTimeout(()=>{rZ(o)},s);return rW.set(o,{rootPath:t,installablePath:a,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:o,installablePath:a,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await f.rm(t,{recursive:!0,force:!0}),e}}async function rZ(e,t){let r=rW.get(e);if(!r)throw new tc("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tc("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rW.delete(e),await f.rm(r.rootPath,{recursive:!0,force:!0})}async function rY(e){let t=Array.from(rW.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await rZ(e)}))}async function rX(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=n.join(t,n.basename(e));return r.isDirectory()?await f.cp(e,a,{recursive:!0}):await f.copyFile(e,a),a}async function rQ(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 tc("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await eY(e.session.device),e.session.device}if(!r)throw new tc("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await ei(e.flags??{});return await eY(a),a}async function r0(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,o,s=(n=function(e){let t=e.meta?.installSource;if(!t)throw new tc("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new tc("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new tc("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:rv(o,t.meta?.tenantId)},cleanup:()=>{ry(o)}}:{source:n,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 tc("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await rQ({session:i,flags:t.flags});if(!ti("install",d))return J("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=tl(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:n}=await import("./760.js"),{prepareIosInstallArtifact:o}=await import("./760.js"),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await rJ({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs})),await n(d,c.installablePath),!c.bundleId)throw new tc("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=T(o,r1(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await rZ(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./760.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./760.js"),p=await c(s.source,{signal:u});try{l.enabled&&(e=await rJ({archivePath:p.archivePath,installablePath:p.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs}));let n=await f(d,p.installablePath,p.packageName);if(!n)throw new tc("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./760.js"),s=o(n),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...s?{appName:s}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=T(u,r1(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await rZ(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:tu(e)}}}function r1(e){return`Installed: ${ts(e)}`}async function r2(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new tc("INVALID_ARGS","release_materialized_paths requires a materializationId");return await rZ(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:tu(e)}}}let r5=ek(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r4=ek(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r3(e,t,r){return t||r8(r)?null:J("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function r8(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function r6(e){return"ios"===e.platform&&"simulator"===e.kind}async function r7(e,t){r6(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function r9(e){let t=r8(e.flags)||!e.session?await ei(e.flags??{}):await ae(e.session.device);return!1!==e.ensureReady&&await eY(t),t}async function ae(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 ei(t)}catch(e){if(!(e instanceof tc)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await ei({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function at(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 ar="shared_prefs/ReactNativeDevPrefs.xml",aa="debug_http_host",ai="dev_server_https",an="RCT_jsLocation",ao="RCT_packager_scheme",as="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.",al='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function ad(e){return void 0!==au(e)}function au(e){if(!e)return;let t=aA(e.metroHost),r=a_(e.metroPort),a="http",i=aA(e.bundleUrl);if(i){var n;let e;try{e=new l(i)}catch(e){throw new tc("INVALID_ARGS",`Invalid runtime bundle URL: ${i}`,{},e)}("http:"===e.protocol||"https:"===e.protocol)&&(t??=aA(e.hostname),r??=a_(e.port.length>0?Number(e.port):"https:"===(n=e.protocol)?443:"http:"===n?80:void 0),a="https:"===e.protocol?"https":"http")}if(t&&r)return{host:t,port:r,scheme:a}}async function ac(e){let{device:t,appId:r,runtime:a}=e;if(!r)return;let i=au(a);if(i){if("android"===t.platform)return void await ap(t,r,i);"ios"===t.platform&&"simulator"===t.kind&&await aw(t,r,i)}}async function af(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await am(t,r);"ios"===t.platform&&"simulator"===t.kind&&await av(t,r)}}async function ap(e,t,r){var a,i,n,o,s,l;let d,u;ab(t);let c=(a=await ah(e,t),i=aa,n=`${r.host}:${r.port}`,d=` <string name="${aN(i)}">${aN(n)}</string>`,aI(aS(a,i),d));o=c,s=ai,l="https"===r.scheme,u=` <boolean name="${aN(s)}" value="${l?"true":"false"}" />`,c=aI(aS(o,s),u),await ag(e,t,c)}async function am(e,t){ab(t);let r=await ah(e,t),a=aS(r,aa),i=aS(a,ai);i!==r&&await ag(e,t,i)}async function ah(e,t){let r=await tw("adb",eT(e,["shell","run-as",t,"cat",ar]),{allowFailure:!0});return 0!==r.exitCode?al:ay(r.stdout)}async function ag(e,t,r){let a=eT(e,["shell","run-as",t,"id"]),i=await tw("adb",a,{allowFailure:!0});if(0!==i.exitCode){let e=ax(i.stdout,i.stderr);throw new tc("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:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:e?as:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await tw("adb",eT(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await tw("adb",eT(e,["shell","run-as",t,"tee",ar]),{stdin:r.trimEnd()})}catch(a){let e=td(a);if("TOOL_MISSING"===e.code)throw e;let r=ax("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new tc("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?as:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function aw(e,t,r){await tw("xcrun",e1(e,["spawn",e.id,"defaults","write",t,an,"-string",`${r.host}:${r.port}`])),await tw("xcrun",e1(e,["spawn",e.id,"defaults","write",t,ao,"-string",r.scheme]))}async function av(e,t){await tw("xcrun",e1(e,["spawn",e.id,"defaults","delete",t,an]),{allowFailure:!0}),await tw("xcrun",e1(e,["spawn",e.id,"defaults","delete",t,ao]),{allowFailure:!0})}function ay(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
6
- `:al}function aI(e,t){return ay(e).replace("</map>",`${t}
7
- </map>`)}function aS(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return ay(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 aA(e){let t=e?.trim();return t&&t.length>0?t:void 0}function ab(e){if("binary"!==es(e))return;let t=ej(e);throw new tc("INVALID_ARGS",t,{package:e,hint:t})}function a_(e){if(Number.isInteger(e)&&!(e<=0)&&!(e>65535))return e}function aN(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function ax(e,t){let r=`${e}
8
- ${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 ak=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function aM(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function aD(e){let t=e?.trim();return t&&t.length>0?t:void 0}function aP(e,t){if(void 0!==e){if("string"!=typeof e)throw new tc("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return aD(e)}}function aL(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new tc("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function aR(e){if("ios"===e||"android"===e)return e}async function aO(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!ad(r)||ad(a)||await af({device:i.device,appId:i.appBundleId})}async function a$(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(o))return J("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){ad(l)&&s?.appBundleId&&await af({device:s.device,appId:s.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===o)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let d=aR(w(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return J("INVALID_ARGS","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 J("INVALID_ARGS",`runtime set targets ${d}, but session "${i}" is already bound to ${s.device.platform}.`);let u={platform:(t=a.flags,r={platform:d,metroHost:aD(t?.metroHost),metroPort:aL(t?.metroPort),bundleUrl:aD(t?.bundleUrl),launchUrl:aD(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===aM(u)?J("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(n.setRuntimeHints(i,u),{ok:!0,data:{session:i,configured:!0,runtime:u}})}let aC="open-command-roundtrip",aE="Not implemented for this platform in this release.",aT=new Set(["app","desktop","frontmost-app"]);async function aF(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await e8();return{appBundleId:t.bundleId,appName:t.appName}}async function aU(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return ep(t)?"macos"===e.platform?void 0:"device"===e.kind?ez(r,t):void 0:await aG(e,t)}async function aG(e,t){try{let{resolveIosApp:r}=await import("./760.js");return await r(e,t)}catch{return}}async function aV(e,t){if(!("android"!==e.platform||!t||ep(t)))try{let{resolveAndroidApp:r}=await import("./760.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function aq(e,t,r,a){return await aU(e,t,r)??await a(e,t)??("android"===e.platform&&t&&ep(t)?r:void 0)}function aj(e){return J("INVALID_ARGS",e)}function aB(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:i}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return i??"app";if("linux"===t.platform){if(!r)return"app";let e=_(r);if(!aT.has(e))throw new tc("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new tc("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new tc("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?_(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new tc("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return J(e instanceof tc?e.code:"INVALID_ARGS",String(e.message))}}function aH(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&ep(r)?aj("open --relaunch does not support URL targets."):"app"!==a?aj("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===es(r)?aj(ej(r)):null:null}async function aK(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await eY(i);let{appBundleId:l,appName:d}=await az({device:i,surface:n,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=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 tc("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ak.includes(e));if(i)throw new tc("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ak.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new tc("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new tc("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:aP(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new tc("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return aL(e)}}(t.metroPort),bundleUrl:aP(t.bundleUrl,"bundleUrl"),launchUrl:aP(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:aR(i.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let i=r?.platform,n=aR(i);if(a.platform&&r&&!n)throw new tc("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${i}.`);if(a.platform&&n&&a.platform!==n)throw new tc("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${i}. Clear the runtime hints or use a different session.`);return n&&a.platform!==n?{...a,platform:n}:a}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&aM(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=td(t);return J(e.code,e.message,e.details)}}({req:t,sessionStore:a,sessionName:r,device:i});if(!u.ok)return{type:"response",response:u};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await aO({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function az(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await aF(r);return{appBundleId:n.appBundleId??await aq(t,a,i,aV),appName:n.appName??a}}let aW=new Map;async function aJ(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await V(t.id),await I(t,"close",[r],a,i),await r7(t,r5)}async function aZ(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||ep(d)||await I(r,"open",[l],a.flags?.out,{...em(i,a.flags,n,o)})}async function aY(e){var t,r,a;let{req:i,sessionName:n,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:f,appBundleId:p,runtime:m,existingSession:h}=e,g=i.flags?.relaunch===!0,w=h?.trace?.outPath;if(g&&d){let e=p??d;await aJ({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...em(s,i.flags,p??h?.appBundleId,w)}})}await ac({device:l,appId:p,runtime:m});let v=Date.now();await I(l,"open",u,i.flags?.out,{...em(s,i.flags,p)}),await aZ({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:u});let y=d?{durationMs:Math.max(0,Date.now()-v),measuredAt:new Date().toISOString(),method:aC,appTarget:d,appBundleId:p}:void 0;if(await r7(l,r4),eC(i.meta?.requestId)){let e=K();return J(e.code,e.message,e.details)}h&&tn(h,"open",h.snapshot);let S=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:n,device:l,surface:f,appBundleId:p,appName:c,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(t=o,r=n,(a=m)&&(0===aM(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let A=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:i};return r&&(d.appName=r),a&&(d.appBundleId=a),n&&(d.startup=n),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,...X(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:y,device:l,runtime:m,runtimeHintCount:aM});return o.recordAction(S,{command:"open",positionals:u,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:A}),o.set(n,S),{ok:!0,data:A}}async function aX(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return J("SESSION_NOT_FOUND",`Session "${r}" not found.`);let n=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(n?e.appName:void 0),l=aB(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?aj("open --relaunch requires an app name or an active session app."):aj("Session already active. Close it first or pass a new --session name.");let d=aH({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await ae(e.device),c=await aK({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await aY({req:t,sessionName:r,sessionStore:i,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 n=t.flags?.relaunch===!0,o=t.positionals?.[0];if(n&&!o)return aj("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&ep(r)?aj("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===es(r)?aj(ej(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await ei(t.flags??{}),d=aB(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=aH({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await er(aW,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return J("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await aK({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await aY({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:d})})}async function aQ(e){let t=await tw("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 a0(e){let{device:t,shutdownRequested:r}=e;if(r&&(r6(t)||"android"===t.platform&&"emulator"===t.kind))try{return r6(t)?await F(t):await aQ(t)}catch(t){let e=tu(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function a1(e){if(await V(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await ed("dismiss",t).catch(t=>{tv({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function a2(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return J("SESSION_NOT_FOUND","No active session");n.appLog&&await rf(n.appLog),t.positionals&&t.positionals.length>0&&(("ios"===n.device.platform||"macos"===n.device.platform)&&await a1(n),await I(n.device,"close",t.positionals,t.flags?.out,{...em(a,t.flags,n.appBundleId,n.trace?.outPath)}),await r7(n.device,r5)),("ios"===n.device.platform||"macos"===n.device.platform)&&await a1(n),ad(i.getRuntimeHints(r))&&n.appBundleId&&await af({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...X(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rY(r).catch(()=>{}),i.delete(r);let o=await a0({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:T({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...X(`Closed: ${r}`)}}}let a5=["platform","target","device","udid","serial","verbose","out"];function a4(e,t){let r=e??{};for(let e of a5)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let a3={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./760.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./760.js");return await a(e,t,r)}},a8={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./760.js"),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await import("./760.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function a6(e){let{req:t,command:r,sessionName:i,sessionStore:n,deployOps:o}=e,s=n.get(i),l=t.flags??{},d=r3(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return J("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,i=f?rv(f,t.meta?.tenantId):tC.expandHome(c);if(!a.existsSync(i))return J("INVALID_ARGS",`App binary not found: ${i}`);let d=await r9({session:s,flags:l,ensureReady:!1});if(!ti(r,d))return J("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,i),r=t.bundleId;e=r?{app:u,appPath:i,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:i,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,i),r=t.package;e=r?{app:u,appPath:i,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:i,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=T(e,(p=e,`Installed: ${p.appName??D(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&ry(f)}}async function a7(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return J("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??el;if(!Number.isInteger(i)||i<1||i>1e3)return J("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=b(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await a9(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=td(t);return J(e.code,e.message,e.details)}}async function a9(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return a4(e,n)}(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()-n;return s.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:i,error:s.error}}async function ie(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new tc("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await it({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await ir({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await ia(t,u),a=!0)}else t=(await ir({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await ia(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function it(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await tw("xcrun",y(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:e6});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let[a,i]of Object.entries(e.devices??{}))if(!r||ii(a).includes(ii(r))){for(let e of i)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function ir(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await tw("xcrun",y(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new tc("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.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(n.stdout??"").trim();if(!o)throw new tc("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function ia(e,t){let r=await tw("xcrun",y(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:e6});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 ii(e){return e.toLowerCase().replace(/[._-]/g,"")}async function io(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,i=eH(e.iosSimulatorDeviceSet);if(!r)return J("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await ie({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:eY});return{ok:!0,data:{udid:n.udid,device:n.device,runtime:n.runtime,ios_simulator_device_set:i??null,created:n.created,booted:n.booted}}}catch(t){let e=td(t);return J(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=tr(t.flags?.androidDeviceAllowlist),a=w(t.flags?.platform),i=S({simulatorSetPath:eH(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./760.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./760.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./760.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./760.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=td(t);return J(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r3(t.command,e,i);if(n)return n;let o=await r9({session:e,flags:i,ensureReady:!0});if(!ti("apps",o))return J("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(g(o.platform)){let{listIosApps:e}=await import("./760.js");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 import("./760.js");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 is(e){let{ensureAndroidEmulatorBooted:t}=await import("./760.js");return await t(e)}let il='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',id='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function iu(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=w(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return J("SESSION_NOT_FOUND","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=r3("appstate",i,n);if(s)return s;let l=(i?.device.platform==="ios"||i?.device.platform==="macos")&&function(e,t){if(!t)return!1;if(!r8(e))return!0;let r=w(e?.platform);return!(r&&!e9(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())}(n,i);if("ios"===o&&!l)return J("SESSION_NOT_FOUND",il);if("macos"===o&&!l)return J("SESSION_NOT_FOUND",id);if(l&&i){let e=i.appName??i.appBundleId;if(!i.appName&&!i.appBundleId){if("macos"===i.device.platform&&i.surface&&"app"!==i.surface&&"frontmost-app"!==i.surface)return{ok:!0,data:{platform:i.device.platform,appName:i.surface,appBundleId:i.appBundleId,source:"session",surface:i.surface}};let e="macos"===i.device.platform?"macOS":"iOS";return J("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:i.device.platform,appName:e??"unknown",appBundleId:i.appBundleId,source:"session",surface:i.surface??"app",..."ios"===i.device.platform?{device_udid:i.device.id,ios_simulator_device_set:i.device.simulatorSetPath??null}:{}}}}let d=await r9({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return J("SESSION_NOT_FOUND",il);if("macos"===d.platform)return J("SESSION_NOT_FOUND",id);let{getAndroidAppState:u}=await import("./760.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function ic(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r3(t.command,i,n);if(o)return o;let s="android"===(w(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return J("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=at({flags:n,sessionDevice:i?.device}),u=s&&!!d,c=!1;try{e=await r9({session:i,flags:n,ensureReady:!1})}catch(r){let t=td(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return J("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await is({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return J("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return J("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=at({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return J("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await is({avdName:t,serial:n.serial,headless:!0})}await eY(e)}else("android"!==e.platform||!0!==e.booted)&&await eY(e);return ti("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:J("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await iu({req:t,sessionName:r,sessionStore:a}):null}function ip(e){return Math.round(10*e)/10}let im="adb-shell-dumpsys-cpuinfo",ih="adb-shell-dumpsys-meminfo";async function ig(e,t){try{let r=await tw("adb",eT(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,o;let e=r.trim();if(0===e.length)continue;let s=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!s)continue;let l=Number(s[1]),d=s[2];Number.isFinite(l)&&(n=d,o=t,n===o||n.startsWith(`${o}:`))&&(i+=l,a.add(d))}return{usagePercent:ip(i),measuredAt:r,method:im,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw iv("cpu",t,e)}}async function iw(e,t){try{let r=await tw("adb",eT(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new tc("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=iy(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!==iI(e));if(!r)break;return iI(r)??void 0}}(e);if(void 0===a)throw new tc("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:iy(e,"TOTAL RSS"),measuredAt:r,method:ih}}(r.stdout,t,new Date().toISOString())}catch(e){throw iv("memory",t,e)}}function iv(e,t,r){return r instanceof tc&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new tc(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof tc?r:new tc("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function iy(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return iI(a[1])??void 0}function iI(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let iS="ps-process-snapshot",iA="ps-process-snapshot",ib="xctrace-activity-monitor",i_="xctrace-activity-monitor";async function iN(e,t){if("ios"===e.platform&&"device"===e.kind)return await iM(e,t);let r=await ik(e,t),a=await i$(e,r);if(0===a.length)throw new tc("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 i=new Date().toISOString(),o=ee(a.map(e=>n.basename(iC(e.command))));return iE({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:o,cpuMethod:iS,memoryMethod:iA})}async function ix(e){let t=e4(e),r=iT(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new tc("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??""}),i=a.indexOf("pid"),n=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(i<0||n<0||o<0||s<0)throw new tc("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let i of t)r(i)&&a.push(i),a.push(...e(i.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,f;let t=e.children;if(0===t.length)continue;for(let e of t){let t=iT(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:iF(e),processName:iG(e)})}let r=iU(t[i],u),a=(c=t[n],f=u,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:iG(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:iU(t[o],u),residentMemoryBytes:iU(t[s],u)})}return d}async function ik(e,t){let r="macos"===e.platform?await iR(t):await iO(e,t),a="macos"===e.platform?n.join(r,"Contents","Info.plist"):n.join(r,"Info.plist"),i=await eQ(a,"CFBundleExecutable");if(!i)throw new tc("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?n.join(r,"Contents","MacOS",i):void 0}}async function iM(e,t){let r=await iD(e,t),a=await iP(e,t),i=await iP(e,t),n=iL(await ix(a.xml),r,t,e),o=iL(await ix(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new tc("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new tc("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 iE({usagePercent:Math.max(0,o.cpuTimeNs-n.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(i.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:ib,memoryMethod:i_})}async function iD(e,t){let r=(await P(e,"all")).find(e=>e.bundleId===t);if(!r)throw new tc("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new tc("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await ta(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new tc("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function iP(e,t){let r=await i.mkdtemp(n.join(c.tmpdir(),"agent-device-ios-perf-")),a=n.join(r,"sample.trace"),o=n.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"],n=await tw("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==n.exitCode)throw new tc("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr,appBundleId:t,deviceId:e.id,hint:iV(n.stdout,n.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",o],d=await tw("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new tc("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:l,exitCode:d.exitCode,stdout:d.stdout,stderr:d.stderr,appBundleId:t,deviceId:e.id,hint:iV(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await i.readFile(o,"utf8")}}finally{await i.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function iL(e,t,r,a){let i=new Set(t.map(e=>e.pid)),o=new Set(t.map(e=>n.basename(d(e.executable)))),s=e.filter(e=>i.has(e.pid)||o.has(e.processName));if(0===s.length)throw new tc("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 l=new Map;for(let e of s){let t=l.get(e.pid);if(!t){l.set(e.pid,e);continue}l.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:iq(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iq(t.residentMemoryBytes,e.residentMemoryBytes)})}let u=[...l.values()],c=u.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=u.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:c.length>0?c.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:ee(u.map(e=>e.processName))}}async function iR(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await tw("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new tc("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 tc("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function iO(e,t){let r=e1(e,["get_app_container",e.id,t,"app"]),a=await tw("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new tc("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 i=a.stdout.trim();if(0===i.length)throw new tc("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function i$(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:e1(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 i=Number(a[1]),n=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(o)&&t.push({pid:i,cpuPercent:n,rssKb:o,command:s})}return t})((await tw("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=iC(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||n.basename(i)===a.executableName})}function iC(e){let[t=""]=e.trim().split(/\s+/,1);return t}function iE(e){return{cpu:{usagePercent:ip(e.usagePercent),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 iT(e,t){for(let r of e){if(t(r))return r;let e=iT(r.children,t);if(e)return e}}function iF(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 iU(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:iF(e):null}function iG(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function iV(e,t){let r=H(e,t);if(r)return r;let a=`${e}
9
- ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?eM: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 iq(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function ij(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===aC&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:aC,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),i=a?{available:!0,lastDurationMs:a.durationMs,lastMeasuredAt:a.measuredAt,method:aC,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:aC},n={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:i,fps:{available:!1,reason:aE},memory:{available:!1,reason:aE},cpu:{available:!1,reason:aE}},sampling:{startup:{method:aC,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:ih,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:im,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:i_,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:ib,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:iA,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:iS,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 n;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 n.metrics.memory={available:!1,reason:t},n.metrics.cpu={available:!1,reason:t},n}let[o,s]=await iB(e);return n.metrics.memory=iH(o),n.metrics.cpu=iH(s),n}async function iB(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([iw(e.device,t),ig(e.device,t)]);return[r,a]}try{let r=await iN(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 iH(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=tu(e.reason);return{available:!1,reason:t.message,error:t}}let iK=["path","start","stop","doctor","mark","clear"],iz=`logs requires ${iK.slice(0,-1).join(", ")}, or ${iK.at(-1)}`,iW=["dump","log"],iJ=`network requires ${iW.join(" or ")}`,iZ=["summary","headers","body","all"],iY=`network include mode must be one of: ${iZ.join(", ")}`;async function iX(e){let{req:t}=e;return"perf"===t.command?iQ(e):"logs"===t.command?i0(e):"network"===t.command?i3(e):null}async function iQ(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return J("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await ij(a)}}catch(e){return{ok:!1,error:tu(e)}}}async function i0(e){let{req:t,sessionName:r,sessionStore:i}=e,n=i.get(r);if(!n)return J("SESSION_NOT_FOUND","logs requires an active session");if(!ti("logs",n.device))return J("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return iK.includes(o)?s&&"clear"!==o?J("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===o?function(e,t,r){let i=r.resolveAppLogPath(t),n=function(e){if(!a.existsSync(e))return{exists:!1,sizeBytes:0};let t=a.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(i);return{ok:!0,data:{path:i,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,i):"doctor"===o?i1(n,r,i):"mark"===o?function(e,t,r){let i,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return rs(o),i=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
10
- `,a.appendFileSync(o,i,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,i):"clear"===o?i2(n,r,i,s):"start"===o?i5(n,r,i):"stop"===o?i4(n,r,i):J("INVALID_ARGS",iz):J("INVALID_ARGS",iz)}async function i1(e,t,r){let a=r.resolveAppLogPath(t),i=await rp(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:i.checks,notes:i.notes}}}async function i2(e,t,r,a){if(e.appLog&&!a)return J("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return J("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:rm(i)};e.appLog&&await rf(e.appLog);let n=rm(i),o=r.resolveAppLogPidPath(t);try{let a=await ru(e.device,e.appBundleId,i,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:i,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...n,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:tu(a)}}}async function i5(e,t,r){if(e.appLog)return J("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return J("INVALID_ARGS","logs start requires an app session; run open <app> first");let a=r.resolveAppLogPath(t),i=r.resolveAppLogPidPath(t);try{let n=await ru(e.device,e.appBundleId,a,i);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:tu(e)}}}async function i4(e,t,r){if(!e.appLog)return J("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rf(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function i3(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return J("SESSION_NOT_FOUND","network requires an active session");if(!ti("network",i.device))return J("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!iW.includes(n))return J("INVALID_ARGS",iJ);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return J("INVALID_ARGS","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 J("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return iZ.includes(a)?{ok:!0,include:a}:J("INVALID_ARGS",iY)}(t);if(!s.ok)return s;let{include:l}=s,d=await rl({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!i.appLog,state:i.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let i8=new Set(["ios","android","macos","linux"]);function i6(e,t,r){let a=e[t];if(void 0!==a)throw new tc("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 i7(e){return!!e&&!Number.isNaN(Number(e))}let i9=/[*?[\]{}]/;async function ne(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;z(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=td(e);return J(t.code,t.message)}).finally(()=>{e0(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eK(i),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}}}}(n,[...d]))},n)})]):await c}finally{t&&clearTimeout(t),u&&(await nt(c)||tv({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){tv({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:td(e).message}})}}}async function nt(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function nr(e){let{req:t,sessionName:r,runReplay:i,cleanupSession:o}=e;if((t.positionals?.length??0)===0)return J("INVALID_ARGS","test requires at least one path or glob");try{var s,l,d,u,c,f;let e,p,m,h,g,w=function(e){let{inputs:t,cwd:r,platformFilter:i}=e,o=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,i;let o=tC.expandHome(e,t);if(a.existsSync(o)){let t=a.statSync(o);if(t.isDirectory())return a.globSync("**/*.ad",{cwd:o}).map(e=>n.join(o,e));if(t.isFile()){if(".ad"!==n.extname(o))throw new tc("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[o]}return[]}if(r=e,!i9.test(r)&&(i=o,!i9.test(i)))throw new tc("INVALID_ARGS",`test input not found: ${e}`);let s=n.isAbsolute(o)?o:e;return a.globSync(s,{cwd:n.isAbsolute(o)?void 0:t}).map(e=>n.isAbsolute(e)?e:n.resolve(t,e)).filter(e=>".ad"===n.extname(e)&&function(e){try{return a.statSync(e).isFile()}catch{return!1}}(e))})(e,o)))].map(e=>n.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var d,u;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&&i8.has(e)&&i6(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&i6(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&i6(r,"retries",Math.floor(e))}}return r}(a.readFileSync(e,"utf8"));if(!i){l.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){l.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${i}`});continue}d=i,u=t.platform,("apple"===d?"apple"===u||"ios"===u||"macos"===u:u===d)&&l.push({kind:"run",path:e,metadata:t})}if(0===l.filter(e=>"run"===e.kind).length){let e=i?` for --platform ${i}`:"";throw new tc("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),v=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),y=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tC.expandHome(t??".agent-device/test-artifacts",r);return n.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:v}),I=[],S=Date.now(),A=0;for(let e of w){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let a=await na({entry:e,sessionName:r,suiteInvocationId:v,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:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:y,runReplay:i,cleanupSession:o});if(I.push(a),t.flags?.failFast===!0)break}let b=(u=w.length,c=I,f=Date.now()-S,e=c.filter(e=>"passed"===e.status).length,m=(p=c.filter(e=>"failed"===e.status)).length,h=c.filter(e=>"skipped"===e.status).length,g=e+m,{total:u,executed:g,passed:e,failed:m,skipped:h,notRun:Math.max(0,u-g-h),durationMs:f,failures:p,tests:c});return{ok:!0,data:b}}catch(t){let e=td(t);return J(e.code,e.message)}}async function na(e){var t,r;let i,o,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,v=Date.now(),y=n.join(h,(t=s.path,(0===(o=c?n.relative(c,t):n.basename(t)).length||o.startsWith("..")?n.basename(t):o).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",S=0;for(let e=0;e<=p;e+=1){S=e+1;let t=function(e,t,r,a,i=0){let o=n.basename(r,n.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${o?`-${o}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),o=n.join(y,`attempt-${S}`);r=s.path,a.mkdirSync(o,{recursive:!0}),a.copyFileSync(r,n.join(o,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:o}=e;return eE(`${t??r}:test:${i+1}:${n.basename(a)}:attempt:${o+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await ne({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:i,attempts:o,maxAttempts:s,attemptArtifactsDir:l}=e,d=[...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||d.push(t.error.logPath);let u=function(e,t){let r=[],i=new Map;for(let o of e){if(!function(e){try{return a.statSync(e).isFile()}catch{return!1}}(o))continue;let e=function(e,t){let r=n.extname(e),a=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${a}-${i+1}${r}`}(n.basename(o),i),s=n.join(t,e);n.resolve(o)!==n.resolve(s)&&a.copyFileSync(o,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${i}`,`attempt: ${o}/${s}`,`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;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");u.length>0&&c.push(`copiedArtifacts: ${u.map(e=>n.basename(e)).join(", ")}`);let f=n.join(l,"result.txt"),p=`${c.join("\n")}
11
- `;a.writeFileSync(f,p),t.ok||a.writeFileSync(n.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:S,maxAttempts:p+1,attemptArtifactsDir:o}),i=h,I=t,h.ok)break}let A=Date.now()-v;if(i?.ok)return{file:s.path,session:I,status:"passed",durationMs:A,attempts:S,artifactsDir:y,replayed:"number"==typeof i.data?.replayed?i.data.replayed:0,healed:"number"==typeof i.data?.healed?i.data.healed:0};let b=i?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:i?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:I,status:"failed",durationMs:A,attempts:S,artifactsDir:y,error:b}}function ni(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=q(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 nn(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(tb(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let n=i.get(r);if(!n)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),tb(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}=e$(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=ni(e.positionals??[]);r&&t.push(r)}return ee(t).filter(e=>e.trim().length>0)})(t).map(e=>eW(e)).filter(e=>null!==e);if(0===o.length)return null;let s=tb(t.command)||"fill"===t.command,l=tb(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await no(n,t,a,s,i);for(let e of o){let r=$(d.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=E(r.node,n.device.platform,{action:tb(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tb(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=O(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}=e$(t.positionals);if(!e)continue;let i=r?.rest.join(" ").trim()??"",n=[e,a];return"text"===e&&i.length>0&&n.push(i),{...t,positionals:n}}if("wait"===t.command){let{selectorTimeout:e}=ni(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function no(e,t,r,a,i){let n=await I(e.device,"snapshot",[],t.flags?.out,{...em(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:x(t.flags?.snapshotRaw?o:et(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return e.snapshot=s,i.set(e.name,e),s}async function ns(e){let{req:t,sessionName:r,logPath:i,sessionStore:n,invoke:o}=e,s=t.positionals?.[0];if(!s)return J("INVALID_ARGS","replay requires a path");let l="",d=new Set;try{l=tC.expandHome(s,t.meta?.cwd);let e=a.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return J("INVALID_ARGS","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,i=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!i)break;i="\\"===t&&!i,"\\"!==t&&(i=!1),a+=1}if(a>=e.length)throw new tc("INVALID_ARGS",`Invalid replay script line: ${e}`);let n=e.slice(r,a+1);t.push(JSON.parse(n)),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,...i]=r;if("context"===a)return null;let n={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){n.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){n.flags.snapshotCompact=!0;continue}if("--raw"===t){n.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(n.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){n.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}return n}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 i=tR(r);return{positionals:i.positionals,flags:a,runtime:(t=i.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?i.flags:void 0}}(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n.runtime=e.runtime,n}if("runtime"===a){let e=tR(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(tb(a)){let e=tL(a,i);if(Object.assign(n.flags,e.flags),0===e.positionals.length)return n;let t=e.positionals[0];if(t.startsWith("@"))return n.positionals=[t],e.positionals[1]&&(n.result={refLabel:e.positionals[1]}),n;let r=e.positionals[0],o=e.positionals[1];return i7(r)&&i7(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tL(a,i);if(Object.assign(n.flags,e.flags),e.positionals.length<2)return n.positionals=e.positionals,n;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(n.positionals=[t,e.positionals.slice(2).join(" ")],n.result={refLabel:e.positionals[1]}):n.positionals=[t,e.positionals[1]],n):(n.positionals=[t,e.positionals.slice(1).join(" ")],n)}if("get"===a){if(i.length<2)return n.positionals=i,n;let e=i[0],t=i[1];return t.startsWith("@")?(n.positionals=[e,t],i[2]&&(n.result={refLabel:i[2]})):n.positionals=[e,i.slice(1).join(" ")],n}if("swipe"===a||"type"===a){let e=tL(a,i);return Object.assign(n.flags,e.flags),n.positionals=e.positionals,n}if("record"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--hide-touches"===r){n.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.fps=Math.floor(e)),t+=1;continue}e.push(r)}return n.positionals=e,n}if("screenshot"===a){let e=[];for(let t of i){if("--fullscreen"===t){n.flags.screenshotFullscreen=!0;continue}e.push(t)}return n.positionals=e,n}return n.positionals=i,n}(r);e&&t.push(e)}return t}(e),f=t.flags?.replayUpdate===!0,p=0;for(let e=0;e<c.length;e+=1){let a=c[e];if(!a||"replay"===a.command)continue;let s=await nl({req:t,sessionName:r,action:a,invoke:o});if(s.ok){nu(s).forEach(e=>d.add(e));continue}if(!f)return nd(s,a,e,l,[...d]);let u=await nn({action:a,sessionName:r,logPath:i,sessionStore:n});if(!u)return nd(s,a,e,l,[...d]);if(c[e]=u,!(s=await nl({req:t,sessionName:r,action:u,invoke:o})).ok)return nd(s,u,e,l,[...d]);nu(s).forEach(e=>d.add(e)),p+=1}return f&&p>0&&function(e,t,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${tx(r.device.name)}${e} theme=unknown`)}for(let e of t)i.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",tN(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return t$(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tk(r));return tD(t,e.flags),t.join(" ")}if("record"===e.command)return tP(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tN(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}for(let r of e.positionals??[])t.push(tN(r));return tM(t,e),t.join(" ")}(e));let n=`${i.join("\n")}
12
- `,o=`${e}.tmp-${process.pid}-${Date.now()}`;a.writeFileSync(o,n),a.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=td(t);return J(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function nl(e){var t;let{req:r,sessionName:a,action:i,invoke:n}=e;return await n({token:r.token,session:a,command:i.command,positionals:i.positionals??[],flags:(t=r.flags,a4(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function nd(e,t,r,a,i=[]){let n;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${n=(t.positionals??[]).map(e=>tN(e)),[t.command,...n].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:i}}}}function nu(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 a.statSync(e).isFile()}catch{return!1}})(e)))]}async function nc(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await ns({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await nr({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await ns({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:i,invoke:async e=>{var t;return t=await n(e),l&&nu(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await a2({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let nf=new Set(["session_list","ensure-simulator","devices","apps"]),np=new Set(["boot","appstate"]),nm=new Set(["perf","logs","network"]),nh=new Set(["replay","test"]);async function ng(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=i.get(r),u=t.flags??{},c=r3(n,d,u);if(c)return c;let f=await r9({session:d,flags:u,ensureReady:!0});if(!ti(n,f))return J("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await I(f,n,o,t.flags?.out,{...em(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,p,f):d;i.recordAction(e,{command:n,positionals:s??o,flags:t.flags??{},result:p??{}}),e!==d&&i.set(r,e)}return{ok:!0,data:p??{}}}async function nw(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r3("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return J("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await r9({session:n,flags:o,ensureReady:!0});if(!ti("clipboard",d))return J("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await I(d,"clipboard",t.positionals??[],t.flags?.out,{...em(a,t.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function nv(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(nf.has(t.command))return await io({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await a$({req:t,sessionName:r,sessionStore:i});if(np.has(t.command))return await ic({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await nw({req:t,sessionName:r,logPath:a,sessionStore:i});if("keyboard"===t.command){let e=i.get(r),n=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==n||"ios"!==w((t.flags??{}).platform)?await ng({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):J("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(nm.has(t.command))return await iX({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await a6({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?a8:a3});if("install_source"===t.command)return await r0({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r2({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await ng({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=eU(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tC.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):J("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await ng({req:t,sessionName:r,logPath:a,sessionStore:i,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await aq(e.device,r,e.appBundleId,aV)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aX({req:t,sessionName:r,logPath:a,sessionStore:i}):nh.has(t.command)?await nc({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await a7(t,r,n):"close"===t.command?await a2({req:t,sessionName:r,logPath:a,sessionStore:i}):null}function ny(e){let{session:t,refInput:r,fallbackLabel:a,requireRect:i,invalidRefMessage:n,notFoundMessage:o}=e;if(!t.snapshot)return J("INVALID_ARGS","No snapshot in session. Run snapshot first.");let s=en(r);if(!s)return J("INVALID_ARGS",n);let l=Y(t.snapshot.nodes,s);return((!l||i&&!l.rect)&&a.length>0&&(l=e7(t.snapshot.nodes,a)),l&&(!i||l.rect))?{ok:!0,target:{ref:s,node:l,snapshotNodes:t.snapshot.nodes}}:J("COMMAND_FAILED",o)}function nI(e){let t=nS(e);if(!t)return null;let r=N(t);return Number.isFinite(r.x)&&Number.isFinite(r.y)?r:null}function nS(e){if(!e)return null;let t=Number(e.x),r=Number(e.y),a=Number(e.width),i=Number(e.height);return Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(a)&&Number.isFinite(i)&&!(a<0)&&!(i<0)?{x:t,y:r,width:a,height:i}:null}async function nA(e){let{session:t,refInput:r,fallbackLabel:a,commandLabel:i,promoteToHittableAncestor:n,invalidRefMessage:o,missingBoundsMessage:s,invalidBoundsMessage:l,reqFlags:d,sessionStore:u,contextFromFlags:c,captureSnapshotForSession:f,resolveRefTarget:p}=e,m=p({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:o,notFoundMessage:s});if(!m.ok)return m;let{ref:h}=m.target,g=n?nb(m.target.snapshotNodes,m.target.node):m.target.node,w=m.target.snapshotNodes,v=nI(g.rect);if(!v){let e=await f(t,d,u,c,{interactiveOnly:!0}),r=Y(e.nodes,h),i=a.length>0?e7(e.nodes,a):null,o=r&&n?nb(e.nodes,r):r,s=i&&n?nb(e.nodes,i):i,l=nI(s?.rect),p=nI(o?.rect)?o:l?s:o??s,m=nI(p?.rect);p&&m&&(g=p,w=e.nodes,v=m)}if(!v)return J("COMMAND_FAILED",l);let y=g.rect?eG(g,w):null;return g.rect&&y&&!M(g,w)?{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${r} is off-screen and not safe to ${i}`,hint:`Run scrollintoview ${r}, then retry ${i} with the returned currentRef or a fresh snapshot.`,details:{reason:"offscreen_ref",ref:h,rect:g.rect,viewport:y}}}:{ok:!0,target:{ref:h,node:g,snapshotNodes:w,point:v}}}function nb(e,t){let r=function(e,t){let r=nS(t.rect);if(!r)return null;let a=t,i=new Set;for(;!i.has(a.ref);){i.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=nS(e.rect);return!!t&&n_(t,r)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(r?.rect&&nI(r.rect))return r;let a=e3(e,t);return a?.rect&&nI(a.rect)?!function(e,t,r){var a,i,n,o;let s,l,d,u=nS(e.rect),c=nS(t.rect);if(!u||!c)return!1;let f=function(e,t){let r=N(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>nS(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let i=a.filter(e=>eh(e,r.x,r.y));return Q(i.length>0?i:a)}(r,u);return!!f&&(a=c,i=f,s=(n=a,o=i,Math.max(0,Math.min(n.x+n.width,o.x+o.width)-Math.max(n.x,o.x))*Math.max(0,Math.min(n.y+n.height,o.y+o.height)-Math.max(n.y,o.y))),l=a.width*a.height,d=i.width*i.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!n_(u,c)}(t,a,e)?a:t:t}function n_(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 nN(e){let{device:t,node:r,flags:a,appBundleId:i,traceOutPath:n,surface:o,contextFromFlags:s}=e,l=eu(r),d=nI(r.rect);if(!d)return l;try{let e=await I(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,i,n),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return tv({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:o,platform:t.platform}}),l}catch(e){return tv({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 nx(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return J("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=function(e){let t="any",r=0;["text","label","value","role","id"].includes(e[0])&&(t=e[0],r=1);let a=e[r]??"",i=e.slice(r+1);if(0===i.length)return{locator:t,query:a,action:"click"};let n=i[0].toLowerCase();if("get"===n){let e=i[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 tc("INVALID_ARGS","find get only supports text or attrs")}if("wait"===n)return{locator:t,query:a,action:"wait",timeoutMs:ex(i[1])??void 0};if("exists"===n)return{locator:t,query:a,action:"exists"};if("click"===n)return{locator:t,query:a,action:"click"};if("focus"===n)return{locator:t,query:a,action:"focus"};if("fill"===n)return{locator:t,query:a,action:"fill",value:i.slice(1).join(" ")};if("type"===n)return{locator:t,query:a,action:"type",value:i.slice(1).join(" ")};throw new tc("INVALID_ARGS",`Unsupported find action: ${i[0]}`)}(s);if(!d)return J("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return J("INVALID_ARGS","find accepts only one of --first or --last");let p=i.get(r);if(!p&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return J("SESSION_NOT_FOUND","No active session. Run open first.");let m=p?.device??await ei(t.flags??{});p||await eY(m);let h="role"!==l?d:void 0,g="click"===u||"focus"===u||"fill"===u||"type"===u,w=0,v=null,y=async()=>{let e=Date.now();if(v&&e-w<750&&!e2(p))return{nodes:v};let{snapshot:n}=await eA({device:m,session:p,flags:{...t.flags,snapshotInteractiveOnly:g,snapshotCompact:g},outPath:t.flags?.out,logPath:a,snapshotScope:h}),o=n.nodes;return w=e,v=o,p&&(p.snapshot=n,i.set(r,p)),{nodes:o,truncated:n.truncated,backend:n.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:p,device:m,command:o,locator:l,query:d};if("wait"===u)return nk(I,y,l,d,f);let{nodes:S}=await y(),A=e5(S,l,d,{requireRect:g});if(g&&A.matches.length>1)if(t.flags?.findFirst)A.matches=[A.matches[0]];else{if(!t.flags?.findLast){var b,_,N;let e;return b=A.matches,_=l,N=d,e=b.slice(0,8).map(e=>{let t=eI(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),J("AMBIGUOUS_MATCH",`find matched ${b.length} elements for ${_} "${N}". Use a more specific locator or selector.`,{locator:_,query:N,matches:b.length,candidates:e})}A.matches=[A.matches[A.matches.length-1]]}let x=A.matches[0]??null;if(!x)return J("COMMAND_FAILED","find did not match any element");let k="click"===u||"focus"===u||"fill"===u||"type"===u?e3(S,x)??x:x,M=`@${k.ref}`,D={node:x,resolvedNode:k,ref:M,nodes:S,actionFlags:{...t.flags??{},noRecord:!0}},P={exists:()=>nM(I),get_text:()=>nD(I,D),get_attrs:()=>nP(I,D),click:()=>nL(I,D),fill:()=>nR(I,D,c),focus:()=>nO(I,D),type:()=>n$(I,D,c)}[u];return P?P():null}async function nk(e,t,r,a,i){let{req:n,sessionStore:o,session:s,command:l}=e,d=i??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(e5(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:n.positionals??[],flags:n.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 J("COMMAND_FAILED","find wait timed out")}async function nM(e){let{req:t,sessionStore:r,session:a,command:i}=e;return a&&r.recordAction(a,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function nD(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await nN({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>em(s,e,t,r)});return i&&a.recordAction(i,{command:n,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 nP(e,t){let{req:r,sessionStore:a,session:i,command:n}=e;return i&&a.recordAction(i,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function nL(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,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?N(t.resolvedNode.rect):null,f={ref:t.ref,locator:l,query:d};return c&&(f.x=c.x,f.y=c.y),n&&i.recordAction(n,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:f}}async function nR(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return J("INVALID_ARGS","find fill requires text");let d=await s({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&n.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function nO(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?N(t.node.rect):null;if(!l)return J("COMMAND_FAILED","matched element has no bounds");let d=await I(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...em(s,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function n$(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return J("INVALID_ARGS","find type requires text");let d=t.node.rect?N(t.node.rect):null;if(!d)return J("COMMAND_FAILED","matched element has no bounds");await I(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...em(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await I(o,"type",[r],a.flags?.out,{...em(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let nC=`
1
+ let e,t;import r from"node:crypto";import a,{promises as i}from"node:fs";import n from"node:path";import{spawn as o}from"node:child_process";import s from"node:http";import{fileURLToPath as l,pathToFileURL as d}from"node:url";import"node:https";import u from"node:os";import c from"node:fs/promises";import{setTimeout as f}from"node:timers/promises";import{PNG as p}from"pngjs";import m from"node:net";import{resolveAppleSimulatorSetPathForSelector as h,buildSimctlArgs as g,dispatchCommand as w,isNodeVisibleInEffectiveViewport as v,isAgentDeviceDaemonProcess as y,handleSnapshotCommands as I,isNodeEditable as S,resolveSelectorChain as A,registerRequestAbort as b,resolveSessionIsolationMode as _,errorResponse as N,pickLargestRect as x,successText as M,uniqueStrings as k,withKeyedLock as D,DEFAULT_BATCH_MAX_STEPS as P,parseSerialAllowlist as L,extractNodeReadText as R,getAndroidScreenSize as O,rect_visibility_containsPoint as E,extractNodeText as C,IOS_DEVICECTL_DEFAULT_HINT as $,captureSnapshotData as T,isRequestCanceled as F,resolveRequestTrackingId as U,abortAllIosRunnerSessions as G,getRunnerSessionSnapshot as V,formatAndroidInstalledPackageRequiredMessage as q,resolveViewportRect as j,tryParseSelectorChain as B,readVersion as H,clearRequestCanceled as K,parseXmlDocumentSync as z,findNearestHittableAncestor as W,IOS_SIMCTL_LIST_TIMEOUT_MS as J,listIosDeviceApps as Z,readProcessStartTime as Y,withDiagnosticsScope as X,isApplePlatform as Q,resolveInstallFromSourceResultTarget as ee,centerOfRect as et,resolveAndroidSerialAllowlist as er,isFillableType as ea,attachRefs as ei,listIosDeviceProcesses as en,buildScrollGesturePlan as eo,splitSelectorFromArgs as es,readProcessCommand as el,parseSessionSurface as ed,resolveDaemonServerMode as eu,validateAndNormalizeBatchSteps as ec,IOS_RUNNER_CONTAINER_BUNDLE_IDS as ef,buttonTag as ep,hasRuntimeTransportHints as em,resolveDeployResultTarget as eh,inferFillText as eg,buildSelectorChainForNode as ew,withSuccessText as ev,shutdownSimulator as ey,stopIosRunnerSession as eI,formatSelectorFailure as eS,createRequestCanceledError as eA,isNavigationSensitiveAction as eb,resolveIosDevicectlHint as e_,getClickButtonValidationError as eN,isNodeVisible as ex,findNodeByRef as eM,snapshotAndroid as ek,withDiagnosticTimer as eD,pruneGroupNodes as eP,applyRuntimeHintsToApp as eL,resolveTargetDevice as eR,stopAllIosRunnerSessions as eO,findSelectorChainMatch as eE,normalizeRef as eC,classifyAndroidAppTarget as e$,getAndroidAppState as eT,runMacOsAlertAction as eF,isDeepLinkTarget as eU,clearRuntimeHintsFromApp as eG,contextFromFlags as eV,parseFindArgs as eq,resolveDaemonCodeSignature as ej,captureSnapshot as eB,parseSelectorChain as eH,normalizeTenantId as eK,resolveClickButton as ez,resolveTimeoutMs as eW,buildSnapshotState as eJ,openAndroidApp as eZ,distanceFromSafeViewportBand as eY,splitIsSelectorArgs as eX,adbArgs as eQ,resolveRefLabel as e0,resolvePayloadInput as e1,resolveEffectiveViewportRect as e2,resolveIosSimulatorDeviceSetPath as e5,markRequestCanceled as e4,resolveIosDeviceDeepLinkBundleId as e3,runIosRunnerCommand as e8,resolveUserPath as e6,ensureDeviceReady as e9,getDiagnosticsMeta as e7,readInfoPlistString as te,getActiveAndroidSnapshotFreshness as tt,buildSimctlArgsForDevice as tr,findBestMatchesByLocator as ta,emitDiagnostic as ti,resolveFrontmostMacOsApp as tn,findNodeByLabel as to,matchesPlatformSelector as ts,isCommandSupportedOnDevice as tl,resolveDaemonPaths as td,flushDiagnosticsToSessionFile as tu,normalizeType as tc,normalizePlatformSelector as tf,decodePng as tp,markAndroidSnapshotFreshness as tm,getRequestSignal as th}from"./155.js";import{runCmdBackground as tg,runCmd as tw,asAppError as tv,normalizeError as ty,AppError as tI}from"./818.js";let tS=/^-?\d+(\.\d+)?$/,tA=/^[^\s"\\]+$/,tb=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),t_=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tN=new Map([["--delay-ms","delayMs"]]);function tx(e){return"click"===e||"press"===e}function tM(e){return"type"===e||"fill"===e}function tk(e){return tP(e,tL)}function tD(e){return JSON.stringify(e)}function tP(e,t){return t(e)?e:tD(e)}function tL(e){return tR(e)&&e.startsWith("@")||tS.test(e)}function tR(e){return tA.test(e)}function tO(e,t){let r=t.flags??{};if(tx(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}tM(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tE(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",tP(t.metroHost,tR)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tP(t.bundleUrl,tR)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tP(t.launchUrl,tR)))}function tC(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tP(r,tR)),a))e.push(tk(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),t.flags?.hideTouches&&e.push("--hide-touches")}function t$(e,t){let r=[],a={},i=tx(e)?tb:"swipe"===e?t_:tM(e)?tN:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(tx(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(tx(e)&&"--button"===o&&n+1<t.length){let e=t[n+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),n+=1;continue}let s=i?.get(o);if(s&&n+1<t.length){let e=tF(t[n+1]);if(null!==e){a[s]=e,n+=1;continue}}if("swipe"===e&&"--pattern"===o&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(o)}return{positionals:r,flags:a}}function tT(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let i=e[a];if("--platform"===i&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===i&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===i&&a+1<e.length){let t=tF(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===i&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===i&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(i)}return{positionals:t,flags:r}}function tF(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tU(e,t){for(let r of t.positionals??[])e.push(tk(r));t.flags?.relaunch&&e.push("--relaunch"),tE(e,t.runtime)}class tG{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=tG.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 t={};for(let r of tV)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),ti({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=n.dirname(t);a.existsSync(r)||a.mkdirSync(r,{recursive:!0});let i=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let i of(r.push(`context platform=${e.device.platform} device=${tD(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(tx(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tk(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tk(a)),tO(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tk(r)),tO(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tk(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tk(a)),e.positionals.length>1&&t.push(tk(i)),tO(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tk(r)),t.push(tk(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tk(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",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tk(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return tU(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tP(r,tR)),tE(t,e.flags),t.join(" ")}if("record"===e.command)return tC(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tk(r));return tO(t,e),t.join(" ")}(i));return`${r.join("\n")}
2
+ `}(e,this.buildOptimizedActions(e));a.writeFileSync(t,i)}catch{}}defaultTracePath(e){let t=tG.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return n.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return n.join(this.sessionsDir,tG.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return n.join(this.sessionsDir,tG.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return e6(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tG.expandHome(e.saveScriptPath);a.existsSync(this.sessionsDir)||a.mkdirSync(this.sessionsDir,{recursive:!0});let t=tG.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return n.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&&(tx(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(tx(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=eg(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(tx(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 tV=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw","screenshotFullscreen","relaunch","saveScript","noRecord","fps","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"],tq="app-log.pid";function tj(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 tB(e,t){if(!e)return;let r=n.dirname(e);a.existsSync(r)||a.mkdirSync(r,{recursive:!0});let i={pid:t,startTime:Y(t)??void 0,command:el(t)??void 0};a.writeFileSync(e,`${JSON.stringify(i)}
3
+ `)}function tH(e){if(e&&a.existsSync(e))try{a.unlinkSync(e)}catch{}}async function tK(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}async function tz(e){await new Promise(t=>setTimeout(t,e))}function tW(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],a="",i=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))i(`${e}
4
+ `)},flush:()=>{a&&(i(a),a="")}}}function tJ(e,t,r){let a=e.stdout,i=e.stderr;return a&&i?(a.setEncoding("utf8"),i.setEncoding("utf8"),a.on("data",r.writer.onChunk),i.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 tZ(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new tI("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tY(e,t){let r=(await tw("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tX(e,t){var r,a;let i;tZ(t);let n=await tY(e,t),o=await tw("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 i of(r&&a.add(r),e.split("\n")))if(i.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")],i=[];for(let t of a){let r=t.exec(e),a=r?.[1];a&&/^\d+$/.test(a)&&i.push(a)}return i}(i,t))a.add(e);return[...a]}(o.stdout,t,n);if(0===s.length)return null;let l=(r=o.stdout,a=t,i=new Set(s),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(a))return!0;let n=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!n&&i.has(n)}).join("\n"));return 0===l.trim().length?null:{pid:n,text:l,recoveredPids:s}}async function tQ(e,t,r,a,i){let n,s,l="recovering",d=!1,u=(async()=>{try{for(;!d;){let u=await tY(e,t);if(!u){l="recovering",await tz(1e3);continue}let c=o("adb",["-s",e,"logcat","-v","time","--pid",u],{stdio:["ignore","pipe","pipe"]});n=c;let f=tW(r,{redactionPatterns:a});if(s=tJ(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&(tB(i,c.pid),l="active"),await s,tH(i),n=void 0,s=void 0,d)break;l="recovering",await tz(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tH(i)}})();return{backend:"android",getState:()=>l,startedAt:Date.now(),wait:u,stop:async()=>{d=!0,n&&!n.killed&&n.kill("SIGINT"),s&&await tK(s),n&&!n.killed&&n.kill("SIGKILL"),await tK(u),tH(i)}}}function t0(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function t1(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=g(["spawn",t,"log","show","--style","compact","--info","--predicate",t0(r)],{simulatorSetPath:i});"number"==typeof a&&Number.isFinite(a)&&a>0?n.push("--start",`@${Math.floor(a/1e3)}`):n.push("--last","5m");let o=await tw("xcrun",n,{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")}
5
+ `,recoveredLineCount:s.length}}async function t2(e,t,r,a,i,n){let s="active",l=o("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return g(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",t0(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tW(r,{redactionPatterns:a});"number"==typeof l.pid&&tB(n,l.pid);let u=tJ(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(s="failed"),tH(n),e));return{backend:"ios-simulator",getState:()=>s,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tK(u),l.killed||l.kill("SIGKILL"),await tK(u),tH(n)}}}async function t5(e,t,r,a){let i="active",n=o("log",["stream","--style","compact","--predicate",t0(e)],{stdio:["ignore","pipe","pipe"]}),s=tW(t,{redactionPatterns:r});"number"==typeof n.pid&&tB(a,n.pid);let l=tJ(n,t,{endStreamOnClose:!0,writer:s}).then(e=>(0!==e.exitCode&&(i="failed"),tH(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tK(l),n.killed||n.kill("SIGKILL"),await tK(l),tH(a)}}}async function t4(e,t,r,a){let i="active",n=o("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),s=tW(t,{redactionPatterns:r});"number"==typeof n.pid&&tB(a,n.pid);let l=tJ(n,t,{endStreamOnClose:!0,writer:s}).then(e=>(0!==e.exitCode&&(i="failed"),tH(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tK(l),n.killed||n.kill("SIGKILL"),await tK(l),tH(a)}}}let t3=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),t8=/https?:\/\/[^\s"'<>\])]+/i,t6=[/\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 t9(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>re(e)));for(let e of t.entries){let t=re(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t7(e,t){let r=ru(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=ru(t?.maxPayloadChars,2048,64,16384),o=ru(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,i,n){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=ro(s,["method","httpMethod"]),d=ro(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=t3.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=t8.exec(o),h=d??m?.[0];if(!h)return null;let g=u??rr(o)??void 0;if(!(l||f?.[1]||c?.[1]||void 0!==g||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let w={method:p,url:h,status:g,timestamp:ra(o),packetId:ri(o)??void 0,durationMs:rn(o)??void 0,raw:rd(o,n),line:r};if("android"===a&&function(e,t,r){let a=rt(t,r,5),i=e.packetId??a.map(e=>ri(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?rt(t,r,12).filter(e=>ri(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>ra(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>rr(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>rn(e)).find(e=>"number"==typeof e))}(w,e,t),"headers"===i||"all"===i){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return rl(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=rd(e,n))}if("body"===i||"all"===i){let e=rs(o,s,["requestBody","body","payload","request"]),t=rs(o,s,["responseBody","response"]);e&&(w.requestBody=rd(e,n)),t&&(w.responseBody=rd(t,n))}return w}(d,e,l+e+1,a,i,n);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:o}}}function re(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function rt(e,t,r){let a=[],i=Math.max(0,t-r),n=Math.min(e.length-1,t+r);for(let t=i;t<=n;t+=1){let r=e[t]?.trim();r&&a.push(r)}return a}function rr(e){for(let t of t6){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function ra(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 ri(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function rn(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 ro(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 rs(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return rl(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 rl(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function rd(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function ru(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function rc(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 rf(e){let t=n.dirname(e);a.existsSync(t)||a.mkdirSync(t,{recursive:!0}),function(e,t){if(a.existsSync(e)&&!(a.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,i=`${e}.${r}`;a.existsSync(t)&&(a.existsSync(i)&&a.unlinkSync(i),a.renameSync(t,i))}}(e,{maxBytes:rc("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:rc("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function rp(e){var t,r,i,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v}=e,y="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:y,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v},o=ru(t?.maxEntries,25,1,200),s=t?.include??"summary",l=ru(t?.maxPayloadChars,2048,64,16384),d=ru(t?.maxScanLines,4e3,100,2e4),a.existsSync(m)?t7(a.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:d}}),S=[],A=await rm({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tX(u.id,c);if(e){let t=t7(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v});t.entries.length>0&&(I=t9(t,I,h),S.push((r=A,i=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 ${i.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${i.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await rg({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v});e&&(e.dump.entries.length>0?(I=t9(e.dump,I,h),S.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&&S.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===f?S.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===S.length&&("ios"===u.platform&&"simulator"===u.kind?S.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."):S.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&S.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:y,dump:I,notes:S}}async function rm(e){let{device:t,appBundleId:r,appLogPath:i,appLogState:o}=e;if("android"!==t.platform||!r)return null;if(void 0!==o&&"active"!==o)return{reason:"inactive"};if("active"!==o)return null;let s=function(e){let t=function(e){if(!e||!a.existsSync(e))return null;try{return tj(a.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}(n.join(n.dirname(i),tq));if(!s)return null;let l=await tY(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function rh(e,t,r,i){rf(r);let n=a.createWriteStream(r,{flags:"a"}),o=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 t4(e.id,n,o,i):await t2(e.id,t,n,o,e.simulatorSetPath,i);if("android"===e.platform)return tZ(t),await tQ(e.id,t,n,o,i);if("macos"===e.platform)return await t5(t,n,o,i);throw n.end(),new tI("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rg(e){let t=await t1({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t7(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 rw(e){await e.stop(),await tK(e.wait)}async function rv(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 tw("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await tw("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 tw("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 tw("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await tw("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function ry(e){let t=n.dirname(e),r=n.basename(e);a.existsSync(t)||a.mkdirSync(t,{recursive:!0}),a.existsSync(e)?a.truncateSync(e,0):a.writeFileSync(e,"","utf8");let i=0;for(let e of a.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let o=e.slice(r.length+1);if(/^\d+$/.test(o))try{a.unlinkSync(n.join(t,e)),i+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:i}}let rI=new Map;function rS(e){let t=rI.get(e);if(t&&(clearTimeout(t.timer),rI.delete(e),t.deleteAfterDownload))try{a.rmSync(t.artifactPath,{force:!0})}catch{}}let rA=new Map;function rb(e,t){let r=rA.get(e);if(!r)throw new tI("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tI("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function r_(e){let t=rA.get(e);t&&(clearTimeout(t.timer),rA.delete(e),a.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rN(e){let t=await rx(e);await tw("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=n.join(e.tempDir,t);if(!a.existsSync(r))throw new tI("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rx(e){let t=await tw("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new tI("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 tI("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(rM),i=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 tI("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new tI("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 tI("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===i||e.startsWith(`${i}/`)))throw new tI("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,o=i;if(n!==o&&!n.startsWith(`${o}/`))throw new tI("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await tw("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new tI("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function rM(e){if(e.includes("\0"))throw new tI("INVALID_ARGS",`Invalid archive entry: ${e}`);if(n.posix.isAbsolute(e))throw new tI("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=n.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new tI("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rk=eW(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function rD(e,t){return new Promise((r,i)=>{let n,o=a.createWriteStream(t),s=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){o.destroy(),a.rmSync(t,{force:!0}),i(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new tI("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rk});s(e),o.destroy(e),u(e)},rk)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new tI("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");s(e),o.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new tI("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",u),o.on("finish",()=>u()),c(),e.pipe(o)})}async function rP(e){let t,r=e.headers["x-artifact-type"],i=e.headers["x-artifact-filename"];if(!r||!i)throw new tI("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new tI("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 tI("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let o=function(e){let t=e.trim(),r=n.basename(t);if(!r||"."===r||".."===r)throw new tI("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(i),s=(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"),a.mkdtempSync(n.join(u.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=n.join(s,o);return await rD(e,t),{artifactPath:t,tempDir:s}}let t=n.join(s,"artifact.tar");await rD(e,t);let i=await rN({archivePath:t,tempDir:s,platform:"ios",expectedRootName:o});return a.rmSync(t,{force:!0}),{artifactPath:i,tempDir:s}}catch(e){throw a.rmSync(s,{recursive:!0,force:!0}),e}}let rL=new Set(["agent_device.command","agent-device.command"]),rR=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rO=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rE={"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"},rC=new Set([...rL,...rR,...rO,...Object.keys(rE)]);function r$(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rT(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rF(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function rU(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function rG(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rV(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function rq(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=ty(new tI("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:r$(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=ty(new tI(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:r$(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=eK(r.tenantId);if(!e){let e=ty(new tI("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:r$(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rj(){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=n.isAbsolute(t)?t:n.resolve(t);try{e=await import(d(a).href)}catch(e){throw new tI("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let i=e[r];if("function"!=typeof i)throw new tI("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rB(e){let t=await rj(),{handleRequest:r,token:a}=e;return s.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void rH(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void rK(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||rT(i,r$(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rT(i,r$(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rT(i,r$(a.id??null,-32600,"Invalid Request"),400);if(!rC.has(a.method))return void rT(i,r$(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rT(i,r$(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(rL.has(e))return{token:rU(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(rR.has(e)){let e,a=rG(t,"platform");if("ios"!==a&&"android"!==a)throw new tI("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:rU(t,r),session:rG(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rG(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new tI("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new tI("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 tI("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 tI("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 tI("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new tI("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rV(t,"retentionMs")}}}if(rO.has(e)){let e=rG(t,"materializationId")?.trim();if(!e)throw new tI("INVALID_ARGS","Invalid params: materializationId is required");return{token:rU(t,r),session:rG(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rG(t,"requestId"),materializationId:e}}}let a=rE[e];if(a)return{token:rU(t,r),session:rG(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rG(t,"tenantId")??rG(t,"tenant"),runId:rG(t,"runId"),leaseId:rG(t,"leaseId"),leaseTtlMs:rV(t,"ttlMs"),leaseBackend:rG(t,"backend")}};throw new tI("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rL.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rT(i,r$(a.id??null,-32602,"Invalid params: command is required"),400);o=U(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},b(o);let d=()=>{i.writableFinished||e4(o)};e.on("aborted",d),i.on("close",d);let u=await rq(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rT(i,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 rT(i,{jsonrpc:"2.0",id:a.id??null,result:c});rT(i,r$(a.id??null,-32e3,c.error.message,c.error),rF(c.error.code))}catch(t){let e=ty(t);rT(i,r$(a.id??null,-32e3,e.message,e),rF(e.code))}finally{K(o)}})})}async function rH(e,t,a,i){try{var n;let o,s,l=rU({},e.headers),d=rz(l,i);if(d){t.statusCode=rF(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await rq(a,{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 rP(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=r.randomUUID(),(s=setTimeout(()=>{r_(o)},3e5)).unref(),rA.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:f}))}catch(r){let e=ty(r);t.statusCode=rF(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rK(e,t,r,i){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=rU({},e.headers),s=rz(o,i);if(s){t.statusCode=rF(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await rq(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:o,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=rI.get(e);if(!r)throw new tI("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tI("UNAUTHORIZED","Artifact belongs to a different tenant");if(!a.existsSync(r.artifactPath))throw rS(e),new tI("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=a.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=ty(e);t.statusCode=rF(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&rS(n)}),u.pipe(t)}catch(r){let e=ty(r);t.statusCode=rF(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rz(e,t){return t&&e!==t?ty(new tI("UNAUTHORIZED","Invalid token")):null}function rW(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rJ(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rZ(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";throw new tI("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rY{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=rZ(e.backend),a=eK(e.tenantId);if(!a)throw new tI("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rW(e.runId);if(!i)throw new tI("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(a,i,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:r.randomBytes(16).toString("hex"),tenantId:a,runId:i,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=rJ(e.leaseId);if(!t)throw new tI("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new tI("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=rJ(e.leaseId);if(!t)throw new tI("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=rZ(e.backend),r=eK(e.tenantId);if(!r)throw new tI("INVALID_ARGS","tenant isolation requires tenant id.");let a=rW(e.runId);if(!a)throw new tI("INVALID_ARGS","tenant isolation requires run id.");let i=rJ(e.leaseId);if(!i)throw new tI("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new tI("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new tI("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 tI("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 tI("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=eK(t),i=rW(r);if(t&&!a)throw new tI("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new tI("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new tI("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rX=eW(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rQ=new Map;async function r0(e){let t=await c.mkdtemp(n.join(u.tmpdir(),"agent-device-materialized-"));try{let a=await r5(e.installablePath,n.join(t,"installable")),i=e.archivePath?await r5(e.archivePath,n.join(t,"archive")):void 0,o=r.randomUUID(),s=e.ttlMs??rX,l=Date.now()+s,d=setTimeout(()=>{r1(o)},s);return rQ.set(o,{rootPath:t,installablePath:a,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:o,installablePath:a,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await c.rm(t,{recursive:!0,force:!0}),e}}async function r1(e,t){let r=rQ.get(e);if(!r)throw new tI("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tI("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rQ.delete(e),await c.rm(r.rootPath,{recursive:!0,force:!0})}async function r2(e){let t=Array.from(rQ.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await r1(e)}))}async function r5(e,t){let r=await c.stat(e);await c.mkdir(t,{recursive:!0});let a=n.join(t,n.basename(e));return r.isDirectory()?await c.cp(e,a,{recursive:!0}):await c.copyFile(e,a),a}async function r4(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 tI("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await e9(e.session.device),e.session.device}if(!r)throw new tI("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await eR(e.flags??{});return await e9(a),a}async function r3(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,o,s=(n=function(e){let t=e.meta?.installSource;if(!t)throw new tI("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new tI("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new tI("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:rb(o,t.meta?.tenantId)},cleanup:()=>{r_(o)}}:{source:n,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 tI("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await r4({session:i,flags:t.flags});if(!tl("install",d))return N("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=th(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:n}=await import("./155.js"),{prepareIosInstallArtifact:o}=await import("./155.js"),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await r0({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs})),await n(d,c.installablePath),!c.bundleId)throw new tI("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=ev(o,r8(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await r1(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./155.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./155.js"),p=await c(s.source,{signal:u});try{l.enabled&&(e=await r0({archivePath:p.archivePath,installablePath:p.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs}));let n=await f(d,p.installablePath,p.packageName);if(!n)throw new tI("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./155.js"),s=o(n),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...s?{appName:s}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=ev(u,r8(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await r1(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:ty(e)}}}function r8(e){return`Installed: ${ee(e)}`}async function r6(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new tI("INVALID_ARGS","release_materialized_paths requires a materializationId");return await r1(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:ty(e)}}}let r9=eW(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r7=eW(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function ae(e,t,r){return t||at(r)?null:N("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function at(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function ar(e){return"ios"===e.platform&&"simulator"===e.kind}async function aa(e,t){ar(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function ai(e){let t=at(e.flags)||!e.session?await eR(e.flags??{}):await an(e.session.device);return!1!==e.ensureReady&&await e9(t),t}async function an(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 eR(t)}catch(e){if(!(e instanceof tI)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await eR({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function ao(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 as=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function al(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ad(e){let t=e?.trim();return t&&t.length>0?t:void 0}function au(e,t){if(void 0!==e){if("string"!=typeof e)throw new tI("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return ad(e)}}function ac(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new tI("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function af(e){if("ios"===e||"android"===e)return e}async function ap(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!em(r)||em(a)||await eG({device:i.device,appId:i.appBundleId})}async function am(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(o))return N("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){em(l)&&s?.appBundleId&&await eG({device:s.device,appId:s.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===o)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let d=af(tf(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return N("INVALID_ARGS","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 N("INVALID_ARGS",`runtime set targets ${d}, but session "${i}" is already bound to ${s.device.platform}.`);let u={platform:(t=a.flags,r={platform:d,metroHost:ad(t?.metroHost),metroPort:ac(t?.metroPort),bundleUrl:ad(t?.bundleUrl),launchUrl:ad(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===al(u)?N("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(n.setRuntimeHints(i,u),{ok:!0,data:{session:i,configured:!0,runtime:u}})}let ah="open-command-roundtrip",ag="Not implemented for this platform in this release.",aw=new Set(["app","desktop","frontmost-app"]);async function av(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await tn();return{appBundleId:t.bundleId,appName:t.appName}}async function ay(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return eU(t)?"macos"===e.platform?void 0:"device"===e.kind?e3(r,t):void 0:await aI(e,t)}async function aI(e,t){try{let{resolveIosApp:r}=await import("./155.js");return await r(e,t)}catch{return}}async function aS(e,t){if(!("android"!==e.platform||!t||eU(t)))try{let{resolveAndroidApp:r}=await import("./155.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function aA(e,t,r,a){return await ay(e,t,r)??await a(e,t)??("android"===e.platform&&t&&eU(t)?r:void 0)}function ab(e){return N("INVALID_ARGS",e)}function a_(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:i}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return i??"app";if("linux"===t.platform){if(!r)return"app";let e=ed(r);if(!aw.has(e))throw new tI("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new tI("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new tI("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?ed(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new tI("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return N(e instanceof tI?e.code:"INVALID_ARGS",String(e.message))}}function aN(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&eU(r)?ab("open --relaunch does not support URL targets."):"app"!==a?ab("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===e$(r)?ab(q(r)):null:null}async function ax(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await e9(i);let{appBundleId:l,appName:d}=await aM({device:i,surface:n,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=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 tI("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!as.includes(e));if(i)throw new tI("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${as.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new tI("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new tI("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:au(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new tI("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return ac(e)}}(t.metroPort),bundleUrl:au(t.bundleUrl,"bundleUrl"),launchUrl:au(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:af(i.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let i=r?.platform,n=af(i);if(a.platform&&r&&!n)throw new tI("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${i}.`);if(a.platform&&n&&a.platform!==n)throw new tI("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${i}. Clear the runtime hints or use a different session.`);return n&&a.platform!==n?{...a,platform:n}:a}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&al(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=tv(t);return N(e.code,e.message,e.details)}}({req:t,sessionStore:a,sessionName:r,device:i});if(!u.ok)return{type:"response",response:u};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await ap({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function aM(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await av(r);return{appBundleId:n.appBundleId??await aA(t,a,i,aS),appName:n.appName??a}}let ak=new Map;async function aD(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await eI(t.id),await w(t,"close",[r],a,i),await aa(t,r9)}async function aP(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||eU(d)||await w(r,"open",[l],a.flags?.out,{...eV(i,a.flags,n,o)})}async function aL(e){var t,r,a;let{req:i,sessionName:n,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:f,appBundleId:p,runtime:m,existingSession:h}=e,g=i.flags?.relaunch===!0,v=h?.trace?.outPath;if(g&&d){let e=p??d;await aD({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eV(s,i.flags,p??h?.appBundleId,v)}})}await eL({device:l,appId:p,runtime:m});let y=Date.now();await w(l,"open",u,i.flags?.out,{...eV(s,i.flags,p)}),await aP({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:v,openPositionals:u});let I=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:ah,appTarget:d,appBundleId:p}:void 0;if(await aa(l,r7),F(i.meta?.requestId)){let e=eA();return N(e.code,e.message,e.details)}h&&tm(h,"open",h.snapshot);let S=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:n,device:l,surface:f,appBundleId:p,appName:c,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(t=o,r=n,(a=m)&&(0===al(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let A=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:i};return r&&(d.appName=r),a&&(d.appBundleId=a),n&&(d.startup=n),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,...M(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:I,device:l,runtime:m,runtimeHintCount:al});return o.recordAction(S,{command:"open",positionals:u,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:A}),o.set(n,S),{ok:!0,data:A}}async function aR(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return N("SESSION_NOT_FOUND",`Session "${r}" not found.`);let n=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(n?e.appName:void 0),l=a_(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?ab("open --relaunch requires an app name or an active session app."):ab("Session already active. Close it first or pass a new --session name.");let d=aN({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await an(e.device),c=await ax({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await aL({req:t,sessionName:r,sessionStore:i,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 n=t.flags?.relaunch===!0,o=t.positionals?.[0];if(n&&!o)return ab("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&eU(r)?ab("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===e$(r)?ab(q(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await eR(t.flags??{}),d=a_(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=aN({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await D(ak,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return N("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await ax({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await aL({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:d})})}async function aO(e){let t=await tw("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 aE(e){let{device:t,shutdownRequested:r}=e;if(r&&(ar(t)||"android"===t.platform&&"emulator"===t.kind))try{return ar(t)?await ey(t):await aO(t)}catch(t){let e=ty(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aC(e){if(await eI(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eF("dismiss",t).catch(t=>{ti({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function a$(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return N("SESSION_NOT_FOUND","No active session");n.appLog&&await rw(n.appLog),t.positionals&&t.positionals.length>0&&(("ios"===n.device.platform||"macos"===n.device.platform)&&await aC(n),await w(n.device,"close",t.positionals,t.flags?.out,{...eV(a,t.flags,n.appBundleId,n.trace?.outPath)}),await aa(n.device,r9)),("ios"===n.device.platform||"macos"===n.device.platform)&&await aC(n),em(i.getRuntimeHints(r))&&n.appBundleId&&await eG({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...M(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await r2(r).catch(()=>{}),i.delete(r);let o=await aE({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:ev({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...M(`Closed: ${r}`)}}}let aT=["platform","target","device","udid","serial","verbose","out"];function aF(e,t){let r=e??{};for(let e of aT)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aU={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./155.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./155.js");return await a(e,t,r)}},aG={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./155.js"),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await import("./155.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aV(e){let{req:t,command:r,sessionName:i,sessionStore:n,deployOps:o}=e,s=n.get(i),l=t.flags??{},d=ae(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return N("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,i=f?rb(f,t.meta?.tenantId):tG.expandHome(c);if(!a.existsSync(i))return N("INVALID_ARGS",`App binary not found: ${i}`);let d=await ai({session:s,flags:l,ensureReady:!1});if(!tl(r,d))return N("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,i),r=t.bundleId;e=r?{app:u,appPath:i,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:i,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,i),r=t.package;e=r?{app:u,appPath:i,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:i,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=ev(e,(p=e,`Installed: ${p.appName??eh(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&r_(f)}}async function aq(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return N("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??P;if(!Number.isInteger(i)||i<1||i>1e3)return N("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=ec(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await aj(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=tv(t);return N(e.code,e.message,e.details)}}async function aj(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aF(e,n)}(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()-n;return s.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:i,error:s.error}}async function aB(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new tI("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await aH({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aK({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await az(t,u),a=!0)}else t=(await aK({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await az(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function aH(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await tw("xcrun",g(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:J});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let[a,i]of Object.entries(e.devices??{}))if(!r||aW(a).includes(aW(r))){for(let e of i)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function aK(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await tw("xcrun",g(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new tI("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.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(n.stdout??"").trim();if(!o)throw new tI("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function az(e,t){let r=await tw("xcrun",g(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:J});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 aW(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aJ(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,i=e5(e.iosSimulatorDeviceSet);if(!r)return N("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await aB({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:e9});return{ok:!0,data:{udid:n.udid,device:n.device,runtime:n.runtime,ios_simulator_device_set:i??null,created:n.created,booted:n.booted}}}catch(t){let e=tv(t);return N(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=er(t.flags?.androidDeviceAllowlist),a=tf(t.flags?.platform),i=h({simulatorSetPath:e5(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./155.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./155.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./155.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./155.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=tv(t);return N(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=ae(t.command,e,i);if(n)return n;let o=await ai({session:e,flags:i,ensureReady:!0});if(!tl("apps",o))return N("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(Q(o.platform)){let{listIosApps:e}=await import("./155.js");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 import("./155.js");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 aZ(e){let{ensureAndroidEmulatorBooted:t}=await import("./155.js");return await t(e)}let aY='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',aX='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function aQ(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=tf(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return N("SESSION_NOT_FOUND","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=ae("appstate",i,n);if(s)return s;let l=(i?.device.platform==="ios"||i?.device.platform==="macos")&&function(e,t){if(!t)return!1;if(!at(e))return!0;let r=tf(e?.platform);return!(r&&!ts(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())}(n,i);if("ios"===o&&!l)return N("SESSION_NOT_FOUND",aY);if("macos"===o&&!l)return N("SESSION_NOT_FOUND",aX);if(l&&i){let e=i.appName??i.appBundleId;if(!i.appName&&!i.appBundleId){if("macos"===i.device.platform&&i.surface&&"app"!==i.surface&&"frontmost-app"!==i.surface)return{ok:!0,data:{platform:i.device.platform,appName:i.surface,appBundleId:i.appBundleId,source:"session",surface:i.surface}};let e="macos"===i.device.platform?"macOS":"iOS";return N("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:i.device.platform,appName:e??"unknown",appBundleId:i.appBundleId,source:"session",surface:i.surface??"app",..."ios"===i.device.platform?{device_udid:i.device.id,ios_simulator_device_set:i.device.simulatorSetPath??null}:{}}}}let d=await ai({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return N("SESSION_NOT_FOUND",aY);if("macos"===d.platform)return N("SESSION_NOT_FOUND",aX);let{getAndroidAppState:u}=await import("./155.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function a0(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=ae(t.command,i,n);if(o)return o;let s="android"===(tf(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return N("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=ao({flags:n,sessionDevice:i?.device}),u=s&&!!d,c=!1;try{e=await ai({session:i,flags:n,ensureReady:!1})}catch(r){let t=tv(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return N("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await aZ({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return N("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return N("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=ao({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return N("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aZ({avdName:t,serial:n.serial,headless:!0})}await e9(e)}else("android"!==e.platform||!0!==e.booted)&&await e9(e);return tl("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:N("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await aQ({req:t,sessionName:r,sessionStore:a}):null}function a1(e){return Math.round(10*e)/10}let a2="adb-shell-dumpsys-cpuinfo",a5="adb-shell-dumpsys-meminfo";async function a4(e,t){try{let r=await tw("adb",eQ(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,o;let e=r.trim();if(0===e.length)continue;let s=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!s)continue;let l=Number(s[1]),d=s[2];Number.isFinite(l)&&(n=d,o=t,n===o||n.startsWith(`${o}:`))&&(i+=l,a.add(d))}return{usagePercent:a1(i),measuredAt:r,method:a2,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw a8("cpu",t,e)}}async function a3(e,t){try{let r=await tw("adb",eQ(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new tI("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=a6(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!==a9(e));if(!r)break;return a9(r)??void 0}}(e);if(void 0===a)throw new tI("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:a6(e,"TOTAL RSS"),measuredAt:r,method:a5}}(r.stdout,t,new Date().toISOString())}catch(e){throw a8("memory",t,e)}}function a8(e,t,r){return r instanceof tI&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new tI(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof tI?r:new tI("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a6(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a9(a[1])??void 0}function a9(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a7="ps-process-snapshot",ie="ps-process-snapshot",it="xctrace-activity-monitor",ir="xctrace-activity-monitor";async function ia(e,t){if("ios"===e.platform&&"device"===e.kind)return await is(e,t);let r=await io(e,t),a=await im(e,r);if(0===a.length)throw new tI("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 i=new Date().toISOString(),o=k(a.map(e=>n.basename(ih(e.command))));return ig({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:o,cpuMethod:a7,memoryMethod:ie})}async function ii(e){let t=z(e),r=iw(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new tI("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??""}),i=a.indexOf("pid"),n=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(i<0||n<0||o<0||s<0)throw new tI("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let i of t)r(i)&&a.push(i),a.push(...e(i.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,f;let t=e.children;if(0===t.length)continue;for(let e of t){let t=iw(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:iv(e),processName:iI(e)})}let r=iy(t[i],u),a=(c=t[n],f=u,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:iI(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:iy(t[o],u),residentMemoryBytes:iy(t[s],u)})}return d}async function io(e,t){let r="macos"===e.platform?await ic(t):await ip(e,t),a="macos"===e.platform?n.join(r,"Contents","Info.plist"):n.join(r,"Info.plist"),i=await te(a,"CFBundleExecutable");if(!i)throw new tI("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?n.join(r,"Contents","MacOS",i):void 0}}async function is(e,t){let r=await il(e,t),a=await id(e,t),i=await id(e,t),n=iu(await ii(a.xml),r,t,e),o=iu(await ii(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new tI("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new tI("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 ig({usagePercent:Math.max(0,o.cpuTimeNs-n.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(i.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:it,memoryMethod:ir})}async function il(e,t){let r=(await Z(e,"all")).find(e=>e.bundleId===t);if(!r)throw new tI("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new tI("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=l(a),n=(await en(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new tI("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function id(e,t){let r=await i.mkdtemp(n.join(u.tmpdir(),"agent-device-ios-perf-")),a=n.join(r,"sample.trace"),o=n.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"],n=await tw("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==n.exitCode)throw new tI("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr,appBundleId:t,deviceId:e.id,hint:iS(n.stdout,n.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",o],d=await tw("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new tI("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:l,exitCode:d.exitCode,stdout:d.stdout,stderr:d.stderr,appBundleId:t,deviceId:e.id,hint:iS(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await i.readFile(o,"utf8")}}finally{await i.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function iu(e,t,r,a){let i=new Set(t.map(e=>e.pid)),o=new Set(t.map(e=>n.basename(l(e.executable)))),s=e.filter(e=>i.has(e.pid)||o.has(e.processName));if(0===s.length)throw new tI("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 d=new Map;for(let e of s){let t=d.get(e.pid);if(!t){d.set(e.pid,e);continue}d.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:iA(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iA(t.residentMemoryBytes,e.residentMemoryBytes)})}let u=[...d.values()],c=u.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=u.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:c.length>0?c.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:k(u.map(e=>e.processName))}}async function ic(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await tw("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new tI("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 tI("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function ip(e,t){let r=tr(e,["get_app_container",e.id,t,"app"]),a=await tw("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new tI("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 i=a.stdout.trim();if(0===i.length)throw new tI("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function im(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:tr(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 i=Number(a[1]),n=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(o)&&t.push({pid:i,cpuPercent:n,rssKb:o,command:s})}return t})((await tw("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=ih(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||n.basename(i)===a.executableName})}function ih(e){let[t=""]=e.trim().split(/\s+/,1);return t}function ig(e){return{cpu:{usagePercent:a1(e.usagePercent),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 iw(e,t){for(let r of e){if(t(r))return r;let e=iw(r.children,t);if(e)return e}}function iv(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 iy(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:iv(e):null}function iI(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function iS(e,t){let r=e_(e,t);if(r)return r;let a=`${e}
6
+ ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?$: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 iA(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function ib(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===ah&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:ah,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),i=a?{available:!0,lastDurationMs:a.durationMs,lastMeasuredAt:a.measuredAt,method:ah,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:ah},n={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:i,fps:{available:!1,reason:ag},memory:{available:!1,reason:ag},cpu:{available:!1,reason:ag}},sampling:{startup:{method:ah,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:a5,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:a2,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:ir,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:it,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:ie,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:a7,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 n;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 n.metrics.memory={available:!1,reason:t},n.metrics.cpu={available:!1,reason:t},n}let[o,s]=await i_(e);return n.metrics.memory=iN(o),n.metrics.cpu=iN(s),n}async function i_(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([a3(e.device,t),a4(e.device,t)]);return[r,a]}try{let r=await ia(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 iN(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=ty(e.reason);return{available:!1,reason:t.message,error:t}}let ix=["path","start","stop","doctor","mark","clear"],iM=`logs requires ${ix.slice(0,-1).join(", ")}, or ${ix.at(-1)}`,ik=["dump","log"],iD=`network requires ${ik.join(" or ")}`,iP=["summary","headers","body","all"],iL=`network include mode must be one of: ${iP.join(", ")}`;async function iR(e){let{req:t}=e;return"perf"===t.command?iO(e):"logs"===t.command?iE(e):"network"===t.command?iU(e):null}async function iO(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return N("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await ib(a)}}catch(e){return{ok:!1,error:ty(e)}}}async function iE(e){let{req:t,sessionName:r,sessionStore:i}=e,n=i.get(r);if(!n)return N("SESSION_NOT_FOUND","logs requires an active session");if(!tl("logs",n.device))return N("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return ix.includes(o)?s&&"clear"!==o?N("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===o?function(e,t,r){let i=r.resolveAppLogPath(t),n=function(e){if(!a.existsSync(e))return{exists:!1,sizeBytes:0};let t=a.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(i);return{ok:!0,data:{path:i,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,i):"doctor"===o?iC(n,r,i):"mark"===o?function(e,t,r){let i,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return rf(o),i=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
7
+ `,a.appendFileSync(o,i,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,i):"clear"===o?i$(n,r,i,s):"start"===o?iT(n,r,i):"stop"===o?iF(n,r,i):N("INVALID_ARGS",iM):N("INVALID_ARGS",iM)}async function iC(e,t,r){let a=r.resolveAppLogPath(t),i=await rv(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:i.checks,notes:i.notes}}}async function i$(e,t,r,a){if(e.appLog&&!a)return N("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return N("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:ry(i)};e.appLog&&await rw(e.appLog);let n=ry(i),o=r.resolveAppLogPidPath(t);try{let a=await rh(e.device,e.appBundleId,i,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:i,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...n,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:ty(a)}}}async function iT(e,t,r){if(e.appLog)return N("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return N("INVALID_ARGS","logs start requires an app session; run open <app> first");let a=r.resolveAppLogPath(t),i=r.resolveAppLogPidPath(t);try{let n=await rh(e.device,e.appBundleId,a,i);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:ty(e)}}}async function iF(e,t,r){if(!e.appLog)return N("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rw(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iU(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return N("SESSION_NOT_FOUND","network requires an active session");if(!tl("network",i.device))return N("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!ik.includes(n))return N("INVALID_ARGS",iD);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return N("INVALID_ARGS","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 N("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return iP.includes(a)?{ok:!0,include:a}:N("INVALID_ARGS",iL)}(t);if(!s.ok)return s;let{include:l}=s,d=await rp({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!i.appLog,state:i.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let iG=new Set(["ios","android","macos","linux"]);function iV(e,t,r){let a=e[t];if(void 0!==a)throw new tI("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 iq(e){return!!e&&!Number.isNaN(Number(e))}let ij=/[*?[\]{}]/;async function iB(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;b(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=tv(e);return N(t.code,t.message)}).finally(()=>{K(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,e4(i),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}}}}(n,[...d]))},n)})]):await c}finally{t&&clearTimeout(t),u&&(await iH(c)||ti({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){ti({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:tv(e).message}})}}}async function iH(e){return await Promise.race([e.then(()=>!0),f(2e3).then(()=>!1)])}async function iK(e){let{req:t,sessionName:r,runReplay:i,cleanupSession:o}=e;if((t.positionals?.length??0)===0)return N("INVALID_ARGS","test requires at least one path or glob");try{var s,l,d,u,c,f;let e,p,m,h,g,w=function(e){let{inputs:t,cwd:r,platformFilter:i}=e,o=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,i;let o=tG.expandHome(e,t);if(a.existsSync(o)){let t=a.statSync(o);if(t.isDirectory())return a.globSync("**/*.ad",{cwd:o}).map(e=>n.join(o,e));if(t.isFile()){if(".ad"!==n.extname(o))throw new tI("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[o]}return[]}if(r=e,!ij.test(r)&&(i=o,!ij.test(i)))throw new tI("INVALID_ARGS",`test input not found: ${e}`);let s=n.isAbsolute(o)?o:e;return a.globSync(s,{cwd:n.isAbsolute(o)?void 0:t}).map(e=>n.isAbsolute(e)?e:n.resolve(t,e)).filter(e=>".ad"===n.extname(e)&&function(e){try{return a.statSync(e).isFile()}catch{return!1}}(e))})(e,o)))].map(e=>n.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var d,u;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&&iG.has(e)&&iV(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&iV(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&iV(r,"retries",Math.floor(e))}}return r}(a.readFileSync(e,"utf8"));if(!i){l.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){l.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${i}`});continue}d=i,u=t.platform,("apple"===d?"apple"===u||"ios"===u||"macos"===u:u===d)&&l.push({kind:"run",path:e,metadata:t})}if(0===l.filter(e=>"run"===e.kind).length){let e=i?` for --platform ${i}`:"";throw new tI("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),v=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),y=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tG.expandHome(t??".agent-device/test-artifacts",r);return n.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:v}),I=[],S=Date.now(),A=0;for(let e of w){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let a=await iz({entry:e,sessionName:r,suiteInvocationId:v,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:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:y,runReplay:i,cleanupSession:o});if(I.push(a),t.flags?.failFast===!0)break}let b=(u=w.length,c=I,f=Date.now()-S,e=c.filter(e=>"passed"===e.status).length,m=(p=c.filter(e=>"failed"===e.status)).length,h=c.filter(e=>"skipped"===e.status).length,g=e+m,{total:u,executed:g,passed:e,failed:m,skipped:h,notRun:Math.max(0,u-g-h),durationMs:f,failures:p,tests:c});return{ok:!0,data:b}}catch(t){let e=tv(t);return N(e.code,e.message)}}async function iz(e){var t,r;let i,o,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,v=Date.now(),y=n.join(h,(t=s.path,(0===(o=c?n.relative(c,t):n.basename(t)).length||o.startsWith("..")?n.basename(t):o).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",S=0;for(let e=0;e<=p;e+=1){S=e+1;let t=function(e,t,r,a,i=0){let o=n.basename(r,n.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${o?`-${o}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),o=n.join(y,`attempt-${S}`);r=s.path,a.mkdirSync(o,{recursive:!0}),a.copyFileSync(r,n.join(o,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:o}=e;return U(`${t??r}:test:${i+1}:${n.basename(a)}:attempt:${o+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await iB({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:i,attempts:o,maxAttempts:s,attemptArtifactsDir:l}=e,d=[...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||d.push(t.error.logPath);let u=function(e,t){let r=[],i=new Map;for(let o of e){if(!function(e){try{return a.statSync(e).isFile()}catch{return!1}}(o))continue;let e=function(e,t){let r=n.extname(e),a=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${a}-${i+1}${r}`}(n.basename(o),i),s=n.join(t,e);n.resolve(o)!==n.resolve(s)&&a.copyFileSync(o,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${i}`,`attempt: ${o}/${s}`,`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;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");u.length>0&&c.push(`copiedArtifacts: ${u.map(e=>n.basename(e)).join(", ")}`);let f=n.join(l,"result.txt"),p=`${c.join("\n")}
8
+ `;a.writeFileSync(f,p),t.ok||a.writeFileSync(n.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:S,maxAttempts:p+1,attemptArtifactsDir:o}),i=h,I=t,h.ok)break}let A=Date.now()-v;if(i?.ok)return{file:s.path,session:I,status:"passed",durationMs:A,attempts:S,artifactsDir:y,replayed:"number"==typeof i.data?.replayed?i.data.replayed:0,healed:"number"==typeof i.data?.healed?i.data.healed:0};let b=i?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:i?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:I,status:"failed",durationMs:A,attempts:S,artifactsDir:y,error:b}}function iW(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=es(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 iJ(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(tx(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let n=i.get(r);if(!n)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),tx(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}=eX(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=iW(e.positionals??[]);r&&t.push(r)}return k(t).filter(e=>e.trim().length>0)})(t).map(e=>B(e)).filter(e=>null!==e);if(0===o.length)return null;let s=tx(t.command)||"fill"===t.command,l=tx(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await iZ(n,t,a,s,i);for(let e of o){let r=A(d.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=ew(r.node,n.device.platform,{action:tx(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tx(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=eg(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}=eX(t.positionals);if(!e)continue;let i=r?.rest.join(" ").trim()??"",n=[e,a];return"text"===e&&i.length>0&&n.push(i),{...t,positionals:n}}if("wait"===t.command){let{selectorTimeout:e}=iW(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function iZ(e,t,r,a,i){let n=await w(e.device,"snapshot",[],t.flags?.out,{...eV(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:ei(t.flags?.snapshotRaw?o:eP(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return e.snapshot=s,i.set(e.name,e),s}async function iY(e){let{req:t,sessionName:r,logPath:i,sessionStore:n,invoke:o}=e,s=t.positionals?.[0];if(!s)return N("INVALID_ARGS","replay requires a path");let l="",d=new Set;try{l=tG.expandHome(s,t.meta?.cwd);let e=a.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return N("INVALID_ARGS","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,i=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!i)break;i="\\"===t&&!i,"\\"!==t&&(i=!1),a+=1}if(a>=e.length)throw new tI("INVALID_ARGS",`Invalid replay script line: ${e}`);let n=e.slice(r,a+1);t.push(JSON.parse(n)),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,...i]=r;if("context"===a)return null;let n={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){n.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){n.flags.snapshotCompact=!0;continue}if("--raw"===t){n.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(n.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){n.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}return n}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 i=tT(r);return{positionals:i.positionals,flags:a,runtime:(t=i.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?i.flags:void 0}}(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n.runtime=e.runtime,n}if("runtime"===a){let e=tT(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(tx(a)){let e=t$(a,i);if(Object.assign(n.flags,e.flags),0===e.positionals.length)return n;let t=e.positionals[0];if(t.startsWith("@"))return n.positionals=[t],e.positionals[1]&&(n.result={refLabel:e.positionals[1]}),n;let r=e.positionals[0],o=e.positionals[1];return iq(r)&&iq(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=t$(a,i);if(Object.assign(n.flags,e.flags),e.positionals.length<2)return n.positionals=e.positionals,n;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(n.positionals=[t,e.positionals.slice(2).join(" ")],n.result={refLabel:e.positionals[1]}):n.positionals=[t,e.positionals[1]],n):(n.positionals=[t,e.positionals.slice(1).join(" ")],n)}if("get"===a){if(i.length<2)return n.positionals=i,n;let e=i[0],t=i[1];return t.startsWith("@")?(n.positionals=[e,t],i[2]&&(n.result={refLabel:i[2]})):n.positionals=[e,i.slice(1).join(" ")],n}if("swipe"===a||"type"===a){let e=t$(a,i);return Object.assign(n.flags,e.flags),n.positionals=e.positionals,n}if("record"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--hide-touches"===r){n.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.fps=Math.floor(e)),t+=1;continue}e.push(r)}return n.positionals=e,n}if("screenshot"===a){let e=[];for(let t of i){if("--fullscreen"===t){n.flags.screenshotFullscreen=!0;continue}e.push(t)}return n.positionals=e,n}return n.positionals=i,n}(r);e&&t.push(e)}return t}(e),f=t.flags?.replayUpdate===!0,p=0;for(let e=0;e<c.length;e+=1){let a=c[e];if(!a||"replay"===a.command)continue;let s=await iX({req:t,sessionName:r,action:a,invoke:o});if(s.ok){i0(s).forEach(e=>d.add(e));continue}if(!f)return iQ(s,a,e,l,[...d]);let u=await iJ({action:a,sessionName:r,logPath:i,sessionStore:n});if(!u)return iQ(s,a,e,l,[...d]);if(c[e]=u,!(s=await iX({req:t,sessionName:r,action:u,invoke:o})).ok)return iQ(s,u,e,l,[...d]);i0(s).forEach(e=>d.add(e)),p+=1}return f&&p>0&&function(e,t,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${tD(r.device.name)}${e} theme=unknown`)}for(let e of t)i.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",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tU(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tP(r,tR));return tE(t,e.flags),t.join(" ")}if("record"===e.command)return tC(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tk(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}for(let r of e.positionals??[])t.push(tk(r));return tO(t,e),t.join(" ")}(e));let n=`${i.join("\n")}
9
+ `,o=`${e}.tmp-${process.pid}-${Date.now()}`;a.writeFileSync(o,n),a.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=tv(t);return N(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function iX(e){var t;let{req:r,sessionName:a,action:i,invoke:n}=e;return await n({token:r.token,session:a,command:i.command,positionals:i.positionals??[],flags:(t=r.flags,aF(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function iQ(e,t,r,a,i=[]){let n;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${n=(t.positionals??[]).map(e=>tk(e)),[t.command,...n].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:i}}}}function i0(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 a.statSync(e).isFile()}catch{return!1}})(e)))]}async function i1(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await iY({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await iK({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await iY({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:i,invoke:async e=>{var t;return t=await n(e),l&&i0(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await a$({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let i2=new Set(["session_list","ensure-simulator","devices","apps"]),i5=new Set(["boot","appstate"]),i4=new Set(["perf","logs","network"]),i3=new Set(["replay","test"]);async function i8(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=i.get(r),u=t.flags??{},c=ae(n,d,u);if(c)return c;let f=await ai({session:d,flags:u,ensureReady:!0});if(!tl(n,f))return N("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await w(f,n,o,t.flags?.out,{...eV(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,p,f):d;i.recordAction(e,{command:n,positionals:s??o,flags:t.flags??{},result:p??{}}),e!==d&&i.set(r,e)}return{ok:!0,data:p??{}}}async function i6(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=ae("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return N("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await ai({session:n,flags:o,ensureReady:!0});if(!tl("clipboard",d))return N("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await w(d,"clipboard",t.positionals??[],t.flags?.out,{...eV(a,t.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function i9(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(i2.has(t.command))return await aJ({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await am({req:t,sessionName:r,sessionStore:i});if(i5.has(t.command))return await a0({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await i6({req:t,sessionName:r,logPath:a,sessionStore:i});if("keyboard"===t.command){let e=i.get(r),n=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==n||"ios"!==tf((t.flags??{}).platform)?await i8({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):N("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(i4.has(t.command))return await iR({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aV({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?aG:aU});if("install_source"===t.command)return await r3({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r6({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await i8({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=e1(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tG.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):N("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await i8({req:t,sessionName:r,logPath:a,sessionStore:i,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await aA(e.device,r,e.appBundleId,aS)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aR({req:t,sessionName:r,logPath:a,sessionStore:i}):i3.has(t.command)?await i1({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await aq(t,r,n):"close"===t.command?await a$({req:t,sessionName:r,logPath:a,sessionStore:i}):null}function i7(e){let{session:t,refInput:r,fallbackLabel:a,requireRect:i,invalidRefMessage:n,notFoundMessage:o}=e;if(!t.snapshot)return N("INVALID_ARGS","No snapshot in session. Run snapshot first.");let s=eC(r);if(!s)return N("INVALID_ARGS",n);let l=eM(t.snapshot.nodes,s);return((!l||i&&!l.rect)&&a.length>0&&(l=to(t.snapshot.nodes,a)),l&&(!i||l.rect))?{ok:!0,target:{ref:s,node:l,snapshotNodes:t.snapshot.nodes}}:N("COMMAND_FAILED",o)}function ne(e){let t=nt(e);if(!t)return null;let r=et(t);return Number.isFinite(r.x)&&Number.isFinite(r.y)?r:null}function nt(e){if(!e)return null;let t=Number(e.x),r=Number(e.y),a=Number(e.width),i=Number(e.height);return Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(a)&&Number.isFinite(i)&&!(a<0)&&!(i<0)?{x:t,y:r,width:a,height:i}:null}async function nr(e){let{session:t,refInput:r,fallbackLabel:a,commandLabel:i,promoteToHittableAncestor:n,invalidRefMessage:o,missingBoundsMessage:s,invalidBoundsMessage:l,reqFlags:d,sessionStore:u,contextFromFlags:c,captureSnapshotForSession:f,resolveRefTarget:p}=e,m=p({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:o,notFoundMessage:s});if(!m.ok)return m;let{ref:h}=m.target,g=n?na(m.target.snapshotNodes,m.target.node):m.target.node,w=m.target.snapshotNodes,y=ne(g.rect);if(!y){let e=await f(t,d,u,c,{interactiveOnly:!0}),r=eM(e.nodes,h),i=a.length>0?to(e.nodes,a):null,o=r&&n?na(e.nodes,r):r,s=i&&n?na(e.nodes,i):i,l=ne(s?.rect),p=ne(o?.rect)?o:l?s:o??s,m=ne(p?.rect);p&&m&&(g=p,w=e.nodes,y=m)}if(!y)return N("COMMAND_FAILED",l);let I=g.rect?e2(g,w):null;return g.rect&&I&&!v(g,w)?{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${r} is off-screen and not safe to ${i}`,hint:`Run scrollintoview ${r}, then retry ${i} with the returned currentRef or a fresh snapshot.`,details:{reason:"offscreen_ref",ref:h,rect:g.rect,viewport:I}}}:{ok:!0,target:{ref:h,node:g,snapshotNodes:w,point:y}}}function na(e,t){let r=function(e,t){let r=nt(t.rect);if(!r)return null;let a=t,i=new Set;for(;!i.has(a.ref);){i.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=nt(e.rect);return!!t&&ni(t,r)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(r?.rect&&ne(r.rect))return r;let a=W(e,t);return a?.rect&&ne(a.rect)?!function(e,t,r){var a,i,n,o;let s,l,d,u=nt(e.rect),c=nt(t.rect);if(!u||!c)return!1;let f=function(e,t){let r=et(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>nt(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let i=a.filter(e=>E(e,r.x,r.y));return x(i.length>0?i:a)}(r,u);return!!f&&(a=c,i=f,s=(n=a,o=i,Math.max(0,Math.min(n.x+n.width,o.x+o.width)-Math.max(n.x,o.x))*Math.max(0,Math.min(n.y+n.height,o.y+o.height)-Math.max(n.y,o.y))),l=a.width*a.height,d=i.width*i.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!ni(u,c)}(t,a,e)?a:t:t}function ni(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 nn(e){let{device:t,node:r,flags:a,appBundleId:i,traceOutPath:n,surface:o,contextFromFlags:s}=e,l=R(r),d=ne(r.rect);if(!d)return l;try{let e=await w(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,i,n),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return ti({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:o,platform:t.platform}}),l}catch(e){return ti({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 no(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return N("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=eq(s);if(!d)return N("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return N("INVALID_ARGS","find accepts only one of --first or --last");let p=i.get(r);if(!p&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return N("SESSION_NOT_FOUND","No active session. Run open first.");let m=p?.device??await eR(t.flags??{});p||await e9(m);let h="role"!==l?d:void 0,g="click"===u||"focus"===u||"fill"===u||"type"===u,w=0,v=null,y=async()=>{let e=Date.now();if(v&&e-w<750&&!tt(p))return{nodes:v};let{snapshot:n}=await eB({device:m,session:p,flags:{...t.flags,snapshotInteractiveOnly:g,snapshotCompact:g},outPath:t.flags?.out,logPath:a,snapshotScope:h}),o=n.nodes;return w=e,v=o,p&&(p.snapshot=n,i.set(r,p)),{nodes:o,truncated:n.truncated,backend:n.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:p,device:m,command:o,locator:l,query:d};if("wait"===u)return ns(I,y,l,d,f);let{nodes:S}=await y(),A=ta(S,l,d,{requireRect:g});if(g&&A.matches.length>1)if(t.flags?.findFirst)A.matches=[A.matches[0]];else{if(!t.flags?.findLast){var b,_,x;let e;return b=A.matches,_=l,x=d,e=b.slice(0,8).map(e=>{let t=C(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),N("AMBIGUOUS_MATCH",`find matched ${b.length} elements for ${_} "${x}". Use a more specific locator or selector.`,{locator:_,query:x,matches:b.length,candidates:e})}A.matches=[A.matches[A.matches.length-1]]}let M=A.matches[0]??null;if(!M)return N("COMMAND_FAILED","find did not match any element");let k="click"===u||"focus"===u||"fill"===u||"type"===u?W(S,M)??M:M,D=`@${k.ref}`,P={node:M,resolvedNode:k,ref:D,nodes:S,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>nl(I),get_text:()=>nd(I,P),get_attrs:()=>nu(I,P),click:()=>nc(I,P),fill:()=>nf(I,P,c),focus:()=>np(I,P),type:()=>nm(I,P,c)}[u];return L?L():null}async function ns(e,t,r,a,i){let{req:n,sessionStore:o,session:s,command:l}=e,d=i??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(ta(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:n.positionals??[],flags:n.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 N("COMMAND_FAILED","find wait timed out")}async function nl(e){let{req:t,sessionStore:r,session:a,command:i}=e;return a&&r.recordAction(a,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function nd(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await nn({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eV(s,e,t,r)});return i&&a.recordAction(i,{command:n,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 nu(e,t){let{req:r,sessionStore:a,session:i,command:n}=e;return i&&a.recordAction(i,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function nc(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,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?et(t.resolvedNode.rect):null,f={ref:t.ref,locator:l,query:d};return c&&(f.x=c.x,f.y=c.y),n&&i.recordAction(n,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:f}}async function nf(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return N("INVALID_ARGS","find fill requires text");let d=await s({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&n.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function np(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?et(t.node.rect):null;if(!l)return N("COMMAND_FAILED","matched element has no bounds");let d=await w(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eV(s,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function nm(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return N("INVALID_ARGS","find type requires text");let d=t.node.rect?et(t.node.rect):null;if(!d)return N("COMMAND_FAILED","matched element has no bounds");await w(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eV(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await w(o,"type",[r],a.flags?.out,{...eV(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let nh=`
13
10
  import Foundation
14
11
  import AVFoundation
15
12
 
@@ -33,11 +30,11 @@ Task {
33
30
 
34
31
  semaphore.wait()
35
32
  exit(exitCode)
36
- `.trim();async function nE(e,t={}){let r,i=t.pollMs??150,n=t.attempts??12,o=0;for(let t=0;t<n;t+=1){let t=0;try{t=a.statSync(e).size}catch{t=0}if(t>0&&t===r){if((o+=1)>=2)return}else o=0;r=t,await new Promise(e=>setTimeout(e,i))}}async function nT(e){try{var t,r;let a,i=await tw("swift",["-",e],{stdin:nC,allowFailure:!0,timeoutMs:1e4});if(0===i.exitCode)return!0;if(t=i.stderr,r=i.stdout,a=`${t}
37
- ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return nU(e);return!1}catch(t){if(t instanceof tc&&"TOOL_MISSING"===t.code)return nU(e);throw t}}async function nF(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await nT(e))return;await new Promise(e=>setTimeout(e,r))}}function nU(e){try{let t=a.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=a.openSync(e,"r");try{let e=a.fstatSync(t).size,r=0,i=[];for(;r+8<=e&&i.length<16;){let e=Buffer.alloc(8);if(8>a.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(i.push(o),1===n){let e=Buffer.alloc(8);if(8>a.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return i}finally{a.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nG(e){let t=n.parse(e);return n.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nV(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nq(e){let t=n.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),n.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),n.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),n.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(a.existsSync(e))return e;throw new tc("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})}async function nj(e){let{videoPath:t,scriptPath:r,scriptArgs:i,commandDescription:o}=e;await nE(t),await nF(t);let s=a.mkdtempSync(n.join(c.tmpdir(),"agent-device-record-overlay-")),l=n.join(s,`input${n.extname(t)||".mp4"}`),d=n.join(s,n.basename(t)),u=n.join(s,"home"),f=n.join(s,"module-cache");a.copyFileSync(t,l),a.mkdirSync(u,{recursive:!0}),a.mkdirSync(f,{recursive:!0});try{await tw("xcrun",["swift",r,"--input",l,"--output",d,...i],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await nF(d),a.copyFileSync(d,t)}catch(a){let e=a instanceof tc?a:new tc("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new tc("COMMAND_FAILED",o,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{a.rmSync(s,{recursive:!0,force:!0})}}async function nB(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nj({videoPath:r,scriptPath:t??=nq("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function nH(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nj({videoPath:r,scriptPath:e??=nq("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}function nK(e){return e instanceof Error?e.message:String(e)}function nz(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function nW(e){let{recording:t,deps:r,trimStartMs:i,targetLabel:n}=e,o=function(e){var t,r,i;let n,o,{recording:s,trimStartMs:l}=e,d=(n=nG((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(i=t.trimStartMs??0)>0?nV(r.flatMap(e=>{let t=e.tMs-i,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):nV(r))},a.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:i});if(t.showTouches){let e=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(e)t.overlayWarning=e;else try{await r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,targetLabel:n})}catch(e){t.overlayWarning=`failed to overlay recording touches: ${nK(e)}`}}}async function nJ(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 nZ(e,t,r){for(let a=0;a<40;a+=1){if(!await nJ(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await nJ(e,t,r)}async function nY(e,t,r){let a,i=0;for(let n=0;n<20;n+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?n.stdout.trim():"";if(o.length>0&&o===a){if((i+=1)>=4)return}else i=0;a=o,await new Promise(e=>setTimeout(e,250))}}async function nX(e,t,r,a){for(let i=0;i<8;i+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?Number(n.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await nJ(e,t,a))break;if(i+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function nQ(e){let t,{deps:r,deviceId:i,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{a.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",i,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=nz(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(tv({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:i,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return a.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;tv({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:i,remotePath:n,outPath:o,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 n0(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function n1(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return tv({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 nJ(e,t,r))&&await nZ(e,t,r)}async function n2(e){var t;let r,{deps:a,device:i,recordingBase:n}=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",i.id,"shell",`screenrecord ${e} >/dev/null 2>&1 & echo $!`],{allowFailure:!0});if(0!==t.exitCode){o=`failed to start recording: ${nz(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 n0(a,i.id,e);continue}if(tv({level:"debug",phase:"record_start_android_started",data:{deviceId:i.id,remotePath:e,remotePid:r}}),await nX(a,i.id,e,r))return{platform:"android",remotePath:e,remotePid:r,...n,startedAt:Date.now()};o="failed to start recording: Android screenrecord did not begin producing frames",await n1(a,i.id,r),await n0(a,i.id,e)}return J("COMMAND_FAILED",o)}async function n5(e){let t,r,{deps:a,device:i,recording:n}=e;tv({level:"debug",phase:"record_stop_android_enter",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid}});let o=await a.runCmd("adb",["-s",i.id,"shell","kill","-2",n.remotePid],{allowFailure:!0});if(tv({level:"debug",phase:"record_stop_android_signal",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await nJ(a,i.id,n.remotePid)&&!await n1(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nz(o,"adb shell kill")}`):await nZ(a,i.id,n.remotePid)||await n1(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nY(a,i.id,n.remotePath);let e=await nQ({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),J("COMMAND_FAILED",e);await nW({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return J("COMMAND_FAILED",t);if(r)return J("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});tv({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:i.id,remotePath:n.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${nz(e,"adb shell rm")}`)}}function n4(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function n3(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function n8(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=n4(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},n3(t,i,r))}catch(e){tv({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:nK(e)}})}}async function n6(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=n3(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,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 g,w;if(!nK(a).toLowerCase().includes("recording already in progress"))return J("COMMAND_FAILED",`failed to start recording: ${nK(a)}`);tv({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:nK(a)}});let e=(g=o.id,w=i.name,n.toArray().find(e=>e.name!==w&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return J("COMMAND_FAILED",`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 J("COMMAND_FAILED",`failed to start recording: ${nK(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function n7(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await n.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,appBundleId:l},n3(t,i,r))}catch(e){return J("COMMAND_FAILED",`failed to start recording: ${nK(e)}`)}return{platform:"macos-runner",...s}}async function n9(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=n4(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},n3(t,i,r))}catch(e){tv({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nK(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of B)if(0===(l=await n.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 J("COMMAND_FAILED",`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);return d>0&&await n.trimRecordingStart({videoPath:o.outPath,trimStartMs:d}),await nW({recording:o,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function oe(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=n4(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},n3(t,i,r))}catch(e){tv({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nK(e)}})}return await nW({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function ot(e){for(let t=0;t<2;t+=1){try{if(a.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 or(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await n8({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",e1(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await ot(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:n4(i)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:i.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:f,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function oa(e){let t,{req:r,sessionName:i,sessionStore:o,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return J("INVALID_ARGS","recording already in progress");let c=r.flags?.fps;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return J("INVALID_ARGS","fps must be an integer between 1 and 120");if(!ti("record",l))return J("UNSUPPORTED_OPERATION","record is not supported on this device");let f=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,p=tC.expandHome(f,r.meta?.cwd),m={outPath:p,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(a.mkdirSync(n.dirname(p),{recursive:!0}),a.rmSync(p,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=n4(s);if(!e)return J("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await n6({req:r,activeSession:s,sessionStore:o,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:m,appBundleId:e})}else if("macos"===l.platform){let e=n4(s);if(!e)return J("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await n7({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:m,appBundleId:e})}else t="ios"===l.platform?await or({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:m,resolvedOut:p}):await n2({deps:u,device:l,recordingBase:m});return"ok"in t?t:(s.recording=t,o.set(i,s),o.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??f,showTouches:t.showTouches}})}async function oi(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await n5({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;return 0!==i.exitCode?J("COMMAND_FAILED",`failed to stop recording: ${nz(i,"simctl recordVideo")}`):(await nW({recording:a,deps:t,targetLabel:"iOS recording"}),null)}async function on(e){var t;let r,{req:a,activeSession:i,device:o,logPath:s,deps:l}=e;if(!i.recording)return J("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await n9({req:a,activeSession:i,device:o,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await oe({req:a,activeSession:i,device:o,logPath:s,deps:l,recording:d}):await oi({deps:l,device:o,recording:d});return c||(u?J("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:n.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nG(e.clientOutPath)}(t),fileName:n.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function oo(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:tw,runCmdBackground:tp,runIosRunnerCommand:eJ,waitForStableFile:nE,isPlayableVideo:nT,trimRecordingStart:nB,overlayRecordingTouches:nH},o=a.get(r),s=o?.device??await ei(t.flags??{});o||await eY(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return J("INVALID_ARGS","record requires start|stop");if("start"===d)return oa({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await on({req:t,activeSession:l,device:s,logPath:i,deps:n});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 os(e){let{req:t,sessionName:r,sessionStore:i,logPath:o}=e,s=t.command;if("record"===s)return oo({req:t,sessionName:r,sessionStore:i,logPath:o});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return J("INVALID_ARGS","trace requires start|stop");let o=i.get(r);if(!o)return J("SESSION_NOT_FOUND","No active session");if("start"===e){if(o.trace)return J("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??i.defaultTracePath(o),r=tC.expandHome(e);return a.mkdirSync(n.dirname(r),{recursive:!0}),a.appendFileSync(r,""),o.trace={outPath:r,startedAt:Date.now()},i.recordAction(o,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!o.trace)return J("INVALID_ARGS","no active trace");let l=o.trace.outPath;if(t.positionals?.[1]){let e=tC.expandHome(t.positionals[1]);a.mkdirSync(n.dirname(e),{recursive:!0}),a.existsSync(l)?a.renameSync(l,e):a.appendFileSync(e,""),l=e}return o.trace=void 0,i.recordAction(o,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function ol(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 od=new WeakMap;function ou(e){if(!e)return;let t=od.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)&&oc(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(oc);if(0===r.length)return;let a=Math.max(...r.map(e=>e.x+e.width)),i=Math.max(...r.map(e=>e.y+e.height));if(!(a<=0)&&!(i<=0))return{x:0,y:0,width:a,height:i}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return od.set(e,r),r}function oc(e){return!!e&&e.width>0&&e.height>0}let of={referenceWidth:1e3,referenceHeight:1e3};function op(e,t,r,a,i={},n=Date.now(),o=Date.now()){var s,l,d;let u,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=ow(p.effectiveDurationMs)??ow(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:ow(p.gestureStartUptimeMs),gestureEndUptimeMs:ow(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:ow(p.gestureStartUptimeMs),gestureEndUptimeMs:ow(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,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),w="ios"===e.device.platform&&void 0===ow(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=ov(ow(t.count),1)??1,r=!0===t.doubleTap,a=ov(ow(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,p)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return ol(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):ol(h),v=(l=e.snapshot,u=ow((d=p).referenceWidth),c=ow(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:ou(l)),y=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=oy(t,e);if(!i)return[];let{x:n,y:o}=i,s=ov(ow(t.count),1)??1,l=ov(ow(t.intervalMs),0)??0,d=!0===t.doubleTap,u=ov(ow(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(oh(t,n,o,u,a));continue}c.push(om(t,n,o,a)),d&&c.push(om(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=oy(t,e);if(!i)return[];let{x:n,y:o}=i;return[om(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=oy(t,e);if(!n)return[];let{x:o,y:s}=n;return[oh(r,o,s,oS(a,[ow(t.durationMs),ow(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=oI(t,e),o=og(t.contentDirection)??og(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=oS(a,[],250),f=ow(t.amount)??ow(e[1]),p=ow(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...i,durationMs:c,contentDirection:o,...void 0!==f?{amount:f}:{},...void 0!==p?{pixels:p}:{}}]}(t,r,a,i,n);case"swipe":return function(e,t,r,a,i){let n=oI(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=oS(a,[ow(t.effectiveDurationMs),ow(t.durationMs),ow(e[4])],250),c=ov(ow(t.count),1)??1,f=ov(ow(t.pauseMs),0)??0,p="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===p&&e%2==1,a=t?l:o,n=t?d:s,c=t?o:l,h=t?s:d,g=r+e*(u+f);if("back-swipe"===function(e,t,r,a,i){if(!i||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let n=.08*i.referenceWidth;return e<=n&&r>e||e>=i.referenceWidth-n&&r<e?"back-swipe":"swipe"}(a,n,c,h,i)){m.push({kind:"back-swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,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,i)});continue}m.push({kind:"swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u})}return m}(t,r,a,i,n);case"pinch":return function(e,t,r,a,i){let n=oy(t,e,1),o=ow(t.scale)??ow(e[0]);if(!n||void 0===o||o<=0)return[];let{x:s,y:l}=n;return[{kind:"pinch",tMs:r,x:s,y:l,...i,scale:o,durationMs:oS(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,v);0!==y.length&&(f.gestureEvents.push(...y),tv({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:y.length,tMs:w,gestureDurationMs:g,kinds:y.map(e=>e.kind)}}))}function om(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function oh(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function og(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 ow(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 ov(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function oy(e,t,r=0){let a=ow(e.x)??ow(t[r]),i=ow(e.y)??ow(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function oI(e,t){let r=ow(e.x1)??ow(t[0]),a=ow(e.y1)??ow(t[1]),i=ow(e.x2)??ow(t[2]),n=ow(e.y2)??ow(t[3]);if(void 0!==r&&void 0!==a&&void 0!==i&&void 0!==n)return{x1:r,y1:a,x2:i,y2:n}}function oS(e,t,r){return ov(e,1)??t.map(e=>ov(e,1)).find(e=>void 0!==e)??r}function oA(e){var t,r,a;let i,n,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,i="string"==typeof t?.ref?t.ref:void 0,n="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:i?n&&"primary"!==n?`Clicked ${n} @${i} (${r}, ${a})`:`Tapped @${i} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...X(c)}}async function ob(e){let{session:t,sessionStore:r,requestCommand:a,requestPositionals:i,flags:n,contextFromFlags:o,interactionCommand:s,interactionPositionals:l,outPath:d,afterDispatch:u,buildPayloads:c}=e,f=await o_({session:t,flags:n,contextFromFlags:o,command:s,positionals:l,outPath:d});await u?.(f.data);let{result:p,responseData:m=p}=await c(f.data);return function(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:o}),Z(a)&&tn(t,a),op(t,a,i,o,n??{},l,d),{ok:!0,data:s}}({session:t,sessionStore:r,command:a,positionals:i,flags:n,result:p,responseData:m,actionStartedAt:f.actionStartedAt,actionFinishedAt:f.actionFinishedAt})}async function o_(e){let{session:t,flags:r,contextFromFlags:a,command:i,positionals:n,outPath:o}=e,s=Date.now(),l={...a(r,t.appBundleId,t.trace?.outPath)},d=await I(t.device,i,n,o,l);return{data:d&&"object"==typeof d?d:void 0,actionStartedAt:s,actionFinishedAt:Date.now()}}async function oN(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await ew(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=ou(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=ou(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function ox(e){try{return await oN(e)}catch(t){tv({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function ok(e){return ou({nodes:e,createdAt:0})}function oM(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:J("UNSUPPORTED_OPERATION",`${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 oD(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r),d=t.command,u="click"===d?"click":"press";if(!l)return J("SESSION_NOT_FOUND","No active session. Run open first.");let c=oM(l,u);if(c)return c;if(!ti("press",l.device))return J("UNSUPPORTED_OPERATION","press is not supported on this device");let f=eP(t.flags),p=L(f);if("primary"!==f){let e=ea({commandLabel:u,platform:l.device.platform,button:f,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return J(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 ob({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[String(m.x),String(m.y)],flags:t.flags,contextFromFlags:i,interactionCommand:"press",interactionPositionals:[String(m.x),String(m.y)],outPath:t.flags?.out,afterDispatch:async()=>{await oP(l,"coordinate tap")},buildPayloads:async e=>{let r=await ox({session:l,flags:t.flags,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}),o=oA({data:e,fallbackX:m.x,fallbackY:m.y,referenceFrame:r,extra:p});return{result:o,responseData:o}}});let h="click",g=t.positionals?.[0]??"";if(g.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 nA({session:l,refInput:g,fallbackLabel:r,commandLabel:u,promoteToHittableAncestor:!0,invalidRefMessage:`${u} requires a ref like @e2`,missingBoundsMessage:`Ref ${g} not found or has no bounds`,invalidBoundsMessage:`Ref ${g} not found or has invalid bounds`,reqFlags:t.flags,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n,resolveRefTarget:o});if(!c.ok)return c;let{ref:f,node:m,snapshotNodes:w,point:v}=c.target,y=eF(m,w),I=E(m,l.device.platform,{action:h}),{x:S,y:A}=v;return ob({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"press",interactionPositionals:[String(S),String(A)],outPath:t.flags?.out,afterDispatch:async()=>{await oP(l,`@${f}`)},buildPayloads:e=>{let t=oA({data:e,fallbackX:S,fallbackY:A,referenceFrame:ok(w),extra:{ref:f,refLabel:y,selectorChain:I,...p}});return{result:t,responseData:t}}})}let w=(t.positionals??[]).join(" ").trim();if(!w)return J("INVALID_ARGS",`${u} requires @ref, selector expression, or x y coordinates`);let v=eb(w),y=await n(l,t.flags,a,i,{interactiveOnly:!0}),I=await tg("selector_resolve",()=>$(y.nodes,v,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:d});if(!I||!I.node.rect)return J("COMMAND_FAILED",j(v,I?.diagnostics??[],{unique:!0}));let S=nb(y.nodes,I.node),A=nI(S.rect);if(!A)return J("COMMAND_FAILED",`Selector ${I.selector.raw} resolved to invalid bounds`);let{x:b,y:_}=A,N=E(S,l.device.platform,{action:h}),x=eF(S,y.nodes);return ob({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"press",interactionPositionals:[String(b),String(_)],outPath:t.flags?.out,afterDispatch:async()=>{await oP(l,I.selector.raw)},buildPayloads:e=>{let t=oA({data:e,fallbackX:b,fallbackY:_,referenceFrame:ok(y.nodes),extra:{selector:I.selector.raw,selectorChain:N,refLabel:x,...p}});return{result:t,responseData:t}}})}async function oP(e,t){if("android"!==e.device.platform||!e.appBundleId)return;let r=await ev(e.device),a=r.package?.trim();if(a&&a!==e.appBundleId){var i;if("com.android.settings"===(i=a)||"com.android.systemui"===i||"com.google.android.permissioncontroller"===i||i.includes("launcher"))throw new tc("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 oL(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r);if(l){let e=oM(l,"fill");if(e)return e}if(l&&!ti("fill",l.device))return J("UNSUPPORTED_OPERATION","fill is not supported on this device");if(t.positionals?.[0]?.startsWith("@")){if(!l)return J("SESSION_NOT_FOUND","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 J("INVALID_ARGS","fill requires text after ref");let u=await nA({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:i,captureSnapshotForSession:n,resolveRefTarget:o});if(!u.ok)return u;let{ref:c,node:f,snapshotNodes:p,point:m}=u.target,h=f.type??"",g=h&&!k(h,l.device.platform)?`fill target ${t.positionals[0]} resolved to "${h}", attempting fill anyway.`:void 0,w=eF(f,p),v=E(f,l.device.platform,{action:"fill"}),{x:y,y:I}=m;return ob({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"fill",interactionPositionals:[String(y),String(I),d],outPath:t.flags?.out,buildPayloads:e=>{let t=oA({data:e,fallbackX:y,fallbackY:I,referenceFrame:ok(p),extra:{ref:c,refLabel:w,selectorChain:v,text:d}}),r={...e??{ref:c,x:y,y:I}};return g&&(t.warning=g,r.warning=g),{result:t,responseData:r}}})}if(!l)return J("SESSION_NOT_FOUND","No active session. Run open first.");let d=q(t.positionals??[],{preferTrailingValue:!0});if(d){if(0===d.rest.length)return J("INVALID_ARGS","fill requires text after selector");let e=d.rest.join(" ").trim();if(!e)return J("INVALID_ARGS","fill requires text after selector");let r=eb(d.selectorExpression),o=await n(l,t.flags,a,i,{interactiveOnly:!0}),s=await tg("selector_resolve",()=>$(o.nodes,r,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:t.command});if(!s||!s.node.rect)return J("COMMAND_FAILED",j(r,s?.diagnostics??[],{unique:!0}));let u=s.node,c=s.node.rect,f=u.type??"",p=f&&!k(f,l.device.platform)?`fill target ${s.selector.raw} resolved to "${f}", attempting fill anyway.`:void 0,{x:m,y:h}=N(c),g=E(u,l.device.platform,{action:"fill"});return ob({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"fill",interactionPositionals:[String(m),String(h),e],outPath:t.flags?.out,buildPayloads:t=>{let r=oA({data:t,fallbackX:m,fallbackY:h,referenceFrame:ok(o.nodes),extra:{text:e,selector:s.selector.raw,selectorChain:g,refLabel:eF(u,o.nodes)}});return p&&(r.warning=p),{result:r,responseData:r}}})}return J("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}async function oR(e){switch(e.req.command){case"press":case"click":return await oD(e);case"fill":return await oL(e);default:return null}}let oO=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function o$(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,a]of oO)void 0!==e[r]&&t.push(a);return t}(t);return 0===r.length?null:J("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function oC(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},o=a(n,e.appBundleId,e.trace?.outPath),{snapshot:s}=await eA({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}async function oE(e){let{command:t,selectorExpression:r,session:a,flags:i,sessionStore:n,contextFromFlags:o,interactiveOnly:s,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}=e,c=eb(r),f=await oC(a,i,n,o,{interactiveOnly:s}),p=await tg("selector_resolve",()=>$(f.nodes,c,{platform:a.device.platform,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}),{command:t});return p&&(!l||p.node.rect)?{ok:!0,chain:c,snapshot:f,resolved:p}:{ok:!1,error:{code:"COMMAND_FAILED",message:j(c,p?.diagnostics??[],{unique:d})}}}async function oT(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i}=e,n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return J("INVALID_ARGS","get only supports text or attrs");let o=a.get(r);if(!o)return J("SESSION_NOT_FOUND","No active session. Run open first.");if(!ti("get",o.device))return J("UNSUPPORTED_OPERATION","get is not supported on this device");let s=t.positionals?.[1]??"";if(s.startsWith("@")){let e=o$("get",t.flags);if(e)return e;let r=ny({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;let{ref:l,node:d}=r.target,u=E(d,o.device.platform,{action:"get"});if("attrs"===n)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 nN({device:o.device,node:d,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:i});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{ref:l,text:c,refLabel:oF(c),selectorChain:u}}),{ok:!0,data:{ref:l,text:c,node:d}}}let l=t.positionals.slice(1).join(" ").trim();if(!l)return J("INVALID_ARGS","get requires @ref or selector expression");let d=await oE({command:t.command,selectorExpression:l,session:o,flags:t.flags,sessionStore:a,contextFromFlags:i,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:"text"===n});if(!d.ok)return d;let{resolved:u}=d,c=u.node,f=E(c,o.device.platform,{action:"get"});if("attrs"===n)return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{selector:u.selector.raw,selectorChain:f}}),{ok:!0,data:{selector:u.selector.raw,node:c}};let p=await nN({device:o.device,node:c,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:i});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{text:p,refLabel:oF(p),selector:u.selector.raw,selectorChain:f}}),{ok:!0,data:{selector:u.selector.raw,text:p,node:c}}}function oF(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function oU(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 oG(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i}=e,n=(t.positionals?.[0]??"").toLowerCase();if(!["visible","hidden","exists","editable","selected","text"].includes(n))return J("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let o=a.get(r);if(!o)return J("SESSION_NOT_FOUND","No active session. Run open first.");if(!ti("is",o.device))return J("UNSUPPORTED_OPERATION","is is not supported on this device");let{split:s}=e$(t.positionals);if(!s)return J("INVALID_ARGS","is requires a selector expression");let l=s.rest.join(" ").trim();if("text"===n&&!l)return J("INVALID_ARGS","is text requires expected text value");if("text"!==n&&s.rest.length>0)return J("INVALID_ARGS",`is ${n} does not accept trailing values`);let d=eb(s.selectorExpression);if("exists"===n){let e=ef((await oC(o,t.flags,a,i,{interactiveOnly:!1})).nodes,d,{platform:o.device.platform});return e?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:n,selector:e.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,matches:e.matches}}),{ok:!0,data:{predicate:n,pass:!0,selector:e.selector.raw,matches:e.matches}}):J("COMMAND_FAILED",j(d,[],{unique:!1}))}let u=await oE({command:"is",selectorExpression:s.selectorExpression,session:o,flags:t.flags,sessionStore:a,contextFromFlags:i,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!u.ok)return u;let{resolved:c}=u,f=function(e){let{predicate:t,node:r,nodes:a,expectedText:i,platform:n}=e,o=eI(r),s=ey(r,n),l=!0===r.selected,d="text"===t?eS(r):function(e,t){if(!0===e.hittable)return!0;if(oU(e.rect))return M(e,t);if(e.rect)return!1;let r=function(e,t){let r=new Map(t.map(e=>[e.index,e])),a=e,i=new Set;for(;"number"==typeof a.parentIndex&&!i.has(a.index);){i.add(a.index);let e=r.get(a.parentIndex);if(!e)break;if(function(e){let t=C(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||oU(e.rect))}(e))return e;a=e}return null}(e,t);return!!r&&(!0===r.hittable||!!oU(r.rect)&&M(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===(i??"")}let c="text"===t?`expected="${i??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:n,node:c.node,nodes:u.snapshot.nodes,expectedText:l,platform:o.device.platform});return f.pass?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:n,selector:c.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,text:"text"===n?f.actualText:void 0}}),{ok:!0,data:{predicate:n,pass:!0,selector:c.selector.raw}}):J("COMMAND_FAILED",`is ${n} failed for selector ${c.selector.raw}: ${f.details}`)}function oV(e,t){var r,a;let i=Math.max(1,t.height),n=Math.max(1,t.width),o=t.y,s=t.y+i,l=t.x,d=t.x+n,u=s-.25*i,c=Math.max(8,.1*n),f=e.y+e.height/2,p=e.x+e.width/2;if(f>=o+.25*i&&f<=u)return null;let m=Math.round((r=p,a=l+c,Math.min(d-c,Math.max(a,r)))),h=Math.round(o+.86*i),g=Math.round(o+.14*i);return f>u?{x:m,startY:h,endY:g,direction:"down"}:{x:m,startY:g,endY:h,direction:"up"}}async function oq(e){var t;let r,a,i,{req:n,sessionName:o,sessionStore:s,contextFromFlags:l}=e,d=s.get(o);if(!d)return J("SESSION_NOT_FOUND","No active session. Run open first.");if(!ti("scrollintoview",d.device))return J("UNSUPPORTED_OPERATION","scrollintoview is not supported on this device");let u=n.positionals?.[0]??"";if(!u.startsWith("@"))return null;let c=o$("scrollintoview",n.flags);if(c)return c;let f=n.positionals&&n.positionals.length>1?n.positionals.slice(1).join(" ").trim():"",p=(r=ny({session:d,refInput:t=u,fallbackLabel:f,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${t} not found or has no bounds`})).ok?oj(t,0,r.target):"COMMAND_FAILED"!==r.error.code?r:oB(t,0,{message:r.error.message});if(!p.ok)return p;let{ref:m}=p.state,{currentRef:h,node:g,snapshotNodes:w,viewportRect:v}=p.state,y=eF(g,w),S=E(g,d.device.platform,{action:"get"}),A=f||y||g.label||"";if(!oV(g.rect,v)){let e=oH({ref:m,currentRef:h,attempts:0,alreadyVisible:!0});return s.recordAction(d,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:{refLabel:y,selectorChain:S,...e}}),{ok:!0,data:e}}let b=n.flags?.maxScrolls??48,_=0,N=0,x=eO(g.rect,v);for(;_<b;){let e=oV(g.rect,v);if(!e)break;a=e.direction,i=await I(d.device,"swipe",[String(e.x),String(e.startY),String(e.x),String(e.endY),"16"],n.flags?.out,{...l(n.flags,d.appBundleId,d.trace?.outPath),count:1,pauseMs:0,pattern:"one-way"}),_+=1,await oC(d,n.flags,s,l,{interactiveOnly:!0});let t=function(e){let{session:t,targetInput:r,fallbackLabel:a,attempts:i,ref:n,selectorChain:o,platform:s}=e;if(t.snapshot){let e=function(e,t,r,a){for(let r of t){let t=$(e,eb(r),{platform:a,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(t?.node.rect)return t.node}return r?e7(e,r):null}(t.snapshot.nodes,o,a,s);if(e)return oj(r,i,{ref:n,node:e,snapshotNodes:t.snapshot.nodes},{currentRef:e.ref})}let l=ny({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${r} not found or has no bounds`});return l.ok?oj(r,i,l.target,{ref:n,currentRef:l.target.node.ref,missingBoundsMessage:`scrollintoview lost bounds for ${r} after ${i} scroll${1===i?"":"s"}`}):"COMMAND_FAILED"!==l.error.code?l:oB(r,i,{message:`scrollintoview lost track of ${r} after ${i} scroll${1===i?"":"s"}`,ref:n})}({session:d,targetInput:u,fallbackLabel:A,attempts:_,ref:m,selectorChain:S,platform:d.device.platform});if(!t.ok)return t;({currentRef:h,node:g,snapshotNodes:w,viewportRect:v}=t.state);let r=eO(g.rect,v);if(0===r)break;if(r>=x){if((N+=1)>=2)return oB(u,_,{message:`scrollintoview made no progress toward ${u} after ${_} scroll${1===_?"":"s"}`,ref:m,stalled:!0})}else N=0;x=r}if(eO(g.rect,v)>0)return oB(u,_,{message:`scrollintoview reached --max-scrolls=${b} before ${u} entered view`,ref:m,maxScrolls:b});let k=oH({data:i,ref:m,currentRef:h,attempts:_,direction:a});return s.recordAction(d,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:{refLabel:y,selectorChain:S,...k}}),{ok:!0,data:k}}function oj(e,t,r,a={}){let{ref:i,currentRef:n,missingBoundsMessage:o}=a,s=r.node;if(!s.rect)return oB(e,t,{message:o??`Ref ${e} not found or has no bounds`,ref:i??r.ref});let l=eB(r.snapshotNodes,s.rect);return l?{ok:!0,state:{ref:i??r.ref,currentRef:n??r.node.ref,node:s,snapshotNodes:r.snapshotNodes,viewportRect:l}}:J("COMMAND_FAILED",`scrollintoview could not infer viewport for ${e}`)}function oB(e,t,r={}){let{message:a,...i}=r;return J("COMMAND_FAILED","string"==typeof a?a:`scrollintoview could not find ${e}`,{reason:"not_found",attempts:t,...i})}function oH(e){let{data:t,ref:r,currentRef:a,attempts:i,alreadyVisible:n,direction:o}=e;return{...t??{},ref:r,currentRef:a,attempts:i,...n?{alreadyVisible:n}:{},...o?{direction:o}:{},...X(`Scrolled into view: @${r}`)}}async function oK(e){let t=await oR({...e,captureSnapshotForSession:oC,resolveRefTarget:ny,refSnapshotFlagGuardResponse:o$});if(t)return t;switch(e.req.command){case"get":return await oT(e);case"is":return await oG(e);case"scrollintoview":return await oq(e);default:return null}}function oz(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 oW(e){let{req:t,leaseRegistry:r}=e,a=oz(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 oJ(e,t){if(!t)return[];let r=[],a=e.device,i=w(t.platform);if(i&&!e9(a.platform,i)&&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(),i=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==i)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=eo(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oZ(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 oY=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"],oX=/\bis(?:n't| not)\s+responding\b/i,oQ=/^close app$/i;async function o0(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await o1(t),r=function(e){if(o3(e))return e.find(e=>{let t=o4(e);return t.length>0&&oQ.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=N(r.rect),n=await tw("adb",eT(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return tv({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),"failed";if(!await o2(t))return tv({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eL(t.device,t.appBundleId),!await o5(t,t.appBundleId)))return tv({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return tv({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:i}}),"recovered"}catch(e){return tv({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 o1(e){return x(et((await eN(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function o2(e){for(let t=0;t<12;t+=1){if(!o3(await o1(e)))return!0;await o8(500)}return!o3(await o1(e))}async function o5(e,t){for(let r=0;r<12;r+=1){if((await ev(e.device)).package===t)return!0;await o8(500)}return(await ev(e.device)).package===t}function o4(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 o3(e){return e.some(e=>{let t=o4(e);return t.length>0&&oX.test(t)})}function o8(e){return new Promise(t=>setTimeout(t,e))}let o6=[255,59,48,255],o7=[255,214,10,255],o9=[0,0,0,255],se={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 st(e){let t=G(await i.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)sa(r)&&sl(r.rect)&&(!t||sd(r.rect)>sd(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,i=-1/0;for(let n of e)n.rect&&sl(n.rect)&&(t=Math.min(t,n.rect.x),r=Math.min(r,n.rect.y),a=Math.max(a,n.rect.x+n.rect.width),i=Math.max(i,n.rect.y+n.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||i<=r?null:{x:t,y:r,width:a-t,height:i-r}}(e.filter(e=>{var t;return sl(e.rect)&&!("image"===C((t=e).type??"")&&!si(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(sn)||so(e.identifier);return sr(e)?t:t&&function(e){let t=C(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 sr(e)&&!sa(e)}(t)&&sl(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(sr(t)&&!sa(t)&&sl(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&sl(r.rect))return r;if(t.hittable&&sl(t.rect)&&!sa(t))return t;let a=e3(e,t);return a?.rect&&sl(a.rect)&&!sa(a)?a:null}(e.nodes,a);if(!o?.rect||!sl(o.rect))continue;let s=function(e,t,r){let a=ss(e);if(e.ref!==t.ref&&a)return a;let i=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 i=ss(a);if(!i)continue;let n=function(e){let t=0;return C(e.type??"").includes("text")&&(t+=2),sn(e.label)&&(t+=2),sn(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(ss(t)??eF(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),sr(t)&&(a+=3),sr(e)&&(a+=2),r&&(a+=2),so(t.identifier)&&(a+=1),si(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return sf({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,a);let i=r/e.width,n=a/e.height;return sf({x:Math.round((t.x-e.x)*i),y:Math.round((t.y-e.y)*n),width:Math.max(1,Math.round(t.width*i)),height:Math.max(1,Math.round(t.height*n))},r,a)}(i,o.rect,t,r);if(!sl(d))continue;let u=n.get(o.ref);(!u||l>u.score)&&n.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)=>sd(e.overlayRect)-sd(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(su(e.overlayRect,r.overlayRect)||su(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}sd(r.overlayRect)<sd(t[e].overlayRect)&&(t[e]=r)}return t})([...n.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:sc(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:sc(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:N(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)sm(e,t.x,t.x+t.width-1,t.y+a,r),sm(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),sh(e,t.x+a,t.y,t.y+t.height-1,r),sh(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(n=e).overlayRect,o6),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=sp(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:sp(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)sg(e,t+o,r+n,i)})(e,i,o,a,o7),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=se[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]&&sg(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,o9)}(a,n.overlayRect,n.ref)}return await i.writeFile(e.screenshotPath,m.sync.write(t)),r}function sr(e){let t=[e.type,e.role,e.subrole].map(e=>C(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 sa(e){let t=[e.type,e.role,e.subrole].map(e=>C(e??"")).join(" ");return t.includes("application")||t.includes("window")}function si(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function sn(e){var t;let r;return!!si(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function so(e){var t;return"string"==typeof e&&!!sn(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function ss(e){let t=[e.label,e.value].find(sn);return t?t.trim():so(e.identifier)?e.identifier.trim():void 0}function sl(e){return!!(e&&e.width>0&&e.height>0)}function sd(e){return e.width*e.height}function su(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 sc(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function sf(e,t,r){let a=sp(e.x,0,Math.max(0,t-1)),i=sp(e.y,0,Math.max(0,r-1)),n=Math.max(1,t-a),o=Math.max(1,r-i);return{x:a,y:i,width:sp(e.width,1,n),height:sp(e.height,1,o)}}function sp(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function sm(e,t,r,a,i){for(let n=t;n<=r;n+=1)sg(e,n,a,i)}function sh(e,t,r,a,i){for(let n=r;n<=a;n+=1)sg(e,t,n,i)}function sg(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let i=(e.width*r+t)*4;e.data[i]=a[0],e.data[i+1]=a[1],e.data[i+2]=a[2],e.data[i+3]=a[3]}let sw=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),sv=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),sy=new Set(sv),sI=new Map;function sS(e,t,r,a){let i=tm().requestId;return{...em(e,t,r,a,i),requestId:i}}async function sA(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||r8(e.flags))try{let t=await ei(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function sb(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await oW({req:t,leaseRegistry:n});if(l)return l;let d=await nv({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await R({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await os({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await nx({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await oK({req:t,sessionName:r,sessionStore:i,contextFromFlags:s});return p||null}async function s_(e){var t;let r,a,i,n,o,s,l,{req:d,session:u,logPath:c,sessionStore:f}=e,p=d.command;if(!ti(p,u.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${p} is not supported on this device`}};if("android"===u.device.platform&&u.recording&&"record"!==p&&"failed"===await o0({session:u}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:m,resolvedOut:h,recordedPositionals:g,recordedFlags:w}=(r=(t=d).command,a=t.positionals??[],i=t.flags?.out,n="screenshot"===r&&a[0]?[tC.expandHome(a[0],t.meta?.cwd),...a.slice(1)]:a,o="screenshot"===r&&i?tC.expandHome(i,t.meta?.cwd):i,s="screenshot"===r?n:a,l="screenshot"===r&&o?{...t.flags??{},out:o}:t.flags??{},{resolvedPositionals:n,resolvedOut:o,recordedPositionals:s,recordedFlags:l}),v=Date.now(),y={...sS(c,d.flags,u.appBundleId,u.trace?.outPath),surface:u.surface},S=await I(u.device,p,m,h,{...y});return"screenshot"===p&&d.flags?.overlayRefs&&"string"==typeof S?.path&&await sN(u,S,c),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=ou(e.snapshot),n={...a??{}},o=og(n.direction)??og(r[0]);if(!o)return a;let s=ow(n.amount)??ow(r[1]),l=ow(n.pixels),d=oI(n,[]),u=ow(n.referenceWidth),c=ow(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??of;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...n,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:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=U({direction:o,amount:s,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,s);op(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:u,sessionStore:f,command:p,resolvedPositionals:m,recordedPositionals:g,recordedFlags:w,data:S,actionStartedAt:v,actionFinishedAt:Date.now(),flags:d.flags??{}}),Z(p)&&tn(u,p),{ok:!0,data:S??{}}}async function sN(e,t,r){let a=eD(await eR({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await st({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function sx(e){a.existsSync(e)&&a.unlinkSync(e)}function sk(e){if(!a.existsSync(e))return null;try{let t=JSON.parse(a.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function sM(e){let t=sk(e);if(!t||t.pid===process.pid)try{a.existsSync(e)&&a.unlinkSync(e)}catch{}}function sD(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:sP,infoPath:sL,lockPath:sR,logPath:sO,sessionsDir:s$}=tt(process.env.AGENT_DEVICE_STATE_DIR),sC=to(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var sE=s$;if(a.existsSync(sE))for(let e of a.readdirSync(sE,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=n.join(sE,e.name,tT);if(a.existsSync(t))try{let e=tF(a.readFileSync(t,"utf8"));if(e&&function(e){let t,r=te(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{tG(t)}}let sT=new tC(s$),sF=new rK({maxActiveSimulatorLeases:sD(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:sD(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:sD(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:sD(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),sU=eX(),sG=r.randomBytes(24).toString("hex"),sV=te(process.pid)??void 0,sq=eg(),sj=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:o}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await tf({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:tu(new tc("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=W(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=e_(r);if(r&&!a)throw new tc("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new tc("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let i=e.session||"default";return i.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${i}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);tv({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let l=r.command,d=oz(r);sv.has(l)||r.meta?.sessionIsolation!=="tenant"||i.assertLeaseAdmission({tenantId:d.tenantId,runId:d.runId,leaseId:d.leaseId,backend:d.leaseBackend});let u=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,a),c=sy.has(l)?null:await sA(r,u,a),f=async()=>{let e=a.get(u);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=eq(e.device.id);if(!t.runnerSessionId){r?.alive&&(t.runnerSessionId=r.sessionId);return}if(!r?.alive){t.invalidatedReason??="iOS runner session exited during recording";return}r.sessionId!==t.runnerSessionId&&(t.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(u,e));let d=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?oJ(t,a):function(e,t,r){var a,i;let n=[],o=w(t);if(void 0!==e.platform&&o&&(a=w(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!g(i):"apple"!==i||!g(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of oY){let r=e[t];"string"==typeof r&&r.trim().length>0&&n.push({key:t,value:r})}return n}(a,e.meta?.lockPlatform,e.command);if(0===i.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,i),a.platform=t.device.platform):function(e,t){for(let t of oY)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new tc("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oZ).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=tm();if(!t.ok){tv({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=th({force:!0})??void 0;return{ok:!1,error:tu(new tc(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 tv({level:"info",phase:"request_success"}),th(),{ok:!0,data:function(e,t,r){var a,i;let o;if(!t)return t;let s=(a=e,i=t,o=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||o.some(e=>e?.field==="path")||"string"!=typeof i.path||o.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:n.basename(a.meta?.clientArtifactPaths?.path??i.path)}),o.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.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)}})(d,e,o);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||sw.has(l)||function(e,t){let r=oJ(e,t);if(0!==r.length){var a;let t,i,n;throw new tc("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oZ).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await sb({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...sS(t,e,r,i),surface:a.get(u)?.surface})});if(f)return c(f);let p=a.get(u);if(!p)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await s_({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await er(sI,c,f)}catch(r){tv({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=tm(),t=th({force:!0})??void 0;return{ok:!1,error:tu(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:sO,token:sG,sessionStore:sT,leaseRegistry:sF,trackDownloadableArtifact:function(e){let t=r.randomUUID(),a=setTimeout(()=>{rg(t)},9e5);return a.unref(),rh.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:a}),t}});!async function(){let e,t;if(!function(e,t,r){a.existsSync(e)||a.mkdirSync(e,{recursive:!0});let i=JSON.stringify(r,null,2),n=()=>{try{return a.writeFileSync(t,i,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=sk(t);if(o?.pid&&o.pid!==process.pid&&A(o.pid,o.processStartTime))return!1;try{a.unlinkSync(t)}catch{}return n()}(sP,sR,{pid:process.pid,version:sU,startedAt:Date.now(),processStartTime:sV})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var i;let n;if("socket"===sC||"dual"===sC){let t=h.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))eK(e);tv({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await eV(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){tv({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",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eE(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),z(o),eC(o))throw K();i=await sj(e)}catch(e){i={ok:!1,error:tu(e)}}finally{r-=1,o&&(a.delete(o),e0(o))}e.destroyed||e.write(`${JSON.stringify(i)}
38
- `),n=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 tc("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===sC||"dual"===sC){let e=await rU({handleRequest:sj,token:sG});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 tc("COMMAND_FAILED","Failed to bind HTTP server"))})})}i={socketPort:e,httpPort:t,token:sG,version:sU,codeSignature:sq,processStartTime:sV},a.existsSync(sP)||a.mkdirSync(sP,{recursive:!0}),a.writeFileSync(sO,""),n=i.socketPort&&i.httpPort?"dual":i.httpPort?"http":"socket",a.writeFileSync(sL,JSON.stringify({port:i.socketPort,httpPort:i.httpPort,transport:n,token:i.token,pid:process.pid,version:i.version,codeSignature:i.codeSignature,processStartTime:i.processStartTime,stateDir:sP},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
33
+ `.trim();async function ng(e,t={}){let r,i=t.pollMs??150,n=t.attempts??12,o=0;for(let t=0;t<n;t+=1){let t=0;try{t=a.statSync(e).size}catch{t=0}if(t>0&&t===r){if((o+=1)>=2)return}else o=0;r=t,await new Promise(e=>setTimeout(e,i))}}async function nw(e){try{var t,r;let a,i=await tw("swift",["-",e],{stdin:nh,allowFailure:!0,timeoutMs:1e4});if(0===i.exitCode)return!0;if(t=i.stderr,r=i.stdout,a=`${t}
34
+ ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return ny(e);return!1}catch(t){if(t instanceof tI&&"TOOL_MISSING"===t.code)return ny(e);throw t}}async function nv(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await nw(e))return;await new Promise(e=>setTimeout(e,r))}}function ny(e){try{let t=a.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=a.openSync(e,"r");try{let e=a.fstatSync(t).size,r=0,i=[];for(;r+8<=e&&i.length<16;){let e=Buffer.alloc(8);if(8>a.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(i.push(o),1===n){let e=Buffer.alloc(8);if(8>a.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return i}finally{a.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nI(e){let t=n.parse(e);return n.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nS(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nA(e){let t=n.dirname(l(import.meta.url)),r=[l(new URL(`./${e}`,import.meta.url)),n.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),n.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),n.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(a.existsSync(e))return e;throw new tI("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})}async function nb(e){let{videoPath:t,scriptPath:r,scriptArgs:i,commandDescription:o}=e;await ng(t),await nv(t);let s=a.mkdtempSync(n.join(u.tmpdir(),"agent-device-record-overlay-")),l=n.join(s,`input${n.extname(t)||".mp4"}`),d=n.join(s,n.basename(t)),c=n.join(s,"home"),f=n.join(s,"module-cache");a.copyFileSync(t,l),a.mkdirSync(c,{recursive:!0}),a.mkdirSync(f,{recursive:!0});try{await tw("xcrun",["swift",r,"--input",l,"--output",d,...i],{timeoutMs:12e4,env:{...process.env,HOME:c,CLANG_MODULE_CACHE_PATH:f}}),await nv(d),a.copyFileSync(d,t)}catch(a){let e=a instanceof tI?a:new tI("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new tI("COMMAND_FAILED",o,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{a.rmSync(s,{recursive:!0,force:!0})}}async function n_(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nb({videoPath:r,scriptPath:t??=nA("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function nN(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nb({videoPath:r,scriptPath:e??=nA("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}function nx(e){return e instanceof Error?e.message:String(e)}function nM(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function nk(e){let{recording:t,deps:r,trimStartMs:i,targetLabel:n}=e,o=function(e){var t,r,i;let n,o,{recording:s,trimStartMs:l}=e,d=(n=nI((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(i=t.trimStartMs??0)>0?nS(r.flatMap(e=>{let t=e.tMs-i,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):nS(r))},a.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:i});if(t.showTouches){let e=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(e)t.overlayWarning=e;else try{await r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,targetLabel:n})}catch(e){t.overlayWarning=`failed to overlay recording touches: ${nx(e)}`}}}async function nD(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 nP(e,t,r){for(let a=0;a<40;a+=1){if(!await nD(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await nD(e,t,r)}async function nL(e,t,r){let a,i=0;for(let n=0;n<20;n+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?n.stdout.trim():"";if(o.length>0&&o===a){if((i+=1)>=4)return}else i=0;a=o,await new Promise(e=>setTimeout(e,250))}}async function nR(e,t,r,a){for(let i=0;i<8;i+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?Number(n.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await nD(e,t,a))break;if(i+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function nO(e){let t,{deps:r,deviceId:i,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{a.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",i,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=nM(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(ti({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:i,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return a.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;ti({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:i,remotePath:n,outPath:o,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 nE(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function nC(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return ti({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 nD(e,t,r))&&await nP(e,t,r)}async function n$(e){var t;let r,{deps:a,device:i,recordingBase:n}=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",i.id,"shell",`screenrecord ${e} >/dev/null 2>&1 & echo $!`],{allowFailure:!0});if(0!==t.exitCode){o=`failed to start recording: ${nM(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 nE(a,i.id,e);continue}if(ti({level:"debug",phase:"record_start_android_started",data:{deviceId:i.id,remotePath:e,remotePid:r}}),await nR(a,i.id,e,r))return{platform:"android",remotePath:e,remotePid:r,...n,startedAt:Date.now()};o="failed to start recording: Android screenrecord did not begin producing frames",await nC(a,i.id,r),await nE(a,i.id,e)}return N("COMMAND_FAILED",o)}async function nT(e){let t,r,{deps:a,device:i,recording:n}=e;ti({level:"debug",phase:"record_stop_android_enter",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid}});let o=await a.runCmd("adb",["-s",i.id,"shell","kill","-2",n.remotePid],{allowFailure:!0});if(ti({level:"debug",phase:"record_stop_android_signal",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await nD(a,i.id,n.remotePid)&&!await nC(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nM(o,"adb shell kill")}`):await nP(a,i.id,n.remotePid)||await nC(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nL(a,i.id,n.remotePath);let e=await nO({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),N("COMMAND_FAILED",e);await nk({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return N("COMMAND_FAILED",t);if(r)return N("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});ti({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:i.id,remotePath:n.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${nM(e,"adb shell rm")}`)}}function nF(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nU(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nG(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nF(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nU(t,i,r))}catch(e){ti({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:nx(e)}})}}async function nV(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=nU(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,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 g,w;if(!nx(a).toLowerCase().includes("recording already in progress"))return N("COMMAND_FAILED",`failed to start recording: ${nx(a)}`);ti({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:nx(a)}});let e=(g=o.id,w=i.name,n.toArray().find(e=>e.name!==w&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return N("COMMAND_FAILED",`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 N("COMMAND_FAILED",`failed to start recording: ${nx(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function nq(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await n.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,appBundleId:l},nU(t,i,r))}catch(e){return N("COMMAND_FAILED",`failed to start recording: ${nx(e)}`)}return{platform:"macos-runner",...s}}async function nj(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nF(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nU(t,i,r))}catch(e){ti({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nx(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of ef)if(0===(l=await n.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 N("COMMAND_FAILED",`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);return d>0&&await n.trimRecordingStart({videoPath:o.outPath,trimStartMs:d}),await nk({recording:o,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function nB(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nF(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nU(t,i,r))}catch(e){ti({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nx(e)}})}return await nk({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nH(e){for(let t=0;t<2;t+=1){try{if(a.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 nK(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await nG({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",tr(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await nH(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nF(i)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:i.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:f,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function nz(e){let t,{req:r,sessionName:i,sessionStore:o,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return N("INVALID_ARGS","recording already in progress");let c=r.flags?.fps;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return N("INVALID_ARGS","fps must be an integer between 1 and 120");if(!tl("record",l))return N("UNSUPPORTED_OPERATION","record is not supported on this device");let f=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,p=tG.expandHome(f,r.meta?.cwd),m={outPath:p,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(a.mkdirSync(n.dirname(p),{recursive:!0}),a.rmSync(p,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nF(s);if(!e)return N("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nV({req:r,activeSession:s,sessionStore:o,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:m,appBundleId:e})}else if("macos"===l.platform){let e=nF(s);if(!e)return N("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nq({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:m,appBundleId:e})}else t="ios"===l.platform?await nK({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:m,resolvedOut:p}):await n$({deps:u,device:l,recordingBase:m});return"ok"in t?t:(s.recording=t,o.set(i,s),o.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??f,showTouches:t.showTouches}})}async function nW(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nT({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;return 0!==i.exitCode?N("COMMAND_FAILED",`failed to stop recording: ${nM(i,"simctl recordVideo")}`):(await nk({recording:a,deps:t,targetLabel:"iOS recording"}),null)}async function nJ(e){var t;let r,{req:a,activeSession:i,device:o,logPath:s,deps:l}=e;if(!i.recording)return N("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await nj({req:a,activeSession:i,device:o,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await nB({req:a,activeSession:i,device:o,logPath:s,deps:l,recording:d}):await nW({deps:l,device:o,recording:d});return c||(u?N("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:n.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nI(e.clientOutPath)}(t),fileName:n.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nZ(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:tw,runCmdBackground:tg,runIosRunnerCommand:e8,waitForStableFile:ng,isPlayableVideo:nw,trimRecordingStart:n_,overlayRecordingTouches:nN},o=a.get(r),s=o?.device??await eR(t.flags??{});o||await e9(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return N("INVALID_ARGS","record requires start|stop");if("start"===d)return nz({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await nJ({req:t,activeSession:l,device:s,logPath:i,deps:n});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 nY(e){let{req:t,sessionName:r,sessionStore:i,logPath:o}=e,s=t.command;if("record"===s)return nZ({req:t,sessionName:r,sessionStore:i,logPath:o});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return N("INVALID_ARGS","trace requires start|stop");let o=i.get(r);if(!o)return N("SESSION_NOT_FOUND","No active session");if("start"===e){if(o.trace)return N("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??i.defaultTracePath(o),r=tG.expandHome(e);return a.mkdirSync(n.dirname(r),{recursive:!0}),a.appendFileSync(r,""),o.trace={outPath:r,startedAt:Date.now()},i.recordAction(o,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!o.trace)return N("INVALID_ARGS","no active trace");let l=o.trace.outPath;if(t.positionals?.[1]){let e=tG.expandHome(t.positionals[1]);a.mkdirSync(n.dirname(e),{recursive:!0}),a.existsSync(l)?a.renameSync(l,e):a.appendFileSync(e,""),l=e}return o.trace=void 0,i.recordAction(o,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nX(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 nQ=new WeakMap;function n0(e){if(!e)return;let t=nQ.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)&&n1(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(n1);if(0===r.length)return;let a=Math.max(...r.map(e=>e.x+e.width)),i=Math.max(...r.map(e=>e.y+e.height));if(!(a<=0)&&!(i<=0))return{x:0,y:0,width:a,height:i}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return nQ.set(e,r),r}function n1(e){return!!e&&e.width>0&&e.height>0}let n2={referenceWidth:1e3,referenceHeight:1e3};function n5(e,t,r,a,i={},n=Date.now(),o=Date.now()){var s,l,d;let u,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=n6(p.effectiveDurationMs)??n6(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:n6(p.gestureStartUptimeMs),gestureEndUptimeMs:n6(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:n6(p.gestureStartUptimeMs),gestureEndUptimeMs:n6(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,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),w="ios"===e.device.platform&&void 0===n6(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=n9(n6(t.count),1)??1,r=!0===t.doubleTap,a=n9(n6(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,p)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return nX(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nX(h),v=(l=e.snapshot,u=n6((d=p).referenceWidth),c=n6(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:n0(l)),y=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=n7(t,e);if(!i)return[];let{x:n,y:o}=i,s=n9(n6(t.count),1)??1,l=n9(n6(t.intervalMs),0)??0,d=!0===t.doubleTap,u=n9(n6(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(n3(t,n,o,u,a));continue}c.push(n4(t,n,o,a)),d&&c.push(n4(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=n7(t,e);if(!i)return[];let{x:n,y:o}=i;return[n4(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=n7(t,e);if(!n)return[];let{x:o,y:s}=n;return[n3(r,o,s,ot(a,[n6(t.durationMs),n6(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=oe(t,e),o=n8(t.contentDirection)??n8(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=ot(a,[],250),f=n6(t.amount)??n6(e[1]),p=n6(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...i,durationMs:c,contentDirection:o,...void 0!==f?{amount:f}:{},...void 0!==p?{pixels:p}:{}}]}(t,r,a,i,n);case"swipe":return function(e,t,r,a,i){let n=oe(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=ot(a,[n6(t.effectiveDurationMs),n6(t.durationMs),n6(e[4])],250),c=n9(n6(t.count),1)??1,f=n9(n6(t.pauseMs),0)??0,p="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===p&&e%2==1,a=t?l:o,n=t?d:s,c=t?o:l,h=t?s:d,g=r+e*(u+f);if("back-swipe"===function(e,t,r,a,i){if(!i||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let n=.08*i.referenceWidth;return e<=n&&r>e||e>=i.referenceWidth-n&&r<e?"back-swipe":"swipe"}(a,n,c,h,i)){m.push({kind:"back-swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,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,i)});continue}m.push({kind:"swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u})}return m}(t,r,a,i,n);case"pinch":return function(e,t,r,a,i){let n=n7(t,e,1),o=n6(t.scale)??n6(e[0]);if(!n||void 0===o||o<=0)return[];let{x:s,y:l}=n;return[{kind:"pinch",tMs:r,x:s,y:l,...i,scale:o,durationMs:ot(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,v);0!==y.length&&(f.gestureEvents.push(...y),ti({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:y.length,tMs:w,gestureDurationMs:g,kinds:y.map(e=>e.kind)}}))}function n4(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function n3(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function n8(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 n6(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 n9(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function n7(e,t,r=0){let a=n6(e.x)??n6(t[r]),i=n6(e.y)??n6(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function oe(e,t){let r=n6(e.x1)??n6(t[0]),a=n6(e.y1)??n6(t[1]),i=n6(e.x2)??n6(t[2]),n=n6(e.y2)??n6(t[3]);if(void 0!==r&&void 0!==a&&void 0!==i&&void 0!==n)return{x1:r,y1:a,x2:i,y2:n}}function ot(e,t,r){return n9(e,1)??t.map(e=>n9(e,1)).find(e=>void 0!==e)??r}function or(e){var t,r,a;let i,n,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,i="string"==typeof t?.ref?t.ref:void 0,n="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:i?n&&"primary"!==n?`Clicked ${n} @${i} (${r}, ${a})`:`Tapped @${i} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...M(c)}}async function oa(e){let{session:t,sessionStore:r,requestCommand:a,requestPositionals:i,flags:n,contextFromFlags:o,interactionCommand:s,interactionPositionals:l,outPath:d,afterDispatch:u,buildPayloads:c}=e,f=await oi({session:t,flags:n,contextFromFlags:o,command:s,positionals:l,outPath:d});await u?.(f.data);let{result:p,responseData:m=p}=await c(f.data);return function(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:o}),eb(a)&&tm(t,a),n5(t,a,i,o,n??{},l,d),{ok:!0,data:s}}({session:t,sessionStore:r,command:a,positionals:i,flags:n,result:p,responseData:m,actionStartedAt:f.actionStartedAt,actionFinishedAt:f.actionFinishedAt})}async function oi(e){let{session:t,flags:r,contextFromFlags:a,command:i,positionals:n,outPath:o}=e,s=Date.now(),l={...a(r,t.appBundleId,t.trace?.outPath)},d=await w(t.device,i,n,o,l);return{data:d&&"object"==typeof d?d:void 0,actionStartedAt:s,actionFinishedAt:Date.now()}}async function on(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await O(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=n0(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=n0(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function oo(e){try{return await on(e)}catch(t){ti({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function os(e){return n0({nodes:e,createdAt:0})}function ol(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:N("UNSUPPORTED_OPERATION",`${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 od(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r),d=t.command,u="click"===d?"click":"press";if(!l)return N("SESSION_NOT_FOUND","No active session. Run open first.");let c=ol(l,u);if(c)return c;if(!tl("press",l.device))return N("UNSUPPORTED_OPERATION","press is not supported on this device");let f=ez(t.flags),p=ep(f);if("primary"!==f){let e=eN({commandLabel:u,platform:l.device.platform,button:f,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return N(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 oa({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[String(m.x),String(m.y)],flags:t.flags,contextFromFlags:i,interactionCommand:"press",interactionPositionals:[String(m.x),String(m.y)],outPath:t.flags?.out,afterDispatch:async()=>{await ou(l,"coordinate tap")},buildPayloads:async e=>{let r=await oo({session:l,flags:t.flags,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}),o=or({data:e,fallbackX:m.x,fallbackY:m.y,referenceFrame:r,extra:p});return{result:o,responseData:o}}});let h="click",g=t.positionals?.[0]??"";if(g.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 nr({session:l,refInput:g,fallbackLabel:r,commandLabel:u,promoteToHittableAncestor:!0,invalidRefMessage:`${u} requires a ref like @e2`,missingBoundsMessage:`Ref ${g} not found or has no bounds`,invalidBoundsMessage:`Ref ${g} not found or has invalid bounds`,reqFlags:t.flags,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n,resolveRefTarget:o});if(!c.ok)return c;let{ref:f,node:m,snapshotNodes:w,point:v}=c.target,y=e0(m,w),I=ew(m,l.device.platform,{action:h}),{x:S,y:A}=v;return oa({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"press",interactionPositionals:[String(S),String(A)],outPath:t.flags?.out,afterDispatch:async()=>{await ou(l,`@${f}`)},buildPayloads:e=>{let t=or({data:e,fallbackX:S,fallbackY:A,referenceFrame:os(w),extra:{ref:f,refLabel:y,selectorChain:I,...p}});return{result:t,responseData:t}}})}let w=(t.positionals??[]).join(" ").trim();if(!w)return N("INVALID_ARGS",`${u} requires @ref, selector expression, or x y coordinates`);let v=eH(w),y=await n(l,t.flags,a,i,{interactiveOnly:!0}),I=await eD("selector_resolve",()=>A(y.nodes,v,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:d});if(!I||!I.node.rect)return N("COMMAND_FAILED",eS(v,I?.diagnostics??[],{unique:!0}));let S=na(y.nodes,I.node),b=ne(S.rect);if(!b)return N("COMMAND_FAILED",`Selector ${I.selector.raw} resolved to invalid bounds`);let{x:_,y:x}=b,M=ew(S,l.device.platform,{action:h}),k=e0(S,y.nodes);return oa({session:l,sessionStore:a,requestCommand:d,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"press",interactionPositionals:[String(_),String(x)],outPath:t.flags?.out,afterDispatch:async()=>{await ou(l,I.selector.raw)},buildPayloads:e=>{let t=or({data:e,fallbackX:_,fallbackY:x,referenceFrame:os(y.nodes),extra:{selector:I.selector.raw,selectorChain:M,refLabel:k,...p}});return{result:t,responseData:t}}})}async function ou(e,t){if("android"!==e.device.platform||!e.appBundleId)return;let r=await eT(e.device),a=r.package?.trim();if(a&&a!==e.appBundleId){var i;if("com.android.settings"===(i=a)||"com.android.systemui"===i||"com.google.android.permissioncontroller"===i||i.includes("launcher"))throw new tI("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 oc(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n,resolveRefTarget:o,refSnapshotFlagGuardResponse:s}=e,l=a.get(r);if(l){let e=ol(l,"fill");if(e)return e}if(l&&!tl("fill",l.device))return N("UNSUPPORTED_OPERATION","fill is not supported on this device");if(t.positionals?.[0]?.startsWith("@")){if(!l)return N("SESSION_NOT_FOUND","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 N("INVALID_ARGS","fill requires text after ref");let u=await nr({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:i,captureSnapshotForSession:n,resolveRefTarget:o});if(!u.ok)return u;let{ref:c,node:f,snapshotNodes:p,point:m}=u.target,h=f.type??"",g=h&&!ea(h,l.device.platform)?`fill target ${t.positionals[0]} resolved to "${h}", attempting fill anyway.`:void 0,w=e0(f,p),v=ew(f,l.device.platform,{action:"fill"}),{x:y,y:I}=m;return oa({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"fill",interactionPositionals:[String(y),String(I),d],outPath:t.flags?.out,buildPayloads:e=>{let t=or({data:e,fallbackX:y,fallbackY:I,referenceFrame:os(p),extra:{ref:c,refLabel:w,selectorChain:v,text:d}}),r={...e??{ref:c,x:y,y:I}};return g&&(t.warning=g,r.warning=g),{result:t,responseData:r}}})}if(!l)return N("SESSION_NOT_FOUND","No active session. Run open first.");let d=es(t.positionals??[],{preferTrailingValue:!0});if(d){if(0===d.rest.length)return N("INVALID_ARGS","fill requires text after selector");let e=d.rest.join(" ").trim();if(!e)return N("INVALID_ARGS","fill requires text after selector");let r=eH(d.selectorExpression),o=await n(l,t.flags,a,i,{interactiveOnly:!0}),s=await eD("selector_resolve",()=>A(o.nodes,r,{platform:l.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:t.command});if(!s||!s.node.rect)return N("COMMAND_FAILED",eS(r,s?.diagnostics??[],{unique:!0}));let u=s.node,c=s.node.rect,f=u.type??"",p=f&&!ea(f,l.device.platform)?`fill target ${s.selector.raw} resolved to "${f}", attempting fill anyway.`:void 0,{x:m,y:h}=et(c),g=ew(u,l.device.platform,{action:"fill"});return oa({session:l,sessionStore:a,requestCommand:t.command,requestPositionals:t.positionals??[],flags:t.flags,contextFromFlags:i,interactionCommand:"fill",interactionPositionals:[String(m),String(h),e],outPath:t.flags?.out,buildPayloads:t=>{let r=or({data:t,fallbackX:m,fallbackY:h,referenceFrame:os(o.nodes),extra:{text:e,selector:s.selector.raw,selectorChain:g,refLabel:e0(u,o.nodes)}});return p&&(r.warning=p),{result:r,responseData:r}}})}return N("INVALID_ARGS","fill requires x y text, @ref text, or selector text")}async function of(e){switch(e.req.command){case"press":case"click":return await od(e);case"fill":return await oc(e);default:return null}}let op=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function om(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,a]of op)void 0!==e[r]&&t.push(a);return t}(t);return 0===r.length?null:N("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function oh(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},o=a(n,e.appBundleId,e.trace?.outPath),{snapshot:s}=await eB({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}async function og(e){let{command:t,selectorExpression:r,session:a,flags:i,sessionStore:n,contextFromFlags:o,interactiveOnly:s,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}=e,c=eH(r),f=await oh(a,i,n,o,{interactiveOnly:s}),p=await eD("selector_resolve",()=>A(f.nodes,c,{platform:a.device.platform,requireRect:l,requireUnique:d,disambiguateAmbiguous:u}),{command:t});return p&&(!l||p.node.rect)?{ok:!0,chain:c,snapshot:f,resolved:p}:{ok:!1,error:{code:"COMMAND_FAILED",message:eS(c,p?.diagnostics??[],{unique:d})}}}async function ow(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i}=e,n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return N("INVALID_ARGS","get only supports text or attrs");let o=a.get(r);if(!o)return N("SESSION_NOT_FOUND","No active session. Run open first.");if(!tl("get",o.device))return N("UNSUPPORTED_OPERATION","get is not supported on this device");let s=t.positionals?.[1]??"";if(s.startsWith("@")){let e=om("get",t.flags);if(e)return e;let r=i7({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;let{ref:l,node:d}=r.target,u=ew(d,o.device.platform,{action:"get"});if("attrs"===n)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 nn({device:o.device,node:d,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:i});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{ref:l,text:c,refLabel:ov(c),selectorChain:u}}),{ok:!0,data:{ref:l,text:c,node:d}}}let l=t.positionals.slice(1).join(" ").trim();if(!l)return N("INVALID_ARGS","get requires @ref or selector expression");let d=await og({command:t.command,selectorExpression:l,session:o,flags:t.flags,sessionStore:a,contextFromFlags:i,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:"text"===n});if(!d.ok)return d;let{resolved:u}=d,c=u.node,f=ew(c,o.device.platform,{action:"get"});if("attrs"===n)return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{selector:u.selector.raw,selectorChain:f}}),{ok:!0,data:{selector:u.selector.raw,node:c}};let p=await nn({device:o.device,node:c,flags:t.flags,appBundleId:o.appBundleId,traceOutPath:o.trace?.outPath,surface:o.surface,contextFromFlags:i});return a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{text:p,refLabel:ov(p),selector:u.selector.raw,selectorChain:f}}),{ok:!0,data:{selector:u.selector.raw,text:p,node:c}}}function ov(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function oy(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 oI(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i}=e,n=(t.positionals?.[0]??"").toLowerCase();if(!["visible","hidden","exists","editable","selected","text"].includes(n))return N("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let o=a.get(r);if(!o)return N("SESSION_NOT_FOUND","No active session. Run open first.");if(!tl("is",o.device))return N("UNSUPPORTED_OPERATION","is is not supported on this device");let{split:s}=eX(t.positionals);if(!s)return N("INVALID_ARGS","is requires a selector expression");let l=s.rest.join(" ").trim();if("text"===n&&!l)return N("INVALID_ARGS","is text requires expected text value");if("text"!==n&&s.rest.length>0)return N("INVALID_ARGS",`is ${n} does not accept trailing values`);let d=eH(s.selectorExpression);if("exists"===n){let e=eE((await oh(o,t.flags,a,i,{interactiveOnly:!1})).nodes,d,{platform:o.device.platform});return e?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:n,selector:e.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,matches:e.matches}}),{ok:!0,data:{predicate:n,pass:!0,selector:e.selector.raw,matches:e.matches}}):N("COMMAND_FAILED",eS(d,[],{unique:!1}))}let u=await og({command:"is",selectorExpression:s.selectorExpression,session:o,flags:t.flags,sessionStore:a,contextFromFlags:i,interactiveOnly:!1,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!u.ok)return u;let{resolved:c}=u,f=function(e){let{predicate:t,node:r,nodes:a,expectedText:i,platform:n}=e,o=C(r),s=S(r,n),l=!0===r.selected,d="text"===t?ex(r):function(e,t){if(!0===e.hittable)return!0;if(oy(e.rect))return v(e,t);if(e.rect)return!1;let r=function(e,t){let r=new Map(t.map(e=>[e.index,e])),a=e,i=new Set;for(;"number"==typeof a.parentIndex&&!i.has(a.index);){i.add(a.index);let e=r.get(a.parentIndex);if(!e)break;if(function(e){let t=tc(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||oy(e.rect))}(e))return e;a=e}return null}(e,t);return!!r&&(!0===r.hittable||!!oy(r.rect)&&v(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===(i??"")}let c="text"===t?`expected="${i??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:n,node:c.node,nodes:u.snapshot.nodes,expectedText:l,platform:o.device.platform});return f.pass?(a.recordAction(o,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:n,selector:c.selector.raw,selectorChain:d.selectors.map(e=>e.raw),pass:!0,text:"text"===n?f.actualText:void 0}}),{ok:!0,data:{predicate:n,pass:!0,selector:c.selector.raw}}):N("COMMAND_FAILED",`is ${n} failed for selector ${c.selector.raw}: ${f.details}`)}function oS(e,t){var r,a;let i=Math.max(1,t.height),n=Math.max(1,t.width),o=t.y,s=t.y+i,l=t.x,d=t.x+n,u=s-.25*i,c=Math.max(8,.1*n),f=e.y+e.height/2,p=e.x+e.width/2;if(f>=o+.25*i&&f<=u)return null;let m=Math.round((r=p,a=l+c,Math.min(d-c,Math.max(a,r)))),h=Math.round(o+.86*i),g=Math.round(o+.14*i);return f>u?{x:m,startY:h,endY:g,direction:"down"}:{x:m,startY:g,endY:h,direction:"up"}}async function oA(e){var t;let r,a,i,{req:n,sessionName:o,sessionStore:s,contextFromFlags:l}=e,d=s.get(o);if(!d)return N("SESSION_NOT_FOUND","No active session. Run open first.");if(!tl("scrollintoview",d.device))return N("UNSUPPORTED_OPERATION","scrollintoview is not supported on this device");let u=n.positionals?.[0]??"";if(!u.startsWith("@"))return null;let c=om("scrollintoview",n.flags);if(c)return c;let f=n.positionals&&n.positionals.length>1?n.positionals.slice(1).join(" ").trim():"",p=(r=i7({session:d,refInput:t=u,fallbackLabel:f,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${t} not found or has no bounds`})).ok?ob(t,0,r.target):"COMMAND_FAILED"!==r.error.code?r:o_(t,0,{message:r.error.message});if(!p.ok)return p;let{ref:m}=p.state,{currentRef:h,node:g,snapshotNodes:v,viewportRect:y}=p.state,I=e0(g,v),S=ew(g,d.device.platform,{action:"get"}),b=f||I||g.label||"";if(!oS(g.rect,y)){let e=oN({ref:m,currentRef:h,attempts:0,alreadyVisible:!0});return s.recordAction(d,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:{refLabel:I,selectorChain:S,...e}}),{ok:!0,data:e}}let _=n.flags?.maxScrolls??48,x=0,M=0,k=eY(g.rect,y);for(;x<_;){let e=oS(g.rect,y);if(!e)break;a=e.direction,i=await w(d.device,"swipe",[String(e.x),String(e.startY),String(e.x),String(e.endY),"16"],n.flags?.out,{...l(n.flags,d.appBundleId,d.trace?.outPath),count:1,pauseMs:0,pattern:"one-way"}),x+=1,await oh(d,n.flags,s,l,{interactiveOnly:!0});let t=function(e){let{session:t,targetInput:r,fallbackLabel:a,attempts:i,ref:n,selectorChain:o,platform:s}=e;if(t.snapshot){let e=function(e,t,r,a){for(let r of t){let t=A(e,eH(r),{platform:a,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(t?.node.rect)return t.node}return r?to(e,r):null}(t.snapshot.nodes,o,a,s);if(e)return ob(r,i,{ref:n,node:e,snapshotNodes:t.snapshot.nodes},{currentRef:e.ref})}let l=i7({session:t,refInput:r,fallbackLabel:a,requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${r} not found or has no bounds`});return l.ok?ob(r,i,l.target,{ref:n,currentRef:l.target.node.ref,missingBoundsMessage:`scrollintoview lost bounds for ${r} after ${i} scroll${1===i?"":"s"}`}):"COMMAND_FAILED"!==l.error.code?l:o_(r,i,{message:`scrollintoview lost track of ${r} after ${i} scroll${1===i?"":"s"}`,ref:n})}({session:d,targetInput:u,fallbackLabel:b,attempts:x,ref:m,selectorChain:S,platform:d.device.platform});if(!t.ok)return t;({currentRef:h,node:g,snapshotNodes:v,viewportRect:y}=t.state);let r=eY(g.rect,y);if(0===r)break;if(r>=k){if((M+=1)>=2)return o_(u,x,{message:`scrollintoview made no progress toward ${u} after ${x} scroll${1===x?"":"s"}`,ref:m,stalled:!0})}else M=0;k=r}if(eY(g.rect,y)>0)return o_(u,x,{message:`scrollintoview reached --max-scrolls=${_} before ${u} entered view`,ref:m,maxScrolls:_});let D=oN({data:i,ref:m,currentRef:h,attempts:x,direction:a});return s.recordAction(d,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:{refLabel:I,selectorChain:S,...D}}),{ok:!0,data:D}}function ob(e,t,r,a={}){let{ref:i,currentRef:n,missingBoundsMessage:o}=a,s=r.node;if(!s.rect)return o_(e,t,{message:o??`Ref ${e} not found or has no bounds`,ref:i??r.ref});let l=j(r.snapshotNodes,s.rect);return l?{ok:!0,state:{ref:i??r.ref,currentRef:n??r.node.ref,node:s,snapshotNodes:r.snapshotNodes,viewportRect:l}}:N("COMMAND_FAILED",`scrollintoview could not infer viewport for ${e}`)}function o_(e,t,r={}){let{message:a,...i}=r;return N("COMMAND_FAILED","string"==typeof a?a:`scrollintoview could not find ${e}`,{reason:"not_found",attempts:t,...i})}function oN(e){let{data:t,ref:r,currentRef:a,attempts:i,alreadyVisible:n,direction:o}=e;return{...t??{},ref:r,currentRef:a,attempts:i,...n?{alreadyVisible:n}:{},...o?{direction:o}:{},...M(`Scrolled into view: @${r}`)}}async function ox(e){let t=await of({...e,captureSnapshotForSession:oh,resolveRefTarget:i7,refSnapshotFlagGuardResponse:om});if(t)return t;switch(e.req.command){case"get":return await ow(e);case"is":return await oI(e);case"scrollintoview":return await oA(e);default:return null}}function oM(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 ok(e){let{req:t,leaseRegistry:r}=e,a=oM(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 oD(e,t){if(!t)return[];let r=[],a=e.device,i=tf(t.platform);if(i&&!ts(a.platform,i)&&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(),i=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==i)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=L(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oP(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 oL=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"],oR=/\bis(?:n't| not)\s+responding\b/i,oO=/^close app$/i;async function oE(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await oC(t),r=function(e){if(oU(e))return e.find(e=>{let t=oF(e);return t.length>0&&oO.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=et(r.rect),n=await tw("adb",eQ(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return ti({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),"failed";if(!await o$(t))return ti({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eZ(t.device,t.appBundleId),!await oT(t,t.appBundleId)))return ti({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return ti({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:i}}),"recovered"}catch(e){return ti({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 oC(e){return ei(eP((await ek(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function o$(e){for(let t=0;t<12;t+=1){if(!oU(await oC(e)))return!0;await oG(500)}return!oU(await oC(e))}async function oT(e,t){for(let r=0;r<12;r+=1){if((await eT(e.device)).package===t)return!0;await oG(500)}return(await eT(e.device)).package===t}function oF(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 oU(e){return e.some(e=>{let t=oF(e);return t.length>0&&oR.test(t)})}function oG(e){return new Promise(t=>setTimeout(t,e))}let oV=[255,59,48,255],oq=[255,214,10,255],oj=[0,0,0,255],oB={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 oH(e){let t=tp(await i.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oz(r)&&oX(r.rect)&&(!t||oQ(r.rect)>oQ(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,i=-1/0;for(let n of e)n.rect&&oX(n.rect)&&(t=Math.min(t,n.rect.x),r=Math.min(r,n.rect.y),a=Math.max(a,n.rect.x+n.rect.width),i=Math.max(i,n.rect.y+n.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||i<=r?null:{x:t,y:r,width:a-t,height:i-r}}(e.filter(e=>{var t;return oX(e.rect)&&!("image"===tc((t=e).type??"")&&!oW(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oJ)||oZ(e.identifier);return oK(e)?t:t&&function(e){let t=tc(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 oK(e)&&!oz(e)}(t)&&oX(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(oK(t)&&!oz(t)&&oX(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oX(r.rect))return r;if(t.hittable&&oX(t.rect)&&!oz(t))return t;let a=W(e,t);return a?.rect&&oX(a.rect)&&!oz(a)?a:null}(e.nodes,a);if(!o?.rect||!oX(o.rect))continue;let s=function(e,t,r){let a=oY(e);if(e.ref!==t.ref&&a)return a;let i=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 i=oY(a);if(!i)continue;let n=function(e){let t=0;return tc(e.type??"").includes("text")&&(t+=2),oJ(e.label)&&(t+=2),oJ(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oY(t)??e0(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),oK(t)&&(a+=3),oK(e)&&(a+=2),r&&(a+=2),oZ(t.identifier)&&(a+=1),oW(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return o2({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,a);let i=r/e.width,n=a/e.height;return o2({x:Math.round((t.x-e.x)*i),y:Math.round((t.y-e.y)*n),width:Math.max(1,Math.round(t.width*i)),height:Math.max(1,Math.round(t.height*n))},r,a)}(i,o.rect,t,r);if(!oX(d))continue;let u=n.get(o.ref);(!u||l>u.score)&&n.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)=>oQ(e.overlayRect)-oQ(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(o0(e.overlayRect,r.overlayRect)||o0(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oQ(r.overlayRect)<oQ(t[e].overlayRect)&&(t[e]=r)}return t})([...n.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:o1(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:o1(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:et(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)o4(e,t.x,t.x+t.width-1,t.y+a,r),o4(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),o3(e,t.x+a,t.y,t.y+t.height-1,r),o3(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(n=e).overlayRect,oV),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=o5(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:o5(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)o8(e,t+o,r+n,i)})(e,i,o,a,oq),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oB[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]&&o8(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,oj)}(a,n.overlayRect,n.ref)}return await i.writeFile(e.screenshotPath,p.sync.write(t)),r}function oK(e){let t=[e.type,e.role,e.subrole].map(e=>tc(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 oz(e){let t=[e.type,e.role,e.subrole].map(e=>tc(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oW(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oJ(e){var t;let r;return!!oW(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oZ(e){var t;return"string"==typeof e&&!!oJ(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oY(e){let t=[e.label,e.value].find(oJ);return t?t.trim():oZ(e.identifier)?e.identifier.trim():void 0}function oX(e){return!!(e&&e.width>0&&e.height>0)}function oQ(e){return e.width*e.height}function o0(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 o1(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function o2(e,t,r){let a=o5(e.x,0,Math.max(0,t-1)),i=o5(e.y,0,Math.max(0,r-1)),n=Math.max(1,t-a),o=Math.max(1,r-i);return{x:a,y:i,width:o5(e.width,1,n),height:o5(e.height,1,o)}}function o5(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function o4(e,t,r,a,i){for(let n=t;n<=r;n+=1)o8(e,n,a,i)}function o3(e,t,r,a,i){for(let n=r;n<=a;n+=1)o8(e,t,n,i)}function o8(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let i=(e.width*r+t)*4;e.data[i]=a[0],e.data[i+1]=a[1],e.data[i+2]=a[2],e.data[i+3]=a[3]}let o6=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),o9=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),o7=new Set(o9),se=new Map;function st(e,t,r,a){let i=e7().requestId;return{...eV(e,t,r,a,i),requestId:i}}async function sr(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||at(e.flags))try{let t=await eR(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function sa(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await ok({req:t,leaseRegistry:n});if(l)return l;let d=await i9({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await I({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await nY({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await no({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await ox({req:t,sessionName:r,sessionStore:i,contextFromFlags:s});return p||null}async function si(e){var t;let r,a,i,n,o,s,l,{req:d,session:u,logPath:c,sessionStore:f}=e,p=d.command;if(!tl(p,u.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${p} is not supported on this device`}};if("android"===u.device.platform&&u.recording&&"record"!==p&&"failed"===await oE({session:u}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:m,resolvedOut:h,recordedPositionals:g,recordedFlags:v}=(r=(t=d).command,a=t.positionals??[],i=t.flags?.out,n="screenshot"===r&&a[0]?[tG.expandHome(a[0],t.meta?.cwd),...a.slice(1)]:a,o="screenshot"===r&&i?tG.expandHome(i,t.meta?.cwd):i,s="screenshot"===r?n:a,l="screenshot"===r&&o?{...t.flags??{},out:o}:t.flags??{},{resolvedPositionals:n,resolvedOut:o,recordedPositionals:s,recordedFlags:l}),y=Date.now(),I={...st(c,d.flags,u.appBundleId,u.trace?.outPath),surface:u.surface},S=await w(u.device,p,m,h,{...I});return"screenshot"===p&&d.flags?.overlayRefs&&"string"==typeof S?.path&&await sn(u,S,c),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=n0(e.snapshot),n={...a??{}},o=n8(n.direction)??n8(r[0]);if(!o)return a;let s=n6(n.amount)??n6(r[1]),l=n6(n.pixels),d=oe(n,[]),u=n6(n.referenceWidth),c=n6(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??n2;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...n,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:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=eo({direction:o,amount:s,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,s);n5(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:u,sessionStore:f,command:p,resolvedPositionals:m,recordedPositionals:g,recordedFlags:v,data:S,actionStartedAt:y,actionFinishedAt:Date.now(),flags:d.flags??{}}),eb(p)&&tm(u,p),{ok:!0,data:S??{}}}async function sn(e,t,r){let a=eJ(await T({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oH({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function so(e){a.existsSync(e)&&a.unlinkSync(e)}function ss(e){if(!a.existsSync(e))return null;try{let t=JSON.parse(a.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function sl(e){let t=ss(e);if(!t||t.pid===process.pid)try{a.existsSync(e)&&a.unlinkSync(e)}catch{}}function sd(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:su,infoPath:sc,lockPath:sf,logPath:sp,sessionsDir:sm}=td(process.env.AGENT_DEVICE_STATE_DIR),sh=eu(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var sg=sm;if(a.existsSync(sg))for(let e of a.readdirSync(sg,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=n.join(sg,e.name,tq);if(a.existsSync(t))try{let e=tj(a.readFileSync(t,"utf8"));if(e&&function(e){let t,r=Y(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=el(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{tH(t)}}let sw=new tG(sm),sv=new rY({maxActiveSimulatorLeases:sd(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:sd(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:sd(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:sd(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),sy=H(),sI=r.randomBytes(24).toString("hex"),sS=Y(process.pid)??void 0,sA=ej(),sb=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:o}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await X({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:ty(new tI("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=_(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=eK(r);if(r&&!a)throw new tI("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new tI("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let i=e.session||"default";return i.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${i}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);ti({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let l=r.command,d=oM(r);o9.has(l)||r.meta?.sessionIsolation!=="tenant"||i.assertLeaseAdmission({tenantId:d.tenantId,runId:d.runId,leaseId:d.leaseId,backend:d.leaseBackend});let u=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,a),c=o7.has(l)?null:await sr(r,u,a),f=async()=>{let e=a.get(u);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=V(e.device.id);if(!t.runnerSessionId){r?.alive&&(t.runnerSessionId=r.sessionId);return}if(!r?.alive){t.invalidatedReason??="iOS runner session exited during recording";return}r.sessionId!==t.runnerSessionId&&(t.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(u,e));let d=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?oD(t,a):function(e,t,r){var a,i;let n=[],o=tf(t);if(void 0!==e.platform&&o&&(a=tf(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!Q(i):"apple"!==i||!Q(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of oL){let r=e[t];"string"==typeof r&&r.trim().length>0&&n.push({key:t,value:r})}return n}(a,e.meta?.lockPlatform,e.command);if(0===i.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,i),a.platform=t.device.platform):function(e,t){for(let t of oL)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new tI("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oP).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=e7();if(!t.ok){ti({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=tu({force:!0})??void 0;return{ok:!1,error:ty(new tI(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 ti({level:"info",phase:"request_success"}),tu(),{ok:!0,data:function(e,t,r){var a,i;let o;if(!t)return t;let s=(a=e,i=t,o=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||o.some(e=>e?.field==="path")||"string"!=typeof i.path||o.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:n.basename(a.meta?.clientArtifactPaths?.path??i.path)}),o.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.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)}})(d,e,o);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||o6.has(l)||function(e,t){let r=oD(e,t);if(0!==r.length){var a;let t,i,n;throw new tI("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oP).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await sa({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...st(t,e,r,i),surface:a.get(u)?.surface})});if(f)return c(f);let p=a.get(u);if(!p)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await si({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await D(se,c,f)}catch(r){ti({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=e7(),t=tu({force:!0})??void 0;return{ok:!1,error:ty(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:sp,token:sI,sessionStore:sw,leaseRegistry:sv,trackDownloadableArtifact:function(e){let t=r.randomUUID(),a=setTimeout(()=>{rS(t)},9e5);return a.unref(),rI.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:a}),t}});!async function(){let e,t;if(!function(e,t,r){a.existsSync(e)||a.mkdirSync(e,{recursive:!0});let i=JSON.stringify(r,null,2),n=()=>{try{return a.writeFileSync(t,i,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=ss(t);if(o?.pid&&o.pid!==process.pid&&y(o.pid,o.processStartTime))return!1;try{a.unlinkSync(t)}catch{}return n()}(su,sf,{pid:process.pid,version:sy,startedAt:Date.now(),processStartTime:sS})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var i;let n;if("socket"===sh||"dual"===sh){let t=m.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))e4(e);ti({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await G(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){ti({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",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=U(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),b(o),F(o))throw eA();i=await sb(e)}catch(e){i={ok:!1,error:ty(e)}}finally{r-=1,o&&(a.delete(o),K(o))}e.destroyed||e.write(`${JSON.stringify(i)}
35
+ `),n=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 tI("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===sh||"dual"===sh){let e=await rB({handleRequest:sb,token:sI});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 tI("COMMAND_FAILED","Failed to bind HTTP server"))})})}i={socketPort:e,httpPort:t,token:sI,version:sy,codeSignature:sA,processStartTime:sS},a.existsSync(su)||a.mkdirSync(su,{recursive:!0}),a.writeFileSync(sp,""),n=i.socketPort&&i.httpPort?"dual":i.httpPort?"http":"socket",a.writeFileSync(sc,JSON.stringify({port:i.socketPort,httpPort:i.httpPort,transport:n,token:i.token,pid:process.pid,version:i.version,codeSignature:i.codeSignature,processStartTime:i.processStartTime,stateDir:su},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
39
36
  `),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${t}
40
- `)}catch(t){let e=td(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
41
- `),r))try{t.close(()=>{})}catch{}sx(sL),sM(sR),process.exit(1);return}let n=!1,o=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},s=async()=>{if(!n){for(let e of(n=!0,await o(),sT.toArray()))sT.writeSessionLog(e);await ec(),sx(sL),sM(sR),process.exit(0)}};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof tc?e:td(e);process.stderr.write(`Daemon error: ${t.message}
42
- `),s()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof tc?t:td(t);process.stderr.write(`Daemon error: ${r.message}
37
+ `)}catch(t){let e=tv(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
38
+ `),r))try{t.close(()=>{})}catch{}so(sc),sl(sf),process.exit(1);return}let n=!1,o=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},s=async()=>{if(!n){for(let e of(n=!0,await o(),sw.toArray()))sw.writeSessionLog(e);await eO(),so(sc),sl(sf),process.exit(0)}};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof tI?e:tv(e);process.stderr.write(`Daemon error: ${t.message}
39
+ `),s()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof tI?t:tv(t);process.stderr.write(`Daemon error: ${r.message}
43
40
  `),s()})}();