agent-device 0.12.7 → 0.12.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/src/113.js +1 -1
  2. package/dist/src/1974.js +2 -0
  3. package/dist/src/3883.js +1 -0
  4. package/dist/src/3918.js +32 -0
  5. package/dist/src/4057.js +1 -0
  6. package/dist/src/4829.js +1 -0
  7. package/dist/src/4993.js +1 -0
  8. package/dist/src/7556.js +1 -0
  9. package/dist/src/7651.js +1 -0
  10. package/dist/src/7847.js +1 -0
  11. package/dist/src/8164.js +1 -0
  12. package/dist/src/8564.js +3 -0
  13. package/dist/src/9076.js +1 -0
  14. package/dist/src/9152.js +1 -0
  15. package/dist/src/9323.js +5 -0
  16. package/dist/src/9366.js +1 -0
  17. package/dist/src/9542.js +2 -0
  18. package/dist/src/9818.js +1 -0
  19. package/dist/src/989.js +1 -0
  20. package/dist/src/android-apps.js +1 -1
  21. package/dist/src/artifacts.js +1 -1
  22. package/dist/src/backend.js +1 -1
  23. package/dist/src/bin.d.ts +1 -0
  24. package/dist/src/bin.js +68 -70
  25. package/dist/src/commands/index.d.ts +4 -1
  26. package/dist/src/commands/index.js +1 -1
  27. package/dist/src/contracts.d.ts +3 -1
  28. package/dist/src/contracts.js +1 -1
  29. package/dist/src/daemon.d.ts +1 -0
  30. package/dist/src/daemon.js +15 -15
  31. package/dist/src/finders.js +1 -1
  32. package/dist/src/index.d.ts +17 -11
  33. package/dist/src/index.js +1 -3
  34. package/dist/src/install-source.js +1 -1
  35. package/dist/src/io.js +1 -1
  36. package/dist/src/metro-companion.d.ts +1 -0
  37. package/dist/src/metro.d.ts +9 -11
  38. package/dist/src/metro.js +1 -1
  39. package/dist/src/remote-config.js +1 -1
  40. package/dist/src/selectors.js +1 -1
  41. package/dist/src/testing/conformance.js +1 -1
  42. package/dist/src/update-check-entry.d.ts +1 -0
  43. package/package.json +9 -1
  44. package/skills/agent-device/references/exploration.md +1 -0
  45. package/skills/agent-device/references/remote-tenancy.md +9 -6
  46. package/skills/agent-device/references/verification.md +3 -0
  47. package/dist/src/152.js +0 -1
  48. package/dist/src/164.js +0 -1
  49. package/dist/src/556.js +0 -1
  50. package/dist/src/57.js +0 -1
  51. package/dist/src/641.js +0 -38
  52. package/dist/src/818.js +0 -1
  53. package/dist/src/974.js +0 -2
  54. /package/dist/src/{267.js → 3267.js} +0 -0
  55. /package/dist/src/{1~rslib-runtime.js → rslib-runtime.js} +0 -0
@@ -1,12 +1,12 @@
1
- let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import o from"node:path";import{spawn as s}from"node:child_process";import l from"node:http";import{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{resolveInstallFromSourceResultTarget as g,normalizePlatformSelector as w,readProcessCommand as y,buildSimctlArgs as v,dispatchCommand as I,resolveAppleSimulatorSetPathForSelector as S,isAgentDeviceDaemonProcess as A,validateAndNormalizeBatchSteps as b,listIosDeviceProcesses as _,attachRefs as N,centerOfRect as k,buildScrollGesturePlan as x,hasRuntimeTransportHints as M,resolveDeployResultTarget as D,listIosDeviceApps as P,device_isApplePlatform as L,buttonTag as R,refSnapshotFlagGuardResponse as O,handleSnapshotCommands as E,runner_client_runIosRunnerCommand as C,normalizeType as T,withSuccessText as $,shutdownSimulator as F,decodePng as U,stopIosRunnerSession as G,splitSelectorFromArgs as V,localCommandPolicy as j,resolveSelectorChain as q,buildSelectorChainForNode as H,IOS_RUNNER_CONTAINER_BUNDLE_IDS as B,createRequestCanceledError as z,isNavigationSensitiveAction as K,registerRequestAbort as W,resolveSessionIsolationMode as J,resolveIosDevicectlHint as Z,getClickButtonValidationError as X,snapshotAndroid as Y,capabilities_isCommandSupportedOnDevice as Q,successText as ee,pruneGroupNodes as et,applyRuntimeHintsToApp as er,withKeyedLock as ea,snapshot_processing_resolveRefLabel as ei,snapshot_capture_captureSnapshot as en,dispatchGetViaRuntime as eo,DEFAULT_BATCH_MAX_STEPS as es,classifyAndroidAppTarget as el,parseSerialAllowlist as ed,runMacOsAlertAction as eu,createAgentDevice as ec,assertAndroidPressStayedInApp as ef,resolveTargetDevice as ep,isDeepLinkTarget as em,clearRuntimeHintsFromApp as eh,parseFindArgs as eg,resolveDaemonCodeSignature as ew,stopAllIosRunnerSessions as ey,getAndroidScreenSize as ev,getAndroidAppState as eI,extractNodeText as eS,readTextForNode as eA,normalizeTenantId as eb,dispatchIsViaRuntime as e_,resolveClickButton as eN,resolveTimeoutMs as ek,IOS_DEVICECTL_DEFAULT_HINT as ex,buildSnapshotState as eM,openAndroidApp as eD,context_contextFromFlags as eP,captureSnapshotData as eL,splitIsSelectorArgs as eR,isRequestCanceled as eO,resolveRequestTrackingId as eE,adbArgs as eC,resolvePayloadInput as eT,abortAllIosRunnerSessions as e$,tryParseSelectorChain as eF,getRunnerSessionSnapshot as eU,formatAndroidInstalledPackageRequiredMessage as eG,createUnsupportedArtifactAdapter as eV,isAndroidEscapeError as ej,resolveIosSimulatorDeviceSetPath as eq,markRequestCanceled as eH,resolveIosDeviceDeepLinkBundleId as eB,dispatchFindReadOnlyViaRuntime as ez,response_errorResponse as eK,parseCoordinateTarget as eW,resolveUserPath as eJ,ensureDeviceReady as eZ,getDiagnosticsMeta as eX,readInfoPlistString as eY,clearRequestCanceled as eQ,buildSimctlArgsForDevice as e0,getActiveAndroidSnapshotFreshness as e1,emitDiagnostic as e2,parseXmlDocumentSync as e4,findNearestHittableAncestor as e3,resolveFrontmostMacOsApp as e5,IOS_SIMCTL_LIST_TIMEOUT_MS as e8,findBestMatchesByLocator as e6,readVersion as e9,matchesPlatformSelector as e7,readProcessStartTime as te,withDiagnosticsScope as tt,parseSessionSurface as tr,resolveAndroidSerialAllowlist as ta,resolveDaemonPaths as ti,markAndroidSnapshotFreshness as tn,resolveDaemonServerMode as to,flushDiagnosticsToSessionFile as ts,getRequestSignal as tl}from"./641.js";import{runCmdBackground as td,runCmd as tu,asAppError as tc,normalizeError as tf,AppError as tp}from"./818.js";function tm(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function th(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tg=/^-?\d+(\.\d+)?$/,tw=/^[^\s"\\]+$/,ty=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tv=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tI=new Map([["--delay-ms","delayMs"]]);function tS(e){return"click"===e||"press"===e}function tA(e){return"type"===e||"fill"===e}function tb(e){return tN(e,tk)}function t_(e){return JSON.stringify(e)}function tN(e,t){return t(e)?e:t_(e)}function tk(e){return tx(e)&&e.startsWith("@")||tg.test(e)}function tx(e){return tw.test(e)}function tM(e,t){let r=t.flags??{};if(tS(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}tA(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",tN(t.metroHost,tx)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tN(t.bundleUrl,tx)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tN(t.launchUrl,tx)))}function tP(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tN(r,tx)),a))e.push(tb(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}function tL(e,t){let r=[],a={},i=tS(e)?ty:"swipe"===e?tv:tA(e)?tI:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(tS(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(tS(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 tE(e,t){for(let r of t.positionals??[])e.push(tb(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 tT)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),e2({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=o.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a=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=${t_(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(tS(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tb(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tb(a)),tM(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tb(r)),tM(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tb(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tb(a)),e.positionals.length>1&&t.push(tb(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(tb(r)),t.push(tb(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tb(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",tb(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tb(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return tE(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tN(r,tx)),tD(t,e.flags),t.join(" ")}if("record"===e.command)return tP(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tb(r));return tM(t,e),t.join(" ")}(i));return`${r.join("\n")}
2
- `}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=tC.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return o.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return o.join(this.sessionsDir,tC.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return o.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 eJ(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tC.expandHome(e.saveScriptPath);i.existsSync(this.sessionsDir)||i.mkdirSync(this.sessionsDir,{recursive:!0});let t=tC.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return o.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&&(tS(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(tS(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=tm(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(tS(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 tT=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw","screenshotFullscreen","relaunch","saveScript","noRecord","fps","quality","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"],t$="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=o.dirname(e);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:te(t)??void 0,command:y(t)??void 0};i.writeFileSync(e,`${JSON.stringify(a)}
3
- `)}function tG(e){if(e&&i.existsSync(e))try{i.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 tj(e){await new Promise(t=>setTimeout(t,e))}function tq(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 tH(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 tB(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new tp("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tz(e,t){let r=(await tu("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tK(e,t){var r,a;let i;tB(t);let n=await tz(e,t),o=await tu("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,o,l="recovering",d=!1,u=(async()=>{try{for(;!d;){let u=await tz(e,t);if(!u){l="recovering",await tj(1e3);continue}let c=s("adb",["-s",e,"logcat","-v","time","--pid",u],{stdio:["ignore","pipe","pipe"]});n=c;let f=tq(r,{redactionPatterns:a});if(o=tH(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&(tU(i,c.pid),l="active"),await o,tG(i),n=void 0,o=void 0,d)break;l="recovering",await tj(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"),o&&await tV(o),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=v(["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 tu("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 tX(e,t,r,a,i,n){let o="active",l=s("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return v(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tJ(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tq(r,{redactionPatterns:a});"number"==typeof l.pid&&tU(n,l.pid);let u=tH(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(o="failed"),tG(n),e));return{backend:"ios-simulator",getState:()=>o,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 tY(e,t,r,a){let i="active",n=s("log",["stream","--style","compact","--predicate",tJ(e)],{stdio:["ignore","pipe","pipe"]}),o=tq(t,{redactionPatterns:r});"number"==typeof n.pid&&tU(a,n.pid);let l=tH(n,t,{endStreamOnClose:!0,writer:o}).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=s("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tq(t,{redactionPatterns:r});"number"==typeof n.pid&&tU(a,n.pid);let l=tH(n,t,{endStreamOnClose:!0,writer:o}).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 t4(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t5(e)));for(let e of t.entries){let t=t5(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t3(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:t9(o),packetId:t7(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=>t7(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t8(t,r,12).filter(e=>t7(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>t9(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 t5(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 t9(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 t7(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=o.dirname(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),function(e,t){if(i.existsSync(e)&&!(i.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;i.existsSync(t)&&(i.existsSync(a)&&i.unlinkSync(a),i.renameSync(t,a))}}(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,a,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:v,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y},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),i.existsSync(m)?t3(i.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 tK(u.id,c);if(e){let t=t3(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(I=t4(t,I,h),S.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await rc({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});e&&(e.dump.entries.length>0?(I=t4(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:v,dump:I,notes:S}}async function rd(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tF(i.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}(o.join(o.dirname(a),t$));if(!s)return null;let l=await tz(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function ru(e,t,r,a){rs(r);let n=i.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,a):await tX(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return tB(t),await tW(e.id,t,n,o,a);if("macos"===e.platform)return await tY(t,n,o,a);throw n.end(),new tp("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:t3(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 tu("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await tu("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 tu("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 tu("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await tu("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rm(e){let t=o.dirname(e),r=o.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let a=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{i.unlinkSync(o.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rh=new Map;function rg(e){let t=rh.get(e);if(t&&(clearTimeout(t.timer),rh.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rw=new Map;function ry(e,t){let r=rw.get(e);if(!r)throw new tp("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tp("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rv(e){let t=rw.get(e);t&&(clearTimeout(t.timer),rw.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rI(e){let t=await rS(e);await tu("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=o.join(e.tempDir,t);if(!i.existsSync(r))throw new tp("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rS(e){let t=await tu("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new tp("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 tp("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 tp("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new tp("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 tp("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 tp("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 tp("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await tu("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new tp("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function rA(e){if(e.includes("\0"))throw new tp("INVALID_ARGS",`Invalid archive entry: ${e}`);if(o.posix.isAbsolute(e))throw new tp("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=o.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new tp("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,a)=>{let n,o=i.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(),i.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new tp("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 tp("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 tp("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"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new tp("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new tp("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 tp("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=o.basename(t);if(!r||"."===r||".."===r)throw new tp("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),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"),i.mkdtempSync(o.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=o.join(s,n);return await r_(e,t),{artifactPath:t,tempDir:s}}let t=o.join(s,"artifact.tar");await r_(e,t);let a=await rI({archivePath:t,tempDir:s,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:s}}catch(e){throw i.rmSync(s,{recursive:!0,force:!0}),e}}let rk=new Set(["agent_device.command","agent-device.command"]),rx=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([...rk,...rx,...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 rE(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 rT(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function r$(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=tf(new tp("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=tf(new tp(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=eb(r.tenantId);if(!e){let e=tf(new tp("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=o.isAbsolute(t)?t:o.resolve(t);try{e=await import(u(a).href)}catch(e){throw new tp("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 tp("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 l.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(rk.has(e))return{token:rE(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(rx.has(e)){let e,a=rC(t,"platform");if("ios"!==a&&"android"!==a)throw new tp("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:rE(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 tp("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new tp("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 tp("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 tp("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 tp("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new tp("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rT(t,"retentionMs")}}}if(rM.has(e)){let e=rC(t,"materializationId")?.trim();if(!e)throw new tp("INVALID_ARGS","Invalid params: materializationId is required");return{token:rE(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:rE(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:rT(t,"ttlMs"),leaseBackend:rC(t,"backend")}};throw new tp("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rk.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},W(o);let d=()=>{i.writableFinished||eH(o)};e.on("aborted",d),i.on("close",d);let u=await r$(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=tf(t);rR(i,rL(a.id??null,-32e3,e.message,e),rO(e.code))}finally{eQ(o)}})})}async function rG(e,t,r,i){try{var n;let o,s,l=rE({},e.headers),d=rj(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 r$(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await rN(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=a.randomUUID(),(s=setTimeout(()=>{rv(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=tf(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,a){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=rE({},e.headers),s=rj(o,a);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 r$(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 tp("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tp("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw rg(e),new tp("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=i.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=tf(e);t.statusCode=rO(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&rg(n)}),u.pipe(t)}catch(r){let e=tf(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 rj(e,t){return t&&e!==t?tf(new tp("UNAUTHORIZED","Invalid token")):null}function rq(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rH(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rB(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";if("ios-instance"===t||"android-instance"===t)return t;throw new tp("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rz{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=rB(e.backend),r=eb(e.tenantId);if(!r)throw new tp("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rq(e.runId);if(!i)throw new tp("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,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:a.randomBytes(16).toString("hex"),tenantId:r,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=rH(e.leaseId);if(!t)throw new tp("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new tp("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=rH(e.leaseId);if(!t)throw new tp("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=rB(e.backend),r=eb(e.tenantId);if(!r)throw new tp("INVALID_ARGS","tenant isolation requires tenant id.");let a=rq(e.runId);if(!a)throw new tp("INVALID_ARGS","tenant isolation requires run id.");let i=rH(e.leaseId);if(!i)throw new tp("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new tp("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new tp("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 tp("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 tp("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=eb(t),i=rq(r);if(t&&!a)throw new tp("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new tp("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 tp("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rK=ek(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rW=new Map;async function rJ(e){let t=await f.mkdtemp(o.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await rY(e.installablePath,o.join(t,"installable")),i=e.archivePath?await rY(e.archivePath,o.join(t,"archive")):void 0,n=a.randomUUID(),s=e.ttlMs??rK,l=Date.now()+s,d=setTimeout(()=>{rZ(n)},s);return rW.set(n,{rootPath:t,installablePath:r,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:n,installablePath:r,...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 tp("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tp("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 rX(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 rY(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=o.join(t,o.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 tp("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await eZ(e.session.device),e.session.device}if(!r)throw new tp("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await ep(e.flags??{});return await eZ(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 tp("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new tp("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new tp("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:ry(o,t.meta?.tenantId)},cleanup:()=>{rv(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 tp("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(!Q("install",d))return eK("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("./641.js"),{prepareIosInstallArtifact:o}=await import("./641.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 tp("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=$(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("./641.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./641.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 tp("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./641.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=$(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:tf(e)}}}function r1(e){return`Installed: ${g(e)}`}async function r2(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new tp("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:tf(e)}}}let r4=ek(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r3=ek(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r5(e,t,r){return t||r8(r)?null:eK("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 r9(e,t){r6(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function r7(e){let t=r8(e.flags)||!e.session?await ep(e.flags??{}):await ae(e.session.device);return!1!==e.ensureReady&&await eZ(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 ep(t)}catch(e){if(!(e instanceof tp)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await ep({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=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function aa(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ai(e){let t=e?.trim();return t&&t.length>0?t:void 0}function an(e,t){if(void 0!==e){if("string"!=typeof e)throw new tp("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return ai(e)}}function ao(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new tp("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function as(e){if("ios"===e||"android"===e)return e}async function al(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!M(r)||M(a)||await eh({device:i.device,appId:i.appBundleId})}async function ad(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 eK("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){M(l)&&s?.appBundleId&&await eh({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=as(w(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return eK("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 eK("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:ai(t?.metroHost),metroPort:ao(t?.metroPort),bundleUrl:ai(t?.bundleUrl),launchUrl:ai(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===aa(u)?eK("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 au="open-command-roundtrip",ac="Not implemented for this platform in this release.",af=new Set(["app","desktop","frontmost-app"]);async function ap(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await e5();return{appBundleId:t.bundleId,appName:t.appName}}async function am(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return em(t)?"macos"===e.platform?void 0:"device"===e.kind?eB(r,t):void 0:await ah(e,t)}async function ah(e,t){try{let{resolveIosApp:r}=await import("./641.js");return await r(e,t)}catch{return}}async function ag(e,t){if(!("android"!==e.platform||!t||em(t)))try{let{resolveAndroidApp:r}=await import("./641.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function aw(e,t,r,a){return await am(e,t,r)??await a(e,t)??("android"===e.platform&&t&&em(t)?r:void 0)}function ay(e){return eK("INVALID_ARGS",e)}function av(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=tr(r);if(!af.has(e))throw new tp("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new tp("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new tp("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?tr(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new tp("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return eK(e instanceof tp?e.code:"INVALID_ARGS",String(e.message))}}function aI(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&em(r)?ay("open --relaunch does not support URL targets."):"app"!==a?ay("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===el(r)?ay(eG(r)):null:null}async function aS(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await eZ(i);let{appBundleId:l,appName:d}=await aA({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 tp("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ar.includes(e));if(i)throw new tp("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ar.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new tp("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new tp("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:an(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new tp("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return ao(e)}}(t.metroPort),bundleUrl:an(t.bundleUrl,"bundleUrl"),launchUrl:an(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:as(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=as(i);if(a.platform&&r&&!n)throw new tp("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 tp("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&&aa(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=tc(t);return eK(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 al({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function aA(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await ap(r);return{appBundleId:n.appBundleId??await aw(t,a,i,ag),appName:n.appName??a}}let ab=new Map;async function a_(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await G(t.id),await I(t,"close",[r],a,i),await r9(t,r4)}async function aN(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||em(d)||await I(r,"open",[l],a.flags?.out,{...eP(i,a.flags,n,o)})}async function ak(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 a_({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eP(s,i.flags,p??h?.appBundleId,w)}})}await er({device:l,appId:p,runtime:m});let y=Date.now();await I(l,"open",u,i.flags?.out,{...eP(s,i.flags,p)}),await aN({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:au,appTarget:d,appBundleId:p}:void 0;if(await r9(l,r3),eO(i.meta?.requestId)){let e=z();return eK(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===aa(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,...ee(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:v,device:l,runtime:m,runtimeHintCount:aa});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 eK("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=av(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?ay("open --relaunch requires an app name or an active session app."):ay("Session already active. Close it first or pass a new --session name.");let d=aI({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await ae(e.device),c=await aS({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await ak({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 ay("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&em(r)?ay("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===el(r)?ay(eG(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await ep(t.flags??{}),d=av(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=aI({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await ea(ab,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return eK("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await aS({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await ak({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 aM(e){let t=await tu("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 aD(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 aM(t)}catch(t){let e=tf(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aP(e){if(await G(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eu("dismiss",t).catch(t=>{e2({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aL(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return eK("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 aP(n),await I(n.device,"close",t.positionals,t.flags?.out,{...eP(a,t.flags,n.appBundleId,n.trace?.outPath)}),await r9(n.device,r4)),("ios"===n.device.platform||"macos"===n.device.platform)&&await aP(n),M(i.getRuntimeHints(r))&&n.appBundleId&&await eh({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...ee(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rX(r).catch(()=>{}),i.delete(r);let o=await aD({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:$({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...ee(`Closed: ${r}`)}}}let aR=["platform","target","device","udid","serial","verbose","out"];function aO(e,t){let r=e??{};for(let e of aR)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aE={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./641.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./641.js");return await a(e,t,r)}},aC={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./641.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("./641.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aT(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},d=r5(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return eK("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,a=f?ry(f,t.meta?.tenantId):tC.expandHome(c);if(!i.existsSync(a))return eK("INVALID_ARGS",`App binary not found: ${a}`);let d=await r7({session:s,flags:l,ensureReady:!1});if(!Q(r,d))return eK("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=$(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&&rv(f)}}async function a$(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return eK("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??es;if(!Number.isInteger(i)||i<1||i>1e3)return eK("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 aF(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=tc(t);return eK(e.code,e.message,e.details)}}async function aF(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aO(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:void 0===r.runtime?e.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 aU(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new tp("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await aG({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aV({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aj(t,u),a=!0)}else t=(await aV({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aj(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 aG(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await tu("xcrun",v(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:e8});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||aq(a).includes(aq(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 aV(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await tu("xcrun",v(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new tp("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 tp("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aj(e,t){let r=await tu("xcrun",v(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:e8});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 aq(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aH(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=eq(e.iosSimulatorDeviceSet);if(!r)return eK("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await aU({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:eZ});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=tc(t);return eK(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=ta(t.flags?.androidDeviceAllowlist),a=w(t.flags?.platform),i=S({simulatorSetPath:eq(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./641.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./641.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./641.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./641.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=tc(t);return eK(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r5(t.command,e,i);if(n)return n;let o=await r7({session:e,flags:i,ensureReady:!0});if(!Q("apps",o))return eK("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(L(o.platform)){let{listIosApps:e}=await import("./641.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("./641.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 aB(e){let{ensureAndroidEmulatorBooted:t}=await import("./641.js");return await t(e)}let az='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',aK='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function aW(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 eK("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=r5("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&&!e7(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 eK("SESSION_NOT_FOUND",az);if("macos"===o&&!l)return eK("SESSION_NOT_FOUND",aK);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 eK("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 r7({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return eK("SESSION_NOT_FOUND",az);if("macos"===d.platform)return eK("SESSION_NOT_FOUND",aK);let{getAndroidAppState:u}=await import("./641.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function aJ(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r5(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 eK("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 r7({session:i,flags:n,ensureReady:!1})}catch(r){let t=tc(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return eK("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 aB({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return eK("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return eK("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 eK("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aB({avdName:t,serial:n.serial,headless:!0})}await eZ(e)}else("android"!==e.platform||!0!==e.booted)&&await eZ(e);return Q("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:eK("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await aW({req:t,sessionName:r,sessionStore:a}):null}function aZ(e){return Math.round(10*e)/10}let aX="adb-shell-dumpsys-cpuinfo",aY="adb-shell-dumpsys-meminfo";async function aQ(e,t){try{let r=await tu("adb",eC(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:aZ(i),measuredAt:r,method:aX,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw a1("cpu",t,e)}}async function a0(e,t){try{let r=await tu("adb",eC(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new tp("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=a2(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!==a4(e));if(!r)break;return a4(r)??void 0}}(e);if(void 0===a)throw new tp("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:a2(e,"TOTAL RSS"),measuredAt:r,method:aY}}(r.stdout,t,new Date().toISOString())}catch(e){throw a1("memory",t,e)}}function a1(e,t,r){return r instanceof tp&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new tp(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof tp?r:new tp("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a2(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a4(a[1])??void 0}function a4(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a3="ps-process-snapshot",a5="ps-process-snapshot",a8="xctrace-activity-monitor",a6="xctrace-activity-monitor";async function a9(e,t){if("ios"===e.platform&&"device"===e.kind)return await it(e,t);let r=await ie(e,t),a=await il(e,r);if(0===a.length)throw new tp("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(),n=th(a.map(e=>o.basename(id(e.command))));return iu({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:n,cpuMethod:a3,memoryMethod:a5})}async function a7(e){let t=e4(e),r=ic(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new tp("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 tp("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=ic(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:ip(e),processName:ih(e)})}let r=im(t[i],u),a=(c=t[n],f=u,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:ih(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:im(t[o],u),residentMemoryBytes:im(t[s],u)})}return d}async function ie(e,t){let r="macos"===e.platform?await io(t):await is(e,t),a="macos"===e.platform?o.join(r,"Contents","Info.plist"):o.join(r,"Info.plist"),i=await eY(a,"CFBundleExecutable");if(!i)throw new tp("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?o.join(r,"Contents","MacOS",i):void 0}}async function it(e,t){let r=await ir(e,t),a=await ia(e,t),i=await ia(e,t),n=ii(await a7(a.xml),r,t,e),o=ii(await a7(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new tp("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 tp("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 iu({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:a8,memoryMethod:a6})}async function ir(e,t){let r=(await P(e,"all")).find(e=>e.bundleId===t);if(!r)throw new tp("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new tp("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await _(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new tp("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 ia(e,t){let r=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-ios-perf-")),a=o.join(r,"sample.trace"),i=o.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"],o=await tu("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==o.exitCode)throw new tp("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:ig(o.stdout,o.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",i],d=await tu("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new tp("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:ig(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function ii(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>o.basename(d(e.executable)))),s=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===s.length)throw new tp("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:iw(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iw(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:th(u.map(e=>e.processName))}}async function io(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await tu("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new tp("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 tp("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function is(e,t){let r=e0(e,["get_app_container",e.id,t,"app"]),a=await tu("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new tp("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 tp("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function il(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:e0(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 tu("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=id(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||o.basename(i)===a.executableName})}function id(e){let[t=""]=e.trim().split(/\s+/,1);return t}function iu(e){return{cpu:{usagePercent:aZ(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 ic(e,t){for(let r of e){if(t(r))return r;let e=ic(r.children,t);if(e)return e}}function ip(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 im(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:ip(e):null}function ih(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function ig(e,t){let r=Z(e,t);if(r)return r;let a=`${e}
6
- ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?ex: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 iw(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function iy(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===au&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:au,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:au,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:au},n={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:i,fps:{available:!1,reason:ac},memory:{available:!1,reason:ac},cpu:{available:!1,reason:ac}},sampling:{startup:{method:au,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:aY,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:aX,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:a6,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:a8,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:a5,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:a3,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 iv(e);return n.metrics.memory=iI(o),n.metrics.cpu=iI(s),n}async function iv(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([a0(e.device,t),aQ(e.device,t)]);return[r,a]}try{let r=await a9(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 iI(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=tf(e.reason);return{available:!1,reason:t.message,error:t}}let iS=["path","start","stop","doctor","mark","clear"],iA=`logs requires ${iS.slice(0,-1).join(", ")}, or ${iS.at(-1)}`,ib=["dump","log"],i_=`network requires ${ib.join(" or ")}`,iN=["summary","headers","body","all"],ik=`network include mode must be one of: ${iN.join(", ")}`;async function ix(e){let{req:t}=e;return"perf"===t.command?iM(e):"logs"===t.command?iD(e):"network"===t.command?iE(e):null}async function iM(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return eK("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await iy(a)}}catch(e){return{ok:!1,error:tf(e)}}}async function iD(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return eK("SESSION_NOT_FOUND","logs requires an active session");if(!Q("logs",n.device))return eK("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return iS.includes(o)?s&&"clear"!==o?eK("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===o?function(e,t,r){let a=r.resolveAppLogPath(t),n=function(e){if(!i.existsSync(e))return{exists:!1,sizeBytes:0};let t=i.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(a);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:n.sizeBytes,modifiedAt:n.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(n,r,a):"doctor"===o?iP(n,r,a):"mark"===o?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return rs(o),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
7
- `,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?iL(n,r,a,s):"start"===o?iR(n,r,a):"stop"===o?iO(n,r,a):eK("INVALID_ARGS",iA):eK("INVALID_ARGS",iA)}async function iP(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 iL(e,t,r,a){if(e.appLog&&!a)return eK("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return eK("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:tf(a)}}}async function iR(e,t,r){if(e.appLog)return eK("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return eK("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:tf(e)}}}async function iO(e,t,r){if(!e.appLog)return eK("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 iE(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eK("SESSION_NOT_FOUND","network requires an active session");if(!Q("network",i.device))return eK("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!ib.includes(n))return eK("INVALID_ARGS",i_);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return eK("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 eK("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return iN.includes(a)?{ok:!0,include:a}:eK("INVALID_ARGS",ik)}(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 iC=new Set(["ios","android","macos","linux"]);function iT(e,t,r){let a=e[t];if(void 0!==a)throw new tp("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 i$(e){return!!e&&!Number.isNaN(Number(e))}let iF=/[*?[\]{}]/;async function iU(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;W(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=tc(e);return eK(t.code,t.message)}).finally(()=>{eQ(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eH(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 iG(c)||e2({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){e2({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:tc(e).message}})}}}async function iG(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function iV(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return eK("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:a}=e,n=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tC.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>o.join(n,e));if(t.isFile()){if(".ad"!==o.extname(n))throw new tp("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!iF.test(r)&&(a=n,!iF.test(a)))throw new tp("INVALID_ARGS",`test input not found: ${e}`);let s=o.isAbsolute(n)?n:e;return i.globSync(s,{cwd:o.isAbsolute(n)?void 0:t}).map(e=>o.isAbsolute(e)?e:o.resolve(t,e)).filter(e=>".ad"===o.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>o.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&&iC.has(e)&&iT(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&iT(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&iT(r,"retries",Math.floor(e))}}return r}(i.readFileSync(e,"utf8"));if(!a){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 ${a}`});continue}d=a,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=a?` for --platform ${a}`:"";throw new tp("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tC.expandHome(t??".agent-device/test-artifacts",r);return o.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),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 i=await ij({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(I.push(i),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=tc(t);return eK(e.code,e.message)}}async function ij(e){var t,r;let a,n,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,y=Date.now(),v=o.join(h,(t=s.path,(0===(n=c?o.relative(c,t):o.basename(t)).length||n.startsWith("..")?o.basename(t):n).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 n=o.basename(r,o.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),n=o.join(v,`attempt-${S}`);r=s.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,o.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eE(`${t??r}:test:${i+1}:${o.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await iU({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:a,attempts:n,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=[],a=new Map;for(let n of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=o.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}`}(o.basename(n),a),s=o.join(t,e);o.resolve(n)!==o.resolve(s)&&i.copyFileSync(n,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${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=>o.basename(e)).join(", ")}`);let f=o.join(l,"result.txt"),p=`${c.join("\n")}
8
- `;i.writeFileSync(f,p),t.ok||i.writeFileSync(o.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:S,maxAttempts:p+1,attemptArtifactsDir:n}),a=h,I=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:s.path,session:I,status:"passed",durationMs:A,attempts:S,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let b=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:I,status:"failed",durationMs:A,attempts:S,artifactsDir:v,error:b}}function iq(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=V(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 iH(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(tS(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),tS(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}=eR(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=iq(e.positionals??[]);r&&t.push(r)}return th(t).filter(e=>e.trim().length>0)})(t).map(e=>eF(e)).filter(e=>null!==e);if(0===o.length)return null;let s=tS(t.command)||"fill"===t.command,l=tS(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await iB(n,t,a,s,i);for(let e of o){let r=q(d.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=H(r.node,n.device.platform,{action:tS(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tS(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=tm(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}=eR(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}=iq(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function iB(e,t,r,a,i){let n=await I(e.device,"snapshot",[],t.flags?.out,{...eP(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:N(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 iz(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o}=e,s=t.positionals?.[0];if(!s)return eK("INVALID_ARGS","replay requires a path");let l="",d=new Set;try{l=tC.expandHome(s,t.meta?.cwd);let e=i.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return eK("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 tp("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(tS(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 i$(r)&&i$(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}if("--quality"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.quality=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 i=c[e];if(!i||"replay"===i.command)continue;let s=await iK({req:t,sessionName:r,action:i,invoke:o});if(s.ok){iJ(s).forEach(e=>d.add(e));continue}if(!f)return iW(s,i,e,l,[...d]);let u=await iH({action:i,sessionName:r,logPath:a,sessionStore:n});if(!u)return iW(s,i,e,l,[...d]);if(c[e]=u,!(s=await iK({req:t,sessionName:r,action:u,invoke:o})).ok)return iW(s,u,e,l,[...d]);iJ(s).forEach(e=>d.add(e)),p+=1}return f&&p>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${t_(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tb(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tE(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tN(r,tx));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(tb(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}for(let r of e.positionals??[])t.push(tb(r));return tM(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
9
- `,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=tc(t);return eK(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function iK(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,aO(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function iW(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=>tb(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 iJ(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 i.statSync(e).isFile()}catch{return!1}})(e)))]}async function iZ(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await iz({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await iV({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await iz({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&&iJ(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await aL({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let iX=new Set(["session_list","ensure-simulator","devices","apps"]),iY=new Set(["boot","appstate"]),iQ=new Set(["perf","logs","network"]),i0=new Set(["replay","test"]);async function i1(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=r5(n,d,u);if(c)return c;let f=await r7({session:d,flags:u,ensureReady:!0});if(!Q(n,f))return eK("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await I(f,n,o,t.flags?.out,{...eP(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 i2(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r5("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return eK("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await r7({session:n,flags:o,ensureReady:!0});if(!Q("clipboard",d))return eK("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await I(d,"clipboard",t.positionals??[],t.flags?.out,{...eP(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 i4(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(iX.has(t.command))return await aH({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await ad({req:t,sessionName:r,sessionStore:i});if(iY.has(t.command))return await aJ({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await i2({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 i1({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):eK("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(iQ.has(t.command))return await ix({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aT({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?aC:aE});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 i1({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=eT(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tC.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):eK("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await i1({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 aw(e.device,r,e.appBundleId,ag)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await ax({req:t,sessionName:r,logPath:a,sessionStore:i}):i0.has(t.command)?await iZ({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await a$(t,r,n):"close"===t.command?await aL({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function i3(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 eK("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=eg(s);if(!d)return eK("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return eK("INVALID_ARGS","find accepts only one of --first or --last");let p=await ez({req:t,sessionName:r,logPath:a,sessionStore:i});if(p)return p;let m=i.get(r);if(!m&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return eK("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await ep(t.flags??{});m||await eZ(h);let g="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,y=0,v=null,I=async()=>{let e=Date.now();if(v&&e-y<750&&!e1(m))return{nodes:v};let{snapshot:n}=await en({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return y=e,v=o,m&&(m.snapshot=n,i.set(r,m)),{nodes:o,truncated:n.truncated,backend:n.backend}},S={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:o,locator:l,query:d};if("wait"===u)return i5(S,I,l,d,f);let{nodes:A}=await I(),b=e6(A,l,d,{requireRect:w});if(w&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,k;let e;return _=b.matches,N=l,k=d,e=_.slice(0,8).map(e=>{let t=eS(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eK("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${k}". Use a more specific locator or selector.`,{locator:N,query:k,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let x=b.matches[0]??null;if(!x)return eK("COMMAND_FAILED","find did not match any element");let M="click"===u||"focus"===u||"fill"===u||"type"===u?e3(A,x)??x:x,D=`@${M.ref}`,P={node:x,resolvedNode:M,ref:D,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>i8(S),get_text:()=>i6(S,P),get_attrs:()=>i9(S,P),click:()=>i7(S,P),fill:()=>ne(S,P,c),focus:()=>nt(S,P),type:()=>nr(S,P,c)}[u];return L?L():null}async function i5(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(e6(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 eK("COMMAND_FAILED","find wait timed out")}async function i8(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 i6(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await eA({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eP(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 i9(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 i7(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?k(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 ne(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return eK("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 nt(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?k(t.node.rect):null;if(!l)return eK("COMMAND_FAILED","matched element has no bounds");let d=await I(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eP(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 nr(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return eK("INVALID_ARGS","find type requires text");let d=t.node.rect?k(t.node.rect):null;if(!d)return eK("COMMAND_FAILED","matched element has no bounds");await I(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eP(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await I(o,"type",[r],a.flags?.out,{...eP(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 na=`
1
+ let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import o from"node:path";import{spawn as s}from"node:child_process";import l from"node:http";import{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{resolveUserPath as g}from"./3267.js";import{localCommandPolicy as w,createAgentDevice as y,readVersion as v,resolveDaemonCodeSignature as S,normalizeTenantId as I,resolveSessionIsolationMode as A,withDiagnosticsScope as b,resolveDaemonPaths as _,flushDiagnosticsToSessionFile as N,getDiagnosticsMeta as k,resolveDaemonServerMode as x,resolveDeployResultTarget as M,resolveInstallFromSourceResultTarget as D,emitDiagnostic as P}from"./8564.js";import{readProcessStartTime as L,isAgentDeviceDaemonProcess as R,readProcessCommand as O}from"./3883.js";import{toAppErrorCode as C,asAppError as E,normalizeError as $,AppError as T}from"./9152.js";import{runCmdBackground as U,runCmd as F}from"./9818.js";import{sleep as G,resolveTimeoutMs as V}from"./4829.js";import{resolveIosSimulatorDeviceSetPath as j,buildSimctlArgs as q,classifyAndroidAppTarget as H,parseSerialAllowlist as B,adbArgs as K,trimRuntimeValue as z,resolveAndroidSerialAllowlist as W,clearRuntimeHintsFromApp as J,hasRuntimeTransportHints as Z,buildSimctlArgsForDevice as X,formatAndroidInstalledPackageRequiredMessage as Y,applyRuntimeHintsToApp as Q}from"./9323.js";import{IOS_RUNNER_CONTAINER_BUNDLE_IDS as ee,resolveAppleSimulatorSetPathForSelector as et,dispatchCommand as er,validateAndNormalizeBatchSteps as ea,refSnapshotFlagGuardResponse as ei,buttonTag as en,handleSnapshotCommands as eo,shutdownSimulator as es,stopIosRunnerSession as el,getClickButtonValidationError as ed,createRequestCanceledError as eu,registerRequestAbort as ec,isNavigationSensitiveAction as ef,resolveIosDevicectlHint as ep,snapshotAndroid as em,resolveTargetDevice as eh,assertAndroidPressStayedInApp as eg,stopAllIosRunnerSessions as ew,withKeyedLock as ey,dispatchGetViaRuntime as ev,DEFAULT_BATCH_MAX_STEPS as eS,getAndroidAppState as eI,runMacOsAlertAction as eA,getAndroidScreenSize as eb,isDeepLinkTarget as e_,readTextForNode as eN,captureSnapshot as ek,dispatchIsViaRuntime as ex,resolveClickButton as eM,IOS_DEVICECTL_DEFAULT_HINT as eD,buildSnapshotState as eP,openAndroidApp as eL,context_contextFromFlags as eR,captureSnapshotData as eO,isRequestCanceled as eC,resolveRequestTrackingId as eE,resolvePayloadInput as e$,abortAllIosRunnerSessions as eT,getRunnerSessionSnapshot as eU,createUnsupportedArtifactAdapter as eF,isAndroidEscapeError as eG,markRequestCanceled as eV,resolveIosDeviceDeepLinkBundleId as ej,parseCoordinateTarget as eq,response_errorResponse as eH,runIosRunnerCommand as eB,dispatchFindReadOnlyViaRuntime as eK,ensureDeviceReady as ez,readInfoPlistString as eW,clearRequestCanceled as eJ,getActiveAndroidSnapshotFreshness as eZ,parseXmlDocumentSync as eX,resolveFrontmostMacOsApp as eY,IOS_SIMCTL_LIST_TIMEOUT_MS as eQ,listIosDeviceApps as e0,matchesPlatformSelector as e1,isCommandSupportedOnDevice as e2,isApplePlatform as e3,parseSessionSurface as e8,normalizePlatformSelector as e4,getRequestSignal as e5,markAndroidSnapshotFreshness as e9,buildScrollGesturePlan as e6,listIosDeviceProcesses as e7}from"./3918.js";import{withSuccessText as te,decodePng as tt,successText as tr}from"./9076.js";import{splitSelectorFromArgs as ta,findNearestHittableAncestor as ti,extractNodeText as tn,splitIsSelectorArgs as to,tryParseSelectorChain as ts,resolveSelectorChain as tl,resolveRefLabel as td,buildSelectorChainForNode as tu,normalizeType as tc,pruneGroupNodes as tf}from"./7847.js";import{attachRefs as tp,centerOfRect as tm}from"./4057.js";import{findBestMatchesByLocator as th,parseFindArgs as tg}from"./7556.js";function tw(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function ty(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tv=/^-?\d+(\.\d+)?$/,tS=/^[^\s"\\]+$/,tI=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tA=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tb=new Map([["--delay-ms","delayMs"]]);function t_(e){return"click"===e||"press"===e}function tN(e){return"type"===e||"fill"===e}function tk(e){return tM(e,tD)}function tx(e){return JSON.stringify(e)}function tM(e,t){return t(e)?e:tx(e)}function tD(e){return tP(e)&&e.startsWith("@")||tv.test(e)}function tP(e){return tS.test(e)}function tL(e,t){let r=t.flags??{};if(t_(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}tN(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tR(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",tM(t.metroHost,tP)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tM(t.bundleUrl,tP)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tM(t.launchUrl,tP)))}function tO(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tM(r,tP)),a))e.push(tk(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}function tC(e,t){let r=[],a={},i=t_(e)?tI:"swipe"===e?tA:tN(e)?tb:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(t_(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(t_(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=t$(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 tE(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=t$(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 t$(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tT(e,t){for(let r of t.positionals??[])e.push(tk(r));t.flags?.relaunch&&e.push("--relaunch"),tR(e,t.runtime)}class tU{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=tU.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 tF)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),P({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=o.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a=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(t_(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)),tL(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tk(r)),tL(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)),tL(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"),"number"==typeof e.flags?.screenshotMaxSize&&t.push("--max-size",String(e.flags.screenshotMaxSize)),t.join(" ")}if("open"===e.command)return tT(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tM(r,tP)),tR(t,e.flags),t.join(" ")}if("record"===e.command)return tO(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tk(r));return tL(t,e),t.join(" ")}(i));return`${r.join("\n")}
2
+ `}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=tU.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return o.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return o.join(this.sessionsDir,tU.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return o.join(this.sessionsDir,tU.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return g(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tU.expandHome(e.saveScriptPath);i.existsSync(this.sessionsDir)||i.mkdirSync(this.sessionsDir,{recursive:!0});let t=tU.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return o.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&&(t_(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(t_(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=tw(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(t_(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 tF=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw","screenshotFullscreen","screenshotMaxSize","relaunch","saveScript","noRecord","fps","quality","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"],tG="app-log.pid";function tV(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 tj(e,t){if(!e)return;let r=o.dirname(e);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:L(t)??void 0,command:O(t)??void 0};i.writeFileSync(e,`${JSON.stringify(a)}
3
+ `)}function tq(e){if(e&&i.existsSync(e))try{i.unlinkSync(e)}catch{}}async function tH(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}function tB(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 tK(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 T("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tW(e,t){let r=(await F("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tJ(e,t){var r,a;let i;tz(t);let n=await tW(e,t),o=await F("adb",["-s",e,"logcat","-d","-v","time","-t","4000"],{allowFailure:!0,timeoutMs:3e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=function(e,t,r){let a=new Set;for(let 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 tZ(e,t,r,a,i){let n,o,l="recovering",d=!1,u=(async()=>{try{for(;!d;){let u=await tW(e,t);if(!u){l="recovering",await G(1e3);continue}let c=s("adb",["-s",e,"logcat","-v","time","--pid",u],{stdio:["ignore","pipe","pipe"]});n=c;let f=tB(r,{redactionPatterns:a});if(o=tK(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&(tj(i,c.pid),l="active"),await o,tq(i),n=void 0,o=void 0,d)break;l="recovering",await G(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tq(i)}})();return{backend:"android",getState:()=>l,startedAt:Date.now(),wait:u,stop:async()=>{d=!0,n&&!n.killed&&n.kill("SIGINT"),o&&await tH(o),n&&!n.killed&&n.kill("SIGKILL"),await tH(u),tq(i)}}}function tX(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function tY(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=q(["spawn",t,"log","show","--style","compact","--info","--predicate",tX(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 F("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 tQ(e,t,r,a,i,n){let o="active",l=s("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return q(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tX(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tB(r,{redactionPatterns:a});"number"==typeof l.pid&&tj(n,l.pid);let u=tK(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(o="failed"),tq(n),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tH(u),l.killed||l.kill("SIGKILL"),await tH(u),tq(n)}}}async function t0(e,t,r,a){let i="active",n=s("log",["stream","--style","compact","--predicate",tX(e)],{stdio:["ignore","pipe","pipe"]}),o=tB(t,{redactionPatterns:r});"number"==typeof n.pid&&tj(a,n.pid);let l=tK(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tq(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tH(l),n.killed||n.kill("SIGKILL"),await tH(l),tq(a)}}}async function t1(e,t,r,a){let i="active",n=s("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tB(t,{redactionPatterns:r});"number"==typeof n.pid&&tj(a,n.pid);let l=tK(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tq(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tH(l),n.killed||n.kill("SIGKILL"),await tH(l),tq(a)}}}let t2=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),t3=/https?:\/\/[^\s"'<>\])]+/i,t8=[/\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 t4(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t9(e)));for(let e of t.entries){let t=t9(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t5(e,t){let r=rs(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=rs(t?.maxPayloadChars,2048,64,16384),o=rs(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=ra(s,["method","httpMethod"]),d=ra(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=t2.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=t3.exec(o),h=d??m?.[0];if(!h)return null;let g=u??t7(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:re(o),packetId:rt(o)??void 0,durationMs:rr(o)??void 0,raw:ro(o,n),line:r};if("android"===a&&function(e,t,r){let a=t6(t,r,5),i=e.packetId??a.map(e=>rt(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t6(t,r,12).filter(e=>rt(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>re(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>t7(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>rr(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 rn(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=ro(e,n))}if("body"===i||"all"===i){let e=ri(o,s,["requestBody","body","payload","request"]),t=ri(o,s,["responseBody","response"]);e&&(w.requestBody=ro(e,n)),t&&(w.responseBody=ro(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 t9(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function t6(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 t7(e){for(let t of t8){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function re(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 rt(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function rr(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 ra(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 ri(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return rn(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 rn(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ro(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function rs(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function rl(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 rd(e){let t=o.dirname(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),function(e,t){if(i.existsSync(e)&&!(i.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;i.existsSync(t)&&(i.existsSync(a)&&i.unlinkSync(a),i.renameSync(t,a))}}(e,{maxBytes:rl("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:rl("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function ru(e){var t,r,a,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",S=(t={backend:v,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y},o=rs(t?.maxEntries,25,1,200),s=t?.include??"summary",l=rs(t?.maxPayloadChars,2048,64,16384),d=rs(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?t5(i.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:d}}),I=[],A=await rc({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tJ(u.id,c);if(e){let t=t5(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(S=t4(t,S,h),I.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===S.entries.length){let e=await rp({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});e&&(e.dump.entries.length>0?(S=t4(e.dump,S,h),I.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&&I.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?I.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===I.length&&("ios"===u.platform&&"simulator"===u.kind?I.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."):I.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===S.entries.length&&I.push("ios"===(n=u).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:S,notes:I}}async function rc(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tV(i.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}(o.join(o.dirname(a),tG));if(!s)return null;let l=await tW(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function rf(e,t,r,a){rd(r);let n=i.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 t1(e.id,n,o,a):await tQ(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return tz(t),await tZ(e.id,t,n,o,a);if("macos"===e.platform)return await t0(t,n,o,a);throw n.end(),new T("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rp(e){let t=await tY({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t5(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 rm(e){await e.stop(),await tH(e.wait)}async function rh(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await F("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await F("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await F("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await F("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await F("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rg(e){let t=o.dirname(e),r=o.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let a=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{i.unlinkSync(o.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rw=new Map;function ry(e){let t=rw.get(e);if(t&&(clearTimeout(t.timer),rw.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rv=new Map;function rS(e,t){let r=rv.get(e);if(!r)throw new T("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rI(e){let t=rv.get(e);t&&(clearTimeout(t.timer),rv.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rA(e){let t=await rb(e);await F("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=o.join(e.tempDir,t);if(!i.existsSync(r))throw new T("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rb(e){let t=await F("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new T("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 T("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(r_),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 T("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new T("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 T("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 T("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 T("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await F("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new T("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function r_(e){if(e.includes("\0"))throw new T("INVALID_ARGS",`Invalid archive entry: ${e}`);if(o.posix.isAbsolute(e))throw new T("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=o.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new T("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rN=V(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function rk(e,t){return new Promise((r,a)=>{let n,o=i.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(),i.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new T("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rN});s(e),o.destroy(e),u(e)},rN)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new T("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 T("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",u),o.on("finish",()=>u()),c(),e.pipe(o)})}async function rx(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new T("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new T("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 T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=o.basename(t);if(!r||"."===r||".."===r)throw new T("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),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"),i.mkdtempSync(o.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=o.join(s,n);return await rk(e,t),{artifactPath:t,tempDir:s}}let t=o.join(s,"artifact.tar");await rk(e,t);let a=await rA({archivePath:t,tempDir:s,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:s}}catch(e){throw i.rmSync(s,{recursive:!0,force:!0}),e}}let rM=new Set(["agent_device.command","agent-device.command"]),rD=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rP=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rL={"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"},rR=new Set([...rM,...rD,...rP,...Object.keys(rL)]);function rO(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rC(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rE(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 rT(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rU(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function rF(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=$(new T("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rO(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=$(new T(C(r.code,"UNAUTHORIZED"),r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rO(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=I(r.tenantId);if(!e){let e=$(new T("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rO(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rG(){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=o.isAbsolute(t)?t:o.resolve(t);try{e=await import(u(a).href)}catch(e){throw new T("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 T("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rV(e){let t=await rG(),{handleRequest:r,token:a}=e;return l.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 rj(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void rq(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||rC(i,rO(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rC(i,rO(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rC(i,rO(a.id??null,-32600,"Invalid Request"),400);if(!rR.has(a.method))return void rC(i,rO(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rC(i,rO(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(rM.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(rD.has(e)){let e,a=rT(t,"platform");if("ios"!==a&&"android"!==a)throw new T("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:r$(t,r),session:rT(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rT(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new T("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 T("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 T("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 T("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new T("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rU(t,"retentionMs")}}}if(rP.has(e)){let e=rT(t,"materializationId")?.trim();if(!e)throw new T("INVALID_ARGS","Invalid params: materializationId is required");return{token:r$(t,r),session:rT(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rT(t,"requestId"),materializationId:e}}}let a=rL[e];if(a)return{token:r$(t,r),session:rT(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rT(t,"tenantId")??rT(t,"tenant"),runId:rT(t,"runId"),leaseId:rT(t,"leaseId"),leaseTtlMs:rU(t,"ttlMs"),leaseBackend:rT(t,"backend")}};throw new T("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rM.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rC(i,rO(a.id??null,-32602,"Invalid params: command is required"),400);o=eE(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},ec(o);let d=()=>{i.writableFinished||eV(o)};e.on("aborted",d),i.on("close",d);let u=await rF(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rC(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 rC(i,{jsonrpc:"2.0",id:a.id??null,result:c});rC(i,rO(a.id??null,-32e3,c.error.message,c.error),rE(c.error.code))}catch(t){let e=$(t);rC(i,rO(a.id??null,-32e3,e.message,e),rE(e.code))}finally{eJ(o)}})})}async function rj(e,t,r,i){try{var n;let o,s,l=r$({},e.headers),d=rH(l,i);if(d){t.statusCode=rE(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await rF(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await rx(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=a.randomUUID(),(s=setTimeout(()=>{rI(o)},3e5)).unref(),rv.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=$(r);t.statusCode=rE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rq(e,t,r,a){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=rH(o,a);if(s){t.statusCode=rE(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await rF(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=rw.get(e);if(!r)throw new T("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw ry(e),new T("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=i.createReadStream(d.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),d.fileName&&t.setHeader("content-disposition",`attachment; filename="${d.fileName.replace(/"/g,"")}"`),u.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=$(e);t.statusCode=rE(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&ry(n)}),u.pipe(t)}catch(r){let e=$(r);t.statusCode=rE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rH(e,t){return t&&e!==t?$(new T("UNAUTHORIZED","Invalid token")):null}function rB(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rK(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";if("ios-instance"===t||"android-instance"===t)return t;throw new T("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rW{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),r=I(e.tenantId);if(!r)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rB(e.runId);if(!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,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:a.randomBytes(16).toString("hex"),tenantId:r,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=rK(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new T("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=rK(e.leaseId);if(!t)throw new T("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=I(e.tenantId);if(!r)throw new T("INVALID_ARGS","tenant isolation requires tenant id.");let a=rB(e.runId);if(!a)throw new T("INVALID_ARGS","tenant isolation requires run id.");let i=rK(e.leaseId);if(!i)throw new T("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new T("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 T("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 T("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=I(t),i=rB(r);if(t&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new T("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 T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rJ=V(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rZ=new Map;async function rX(e){let t=await f.mkdtemp(o.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await r0(e.installablePath,o.join(t,"installable")),i=e.archivePath?await r0(e.archivePath,o.join(t,"archive")):void 0,n=a.randomUUID(),s=e.ttlMs??rJ,l=Date.now()+s,d=setTimeout(()=>{rY(n)},s);return rZ.set(n,{rootPath:t,installablePath:r,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:n,installablePath:r,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await f.rm(t,{recursive:!0,force:!0}),e}}async function rY(e,t){let r=rZ.get(e);if(!r)throw new T("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rZ.delete(e),await f.rm(r.rootPath,{recursive:!0,force:!0})}async function rQ(e){let t=Array.from(rZ.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await rY(e)}))}async function r0(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=o.join(t,o.basename(e));return r.isDirectory()?await f.cp(e,a,{recursive:!0}):await f.copyFile(e,a),a}async function r1(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 T("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await ez(e.session.device),e.session.device}if(!r)throw new T("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await eh(e.flags??{});return await ez(a),a}async function r2(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 T("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new T("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new T("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:rS(o,t.meta?.tenantId)},cleanup:()=>{rI(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 T("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await r1({session:i,flags:t.flags});if(!e2("install",d))return eH("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=e5(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:n}=await import("./3918.js"),{prepareIosInstallArtifact:o}=await import("./3918.js"),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await rX({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 T("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=te(o,r3(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await rY(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./3918.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./3918.js"),p=await c(s.source,{signal:u});try{l.enabled&&(e=await rX({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 T("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./3918.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=te(u,r3(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await rY(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:$(e)}}}function r3(e){return`Installed: ${D(e)}`}async function r8(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new T("INVALID_ARGS","release_materialized_paths requires a materializationId");return await rY(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:$(e)}}}let r4=V(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r5=V(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r9(e,t,r){return t||r6(r)?null:eH("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function r6(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function r7(e){return"ios"===e.platform&&"simulator"===e.kind}async function ae(e,t){r7(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function at(e){let t=r6(e.flags)||!e.session?await eh(e.flags??{}):await ar(e.session.device);return!1!==e.ensureReady&&await ez(t),t}async function ar(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 eh(t)}catch(e){if(!(e instanceof T)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await eh({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function aa(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 ai=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function an(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ao(e,t){if(void 0!==e){if("string"!=typeof e)throw new T("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return z(e)}}function as(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new T("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function al(e){if("ios"===e||"android"===e)return e}async function ad(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!Z(r)||Z(a)||await J({device:i.device,appId:i.appBundleId})}async function au(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 eH("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){Z(l)&&s?.appBundleId&&await J({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=al(e4(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return eH("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 eH("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:z(t?.metroHost),metroPort:as(t?.metroPort),bundleUrl:z(t?.bundleUrl),launchUrl:z(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===an(u)?eH("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",af="Not implemented for this platform in this release.",ap=new Set(["app","desktop","frontmost-app"]);async function am(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eY();return{appBundleId:t.bundleId,appName:t.appName}}async function ah(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return e_(t)?"macos"===e.platform?void 0:"device"===e.kind?ej(r,t):void 0:await ag(e,t)}async function ag(e,t){try{let{resolveIosApp:r}=await import("./3918.js");return await r(e,t)}catch{return}}async function aw(e,t){if(!("android"!==e.platform||!t||e_(t)))try{let{resolveAndroidApp:r}=await import("./3918.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function ay(e,t,r,a){return await ah(e,t,r)??await a(e,t)??("android"===e.platform&&t&&e_(t)?r:void 0)}function av(e){return eH("INVALID_ARGS",e)}function aS(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=e8(r);if(!ap.has(e))throw new T("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new T("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new T("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?e8(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new T("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return eH(e instanceof T?e.code:"INVALID_ARGS",String(e.message))}}function aI(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&e_(r)?av("open --relaunch does not support URL targets."):"app"!==a?av("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===H(r)?av(Y(r)):null:null}async function aA(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await ez(i);let{appBundleId:l,appName:d}=await ab({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 T("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ai.includes(e));if(i)throw new T("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ai.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new T("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new T("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:ao(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new T("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return as(e)}}(t.metroPort),bundleUrl:ao(t.bundleUrl,"bundleUrl"),launchUrl:ao(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:al(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=al(i);if(a.platform&&r&&!n)throw new T("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 T("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&&an(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=E(t);return eH(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 ad({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function ab(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await am(r);return{appBundleId:n.appBundleId??await ay(t,a,i,aw),appName:n.appName??a}}let a_=new Map;async function aN(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await el(t.id),await er(t,"close",[r],a,i),await ae(t,r4)}async function ak(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||e_(d)||await er(r,"open",[l],a.flags?.out,{...eR(i,a.flags,n,o)})}async function ax(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 aN({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eR(s,i.flags,p??h?.appBundleId,w)}})}await Q({device:l,appId:p,runtime:m});let y=Date.now();await er(l,"open",u,i.flags?.out,{...eR(s,i.flags,p)}),await ak({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:ac,appTarget:d,appBundleId:p}:void 0;if(await ae(l,r5),eC(i.meta?.requestId)){let e=eu();return eH(e.code,e.message,e.details)}h&&e9(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===an(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let I=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,...tr(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:v,device:l,runtime:m,runtimeHintCount:an});return o.recordAction(S,{command:"open",positionals:u,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:I}),o.set(n,S),{ok:!0,data:I}}async function aM(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return eH("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=aS(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?av("open --relaunch requires an app name or an active session app."):av("Session already active. Close it first or pass a new --session name.");let d=aI({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await ar(e.device),c=await aA({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await ax({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 av("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&e_(r)?av("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===H(r)?av(Y(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await eh(t.flags??{}),d=aS(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=aI({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await ey(a_,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return eH("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await aA({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await ax({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 aD(e){let t=await F("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function aP(e){let{device:t,shutdownRequested:r}=e;if(r&&(r7(t)||"android"===t.platform&&"emulator"===t.kind))try{return r7(t)?await es(t):await aD(t)}catch(t){let e=$(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aL(e){if(await el(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eA("dismiss",t).catch(t=>{P({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aR(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");n.appLog&&await rm(n.appLog),t.positionals&&t.positionals.length>0&&(e3(n.device.platform)&&await aL(n),await er(n.device,"close",t.positionals,t.flags?.out,{...eR(a,t.flags,n.appBundleId,n.trace?.outPath)}),await ae(n.device,r4)),e3(n.device.platform)&&await aL(n),Z(i.getRuntimeHints(r))&&n.appBundleId&&await J({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...tr(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rQ(r).catch(()=>{}),i.delete(r);let o=await aP({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:te({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...tr(`Closed: ${r}`)}}}let aO=["platform","target","device","udid","serial","verbose","out"];function aC(e,t){let r=e??{};for(let e of aO)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aE={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./3918.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./3918.js");return await a(e,t,r)}},a$={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./3918.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("./3918.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aT(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},d=r9(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return eH("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,a=f?rS(f,t.meta?.tenantId):tU.expandHome(c);if(!i.existsSync(a))return eH("INVALID_ARGS",`App binary not found: ${a}`);let d=await at({session:s,flags:l,ensureReady:!1});if(!e2(r,d))return eH("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=te(e,(p=e,`Installed: ${p.appName??M(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&rI(f)}}async function aU(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return eH("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??eS;if(!Number.isInteger(i)||i<1||i>1e3)return eH("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=ea(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await aF(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=E(t);return eH(e.code,e.message,e.details)}}async function aF(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aC(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:void 0===r.runtime?e.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 aG(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new T("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await aV({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aj({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aq(t,u),a=!0)}else t=(await aj({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aq(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 aV(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await F("xcrun",q(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:eQ});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||aH(a).includes(aH(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 aj(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await F("xcrun",q(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new T("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 T("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aq(e,t){let r=await F("xcrun",q(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:eQ});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 aH(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aB(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=j(e.iosSimulatorDeviceSet);if(!r)return eH("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await aG({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:ez});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=E(t);return eH(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=W(t.flags?.androidDeviceAllowlist),a=e4(t.flags?.platform),i=et({simulatorSetPath:j(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./3918.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./3918.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./3918.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./3918.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=E(t);return eH(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r9(t.command,e,i);if(n)return n;let o=await at({session:e,flags:i,ensureReady:!0});if(!e2("apps",o))return eH("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(e3(o.platform)){let{listIosApps:e}=await import("./3918.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("./3918.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 aK(e){let{ensureAndroidEmulatorBooted:t}=await import("./3918.js");return await t(e)}let az='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',aW='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function aJ(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=e4(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return eH("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=r9("appstate",i,n);if(s)return s;let l=e3(i?.device.platform)&&function(e,t){if(!t)return!1;if(!r6(e))return!0;let r=e4(e?.platform);return!(r&&!e1(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 eH("SESSION_NOT_FOUND",az);if("macos"===o&&!l)return eH("SESSION_NOT_FOUND",aW);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 eH("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 at({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return eH("SESSION_NOT_FOUND",az);if("macos"===d.platform)return eH("SESSION_NOT_FOUND",aW);let{getAndroidAppState:u}=await import("./3918.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function aZ(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r9(t.command,i,n);if(o)return o;let s="android"===(e4(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=aa({flags:n,sessionDevice:i?.device}),u=s&&!!d,c=!1;try{e=await at({session:i,flags:n,ensureReady:!1})}catch(r){let t=E(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return eH("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 aK({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return eH("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=aa({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return eH("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aK({avdName:t,serial:n.serial,headless:!0})}await ez(e)}else("android"!==e.platform||!0!==e.booted)&&await ez(e);return e2("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:eH("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await aJ({req:t,sessionName:r,sessionStore:a}):null}function aX(e){return Math.round(10*e)/10}let aY="adb-shell-dumpsys-cpuinfo",aQ="adb-shell-dumpsys-meminfo";async function a0(e,t){try{let r=await F("adb",K(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:aX(i),measuredAt:r,method:aY,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw a2("cpu",t,e)}}async function a1(e,t){try{let r=await F("adb",K(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new T("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=a3(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!==a8(e));if(!r)break;return a8(r)??void 0}}(e);if(void 0===a)throw new T("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:a3(e,"TOTAL RSS"),measuredAt:r,method:aQ}}(r.stdout,t,new Date().toISOString())}catch(e){throw a2("memory",t,e)}}function a2(e,t,r){return r instanceof T&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new T(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof T?r:new T("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a3(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a8(a[1])??void 0}function a8(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a4="ps-process-snapshot",a5="ps-process-snapshot",a9="xctrace-activity-monitor",a6="xctrace-activity-monitor";async function a7(e,t){if("ios"===e.platform&&"device"===e.kind)return await ir(e,t);let r=await it(e,t),a=await id(e,r);if(0===a.length)throw new T("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(),n=ty(a.map(e=>o.basename(iu(e.command))));return ic({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:n,cpuMethod:a4,memoryMethod:a5})}async function ie(e){let t=eX(e),r=ip(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new T("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 T("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=ip(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:im(e),processName:ig(e)})}let r=ih(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:ih(t[o],u),residentMemoryBytes:ih(t[s],u)})}return d}async function it(e,t){let r="macos"===e.platform?await is(t):await il(e,t),a="macos"===e.platform?o.join(r,"Contents","Info.plist"):o.join(r,"Info.plist"),i=await eW(a,"CFBundleExecutable");if(!i)throw new T("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?o.join(r,"Contents","MacOS",i):void 0}}async function ir(e,t){let r=await ia(e,t),a=await ii(e,t),i=await ii(e,t),n=io(await ie(a.xml),r,t,e),o=io(await ie(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new T("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 T("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 ic({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:a9,memoryMethod:a6})}async function ia(e,t){let r=(await e0(e,"all")).find(e=>e.bundleId===t);if(!r)throw new T("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new T("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await e7(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new T("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 ii(e,t){let r=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-ios-perf-")),a=o.join(r,"sample.trace"),i=o.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"],o=await F("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==o.exitCode)throw new T("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:iw(o.stdout,o.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",i],d=await F("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new T("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:iw(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function io(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>o.basename(d(e.executable)))),s=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===s.length)throw new T("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:iy(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iy(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:ty(u.map(e=>e.processName))}}async function is(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await F("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new T("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 T("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function il(e,t){let r=X(e,["get_app_container",e.id,t,"app"]),a=await F("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new T("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 T("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function id(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:X(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 F("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=iu(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||o.basename(i)===a.executableName})}function iu(e){let[t=""]=e.trim().split(/\s+/,1);return t}function ic(e){return{cpu:{usagePercent:aX(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 ip(e,t){for(let r of e){if(t(r))return r;let e=ip(r.children,t);if(e)return e}}function im(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 ih(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:im(e):null}function ig(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function iw(e,t){let r=ep(e,t);if(r)return r;let a=`${e}
6
+ ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?eD: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 iy(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function iv(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:af},memory:{available:!1,reason:af},cpu:{available:!1,reason:af}},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:aQ,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:aY,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:a6,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:a9,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:a5,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:a4,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 iS(e);return n.metrics.memory=iI(o),n.metrics.cpu=iI(s),n}async function iS(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([a1(e.device,t),a0(e.device,t)]);return[r,a]}try{let r=await a7(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 iI(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=$(e.reason);return{available:!1,reason:t.message,error:t}}let iA=["path","start","stop","doctor","mark","clear"],ib=`logs requires ${iA.slice(0,-1).join(", ")}, or ${iA.at(-1)}`,i_=["dump","log"],iN=`network requires ${i_.join(" or ")}`,ik=["summary","headers","body","all"],ix=`network include mode must be one of: ${ik.join(", ")}`;async function iM(e){let{req:t}=e;return"perf"===t.command?iD(e):"logs"===t.command?iP(e):"network"===t.command?iE(e):null}async function iD(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return eH("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await iv(a)}}catch(e){return{ok:!1,error:$(e)}}}async function iP(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return eH("SESSION_NOT_FOUND","logs requires an active session");if(!e2("logs",n.device))return eH("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return iA.includes(o)?s&&"clear"!==o?eH("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===o?function(e,t,r){let a=r.resolveAppLogPath(t),n=function(e){if(!i.existsSync(e))return{exists:!1,sizeBytes:0};let t=i.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(a);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:n.sizeBytes,modifiedAt:n.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(n,r,a):"doctor"===o?iL(n,r,a):"mark"===o?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return rd(o),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
7
+ `,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?iR(n,r,a,s):"start"===o?iO(n,r,a):"stop"===o?iC(n,r,a):eH("INVALID_ARGS",ib):eH("INVALID_ARGS",ib)}async function iL(e,t,r){let a=r.resolveAppLogPath(t),i=await rh(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 iR(e,t,r,a){if(e.appLog&&!a)return eH("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return eH("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:rg(i)};e.appLog&&await rm(e.appLog);let n=rg(i),o=r.resolveAppLogPidPath(t);try{let a=await rf(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:$(a)}}}async function iO(e,t,r){if(e.appLog)return eH("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return eH("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 rf(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:$(e)}}}async function iC(e,t,r){if(!e.appLog)return eH("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rm(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iE(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","network requires an active session");if(!e2("network",i.device))return eH("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!i_.includes(n))return eH("INVALID_ARGS",iN);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return eH("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 eH("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return ik.includes(a)?{ok:!0,include:a}:eH("INVALID_ARGS",ix)}(t);if(!s.ok)return s;let{include:l}=s,d=await ru({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 i$=new Set(["ios","android","macos","linux"]);function iT(e,t,r){let a=e[t];if(void 0!==a)throw new T("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 iU(e){return!!e&&!Number.isNaN(Number(e))}let iF=/[*?[\]{}]/;async function iG(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;ec(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=E(e);return eH(t.code,t.message)}).finally(()=>{eJ(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eV(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 iV(c)||P({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){P({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:E(e).message}})}}}async function iV(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function ij(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return eH("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:a}=e,n=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tU.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>o.join(n,e));if(t.isFile()){if(".ad"!==o.extname(n))throw new T("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!iF.test(r)&&(a=n,!iF.test(a)))throw new T("INVALID_ARGS",`test input not found: ${e}`);let s=o.isAbsolute(n)?n:e;return i.globSync(s,{cwd:o.isAbsolute(n)?void 0:t}).map(e=>o.isAbsolute(e)?e:o.resolve(t,e)).filter(e=>".ad"===o.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>o.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&&i$.has(e)&&iT(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&iT(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&iT(r,"retries",Math.floor(e))}}return r}(i.readFileSync(e,"utf8"));if(!a){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 ${a}`});continue}d=a,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=a?` for --platform ${a}`:"";throw new T("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tU.expandHome(t??".agent-device/test-artifacts",r);return o.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),S=[],I=Date.now(),A=0;for(let e of w){if("skip"===e.kind){S.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await iq({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(S.push(i),t.flags?.failFast===!0)break}let b=(u=w.length,c=S,f=Date.now()-I,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=E(t);return eH(e.code,e.message)}}async function iq(e){var t,r;let a,n,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,y=Date.now(),v=o.join(h,(t=s.path,(0===(n=c?o.relative(c,t):o.basename(t)).length||n.startsWith("..")?o.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),S="",I=0;for(let e=0;e<=p;e+=1){I=e+1;let t=function(e,t,r,a,i=0){let n=o.basename(r,o.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),n=o.join(v,`attempt-${I}`);r=s.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,o.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eE(`${t??r}:test:${i+1}:${o.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await iG({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:a,attempts:n,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=[],a=new Map;for(let n of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=o.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}`}(o.basename(n),a),s=o.join(t,e);o.resolve(n)!==o.resolve(s)&&i.copyFileSync(n,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${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=>o.basename(e)).join(", ")}`);let f=o.join(l,"result.txt"),p=`${c.join("\n")}
8
+ `;i.writeFileSync(f,p),t.ok||i.writeFileSync(o.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:I,maxAttempts:p+1,attemptArtifactsDir:n}),a=h,S=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:s.path,session:S,status:"passed",durationMs:A,attempts:I,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let b=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:S,status:"failed",durationMs:A,attempts:I,artifactsDir:v,error:b}}function iH(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=ta(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 iB(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(t_(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),t_(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}=to(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=iH(e.positionals??[]);r&&t.push(r)}return ty(t).filter(e=>e.trim().length>0)})(t).map(e=>ts(e)).filter(e=>null!==e);if(0===o.length)return null;let s=t_(t.command)||"fill"===t.command,l=t_(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await iK(n,t,a,s,i);for(let e of o){let r=tl(d.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=tu(r.node,n.device.platform,{action:t_(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(t_(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=tw(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}=to(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}=iH(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function iK(e,t,r,a,i){let n=await er(e.device,"snapshot",[],t.flags?.out,{...eR(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:tp(t.flags?.snapshotRaw?o:tf(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return e.snapshot=s,i.set(e.name,e),s}async function iz(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o}=e,s=t.positionals?.[0];if(!s)return eH("INVALID_ARGS","replay requires a path");let l="",d=new Set;try{l=tU.expandHome(s,t.meta?.cwd);let e=i.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return eH("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 T("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=tE(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=tE(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(t_(a)){let e=tC(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 iU(r)&&iU(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tC(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=tC(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}if("--quality"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return n.positionals=e,n}if("screenshot"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--fullscreen"===r){n.flags.screenshotFullscreen=!0;continue}if("--max-size"===r){let e=i[t+1],r=void 0===e?NaN:Number(e);if(!Number.isInteger(r)||r<1)throw new T("INVALID_ARGS","screenshot --max-size requires a positive integer");n.flags.screenshotMaxSize=r,t+=1;continue}e.push(r)}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 i=c[e];if(!i||"replay"===i.command)continue;let s=await iW({req:t,sessionName:r,action:i,invoke:o});if(s.ok){iZ(s).forEach(e=>d.add(e));continue}if(!f)return iJ(s,i,e,l,[...d]);let u=await iB({action:i,sessionName:r,logPath:a,sessionStore:n});if(!u)return iJ(s,i,e,l,[...d]);if(c[e]=u,!(s=await iW({req:t,sessionName:r,action:u,invoke:o})).ok)return iJ(s,u,e,l,[...d]);iZ(s).forEach(e=>d.add(e)),p+=1}return f&&p>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${tx(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tT(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tM(r,tP));return tR(t,e.flags),t.join(" ")}if("record"===e.command)return tO(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"),"number"==typeof e.flags?.screenshotMaxSize&&t.push("--max-size",String(e.flags.screenshotMaxSize)),t.join(" ")}for(let r of e.positionals??[])t.push(tk(r));return tL(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
9
+ `,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=E(t);return eH(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function iW(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,aC(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function iJ(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 iZ(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 i.statSync(e).isFile()}catch{return!1}})(e)))]}async function iX(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await iz({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await ij({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await iz({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&&iZ(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await aR({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let iY=new Set(["session_list","ensure-simulator","devices","apps"]),iQ=new Set(["boot","appstate"]),i0=new Set(["perf","logs","network"]),i1=new Set(["replay","test"]);async function i2(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=r9(n,d,u);if(c)return c;let f=await at({session:d,flags:u,ensureReady:!0});if(!e2(n,f))return eH("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await er(f,n,o,t.flags?.out,{...eR(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 i3(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r9("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return eH("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await at({session:n,flags:o,ensureReady:!0});if(!e2("clipboard",d))return eH("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await er(d,"clipboard",t.positionals??[],t.flags?.out,{...eR(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 i8(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(iY.has(t.command))return await aB({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await au({req:t,sessionName:r,sessionStore:i});if(iQ.has(t.command))return await aZ({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await i3({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"!==e4((t.flags??{}).platform)?await i2({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):eH("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(i0.has(t.command))return await iM({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aT({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?a$:aE});if("install_source"===t.command)return await r2({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r8({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await i2({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=e$(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tU.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):eH("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await i2({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 ay(e.device,r,e.appBundleId,aw)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aM({req:t,sessionName:r,logPath:a,sessionStore:i}):i1.has(t.command)?await iX({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await aU(t,r,n):"close"===t.command?await aR({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function i4(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 eH("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=tg(s);if(!d)return eH("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return eH("INVALID_ARGS","find accepts only one of --first or --last");let p=await eK({req:t,sessionName:r,logPath:a,sessionStore:i});if(p)return p;let m=i.get(r);if(!m&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await eh(t.flags??{});m||await ez(h);let g="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,y=0,v=null,S=async()=>{let e=Date.now();if(v&&e-y<750&&!eZ(m))return{nodes:v};let{snapshot:n}=await ek({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return y=e,v=o,m&&(m.snapshot=n,i.set(r,m)),{nodes:o,truncated:n.truncated,backend:n.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:o,locator:l,query:d};if("wait"===u)return i5(I,S,l,d,f);let{nodes:A}=await S(),b=th(A,l,d,{requireRect:w});if(w&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,k;let e;return _=b.matches,N=l,k=d,e=_.slice(0,8).map(e=>{let t=tn(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eH("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${k}". Use a more specific locator or selector.`,{locator:N,query:k,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let x=b.matches[0]??null;if(!x)return eH("COMMAND_FAILED","find did not match any element");let M="click"===u||"focus"===u||"fill"===u||"type"===u?ti(A,x)??x:x,D=`@${M.ref}`,P={node:x,resolvedNode:M,ref:D,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>i9(I),get_text:()=>i6(I,P),get_attrs:()=>i7(I,P),click:()=>ne(I,P),fill:()=>nt(I,P,c),focus:()=>nr(I,P),type:()=>na(I,P,c)}[u];return L?L():null}async function i5(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(th(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 G(300)}return eH("COMMAND_FAILED","find wait timed out")}async function i9(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 i6(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await eN({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eR(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 i7(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 ne(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?tm(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 nt(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return eH("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 nr(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?tm(t.node.rect):null;if(!l)return eH("COMMAND_FAILED","matched element has no bounds");let d=await er(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eR(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 na(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return eH("INVALID_ARGS","find type requires text");let d=t.node.rect?tm(t.node.rect):null;if(!d)return eH("COMMAND_FAILED","matched element has no bounds");await er(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eR(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await er(o,"type",[r],a.flags?.out,{...eR(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 ni=`
10
10
  import Foundation
11
11
  import AVFoundation
12
12
 
@@ -30,11 +30,11 @@ Task {
30
30
 
31
31
  semaphore.wait()
32
32
  exit(exitCode)
33
- `.trim();async function ni(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,o=0;for(let t=0;t<n;t+=1){let t=0;try{t=i.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,a))}}async function nn(e){try{var t,r;let a,i=await tu("swift",["-",e],{stdin:na,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 ns(e);return!1}catch(t){if(t instanceof tp&&"TOOL_MISSING"===t.code)return ns(e);throw t}}async function no(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await nn(e))return;await new Promise(e=>setTimeout(e,r))}}function ns(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(a.push(o),1===n){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nl(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nd(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nu(e){let t=o.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new tp("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 nc(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await ni(t),await no(t);let s=i.mkdtempSync(o.join(c.tmpdir(),"agent-device-record-overlay-")),l=o.join(s,`input${o.extname(t)||".mp4"}`),d=o.join(s,o.basename(t)),u=o.join(s,"home"),f=o.join(s,"module-cache");i.copyFileSync(t,l),i.mkdirSync(u,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await tu("xcrun",["swift",r,"--input",l,"--output",d,...a],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await no(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof tp?a:new tp("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new tp("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function nf(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nc({videoPath:r,scriptPath:t??=nu("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function np(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nc({videoPath:r,scriptPath:e??=nu("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function nm(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await nc({videoPath:t,scriptPath:r??=nu("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function nh(e){return e instanceof Error?e.message:String(e)}function ng(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:a,targetLabel:n}=e,o=function(e){var t,r,a;let n,o,{recording:s,trimStartMs:l}=e,d=(n=nl((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?nd(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):nd(r))},i.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:a});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: ${nh(e)}`}}}async function ny(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 nv(e,t,r){for(let a=0;a<40;a+=1){if(!await ny(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await ny(e,t,r)}async function nI(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 nS(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 ny(e,t,a))break;if(i+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function nA(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{i.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",a,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=ng(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(e2({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return i.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;e2({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,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 nb(e){let{deps:t,deviceId:r,quality:a}=e;if(void 0===a||a>=10)return;let i=await t.runCmd("adb",["-s",r,"shell","wm","size"],{allowFailure:!0}),n=i.stdout.match(/Override size:\s*(\d+)x(\d+)/)??i.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==i.exitCode||!n)throw Error(`failed to resolve Android screen size for recording quality: ${ng(i,"adb shell wm size")}`);return{width:n_(Number(n[1]),a),height:n_(Number(n[2]),a)}}function n_(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nN(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function nk(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return e2({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 ny(e,t,r))&&await nv(e,t,r)}async function nx(e){var t;let r,a,{deps:i,device:n,recordingBase:o}=e,s="failed to start recording: Android screenrecord did not begin producing frames";try{r=await nb({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return eK("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),a=`agent-device-recording-${t}.mp4`,[`/sdcard/${a}`,`/data/local/tmp/${a}`])){let t=await i.runCmd("adb",["-s",n.id,"shell",function(e,t){let r=["screenrecord"];return t&&r.push("--size",`${t.width}x${t.height}`),r.push(e),`${r.join(" ")} >/dev/null 2>&1 & echo $!`}(e,r)],{allowFailure:!0});if(0!==t.exitCode){s=`failed to start recording: ${ng(t,"adb shell screenrecord")}`;continue}let a=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!a){s="failed to start recording: adb did not return a valid Android screenrecord pid",await nN(i,n.id,e);continue}if(e2({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nS(i,n.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...o,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await nk(i,n.id,a),await nN(i,n.id,e)}return eK("COMMAND_FAILED",s)}async function nM(e){let t,r,{deps:a,device:i,recording:n}=e;e2({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(e2({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 ny(a,i.id,n.remotePid)&&!await nk(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${ng(o,"adb shell kill")}`):await nv(a,i.id,n.remotePid)||await nk(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nI(a,i.id,n.remotePath);let e=await nA({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),eK("COMMAND_FAILED",e);await nw({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return eK("COMMAND_FAILED",t);if(r)return eK("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});e2({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: ${ng(e,"adb shell rm")}`)}}function nD(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nP(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nL(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nD(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nP(t,i,r))}catch(e){e2({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:nh(e)}})}}async function nR(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=nP(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,fps:d,quality:u.quality,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(!nh(a).toLowerCase().includes("recording already in progress"))return eK("COMMAND_FAILED",`failed to start recording: ${nh(a)}`);e2({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:nh(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 eK("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 eK("COMMAND_FAILED",`failed to start recording: ${nh(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function nO(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,quality:s.quality,appBundleId:l},nP(t,i,r))}catch(e){return eK("COMMAND_FAILED",`failed to start recording: ${nh(e)}`)}return{platform:"macos-runner",...s}}async function nE(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nD(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nP(t,i,r))}catch(e){e2({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nh(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 eK("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 nC(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nD(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nP(t,i,r))}catch(e){e2({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nh(e)}})}return await nw({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nT(e){for(let t=0;t<2;t+=1){try{if(i.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 n$(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await nL({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",e0(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await nT(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nD(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 nF(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return eK("INVALID_ARGS","recording already in progress");let c=r.flags?.fps,f=r.flags?.quality;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return eK("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return eK("INVALID_ARGS","quality must be an integer between 5 and 10");if(!Q("record",l))return eK("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tC.expandHome(p,r.meta?.cwd),h={outPath:m,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),quality:r.flags?.quality,showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(i.mkdirSync(o.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nD(s);if(!e)return eK("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nR({req:r,activeSession:s,sessionStore:n,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nD(s);if(!e)return eK("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nO({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await n$({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:h,resolvedOut:m}):await nx({deps:u,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,n.set(a,s),n.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??p,showTouches:t.showTouches}})}async function nU(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nM({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;if(0!==i.exitCode)return eK("COMMAND_FAILED",`failed to stop recording: ${ng(i,"simctl recordVideo")}`);if(void 0!==a.quality&&a.quality<10)try{await t.resizeRecording({videoPath:a.outPath,quality:a.quality,targetLabel:"iOS recording"})}catch(e){a.overlayWarning=`failed to resize recording: ${nh(e)}`}return await nw({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nG(e){var t;let r,{req:a,activeSession:i,device:n,logPath:s,deps:l}=e;if(!i.recording)return eK("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await nE({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await nC({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):await nU({deps:l,device:n,recording:d});return c||(u?eK("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nl(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nV(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:tu,runCmdBackground:td,runIosRunnerCommand:C,waitForStableFile:ni,isPlayableVideo:nn,trimRecordingStart:nf,resizeRecording:nm,overlayRecordingTouches:np},o=a.get(r),s=o?.device??await ep(t.flags??{});o||await eZ(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return eK("INVALID_ARGS","record requires start|stop");if("start"===d)return nF({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await nG({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 nj(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,s=t.command;if("record"===s)return nV({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return eK("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return eK("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return eK("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=tC.expandHome(e);return i.mkdirSync(o.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return eK("INVALID_ARGS","no active trace");let l=n.trace.outPath;if(t.positionals?.[1]){let e=tC.expandHome(t.positionals[1]);i.mkdirSync(o.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nq(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 nH=new WeakMap;function nB(e){if(!e)return;let t=nH.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)&&nz(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(nz);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 nH.set(e,r),r}function nz(e){return!!e&&e.width>0&&e.height>0}let nK={referenceWidth:1e3,referenceHeight:1e3};function nW(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=nY(p.effectiveDurationMs)??nY(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:nY(p.gestureStartUptimeMs),gestureEndUptimeMs:nY(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:nY(p.gestureStartUptimeMs),gestureEndUptimeMs:nY(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===nY(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=nQ(nY(t.count),1)??1,r=!0===t.doubleTap,a=nQ(nY(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 nq(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nq(h),y=(l=e.snapshot,u=nY((d=p).referenceWidth),c=nY(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:nB(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=n0(t,e);if(!i)return[];let{x:n,y:o}=i,s=nQ(nY(t.count),1)??1,l=nQ(nY(t.intervalMs),0)??0,d=!0===t.doubleTap,u=nQ(nY(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(nZ(t,n,o,u,a));continue}c.push(nJ(t,n,o,a)),d&&c.push(nJ(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=n0(t,e);if(!i)return[];let{x:n,y:o}=i;return[nJ(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=n0(t,e);if(!n)return[];let{x:o,y:s}=n;return[nZ(r,o,s,n2(a,[nY(t.durationMs),nY(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=n1(t,e),o=nX(t.contentDirection)??nX(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=n2(a,[],250),f=nY(t.amount)??nY(e[1]),p=nY(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=n1(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=n2(a,[nY(t.effectiveDurationMs),nY(t.durationMs),nY(e[4])],250),c=nQ(nY(t.count),1)??1,f=nQ(nY(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=n0(t,e,1),o=nY(t.scale)??nY(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:n2(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),e2({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:w,gestureDurationMs:g,kinds:v.map(e=>e.kind)}}))}function nJ(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function nZ(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function nX(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 nY(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 nQ(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function n0(e,t,r=0){let a=nY(e.x)??nY(t[r]),i=nY(e.y)??nY(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function n1(e,t){let r=nY(e.x1)??nY(t[0]),a=nY(e.y1)??nY(t[1]),i=nY(e.x2)??nY(t[2]),n=nY(e.y2)??nY(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 n2(e,t,r){return nQ(e,1)??t.map(e=>nQ(e,1)).find(e=>void 0!==e)??r}function n4(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??{},...ee(c)}}function n3(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}),K(a)&&tn(t,a),nW(t,a,i,o,n??{},l,d),{ok:!0,data:s}}async function n5(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 ev(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=nB(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=nB(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function n8(e){try{return await n5(e)}catch(t){e2({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function n6(e){return nB({nodes:e,createdAt:0})}function n9(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:eK("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.`)}function n7(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new tp("SESSION_NOT_FOUND","No active session. Run open first.");return ec({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,i)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0})}),tap:async(a,i)=>oe(await I(r.device,"press",[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(a,i,n)=>oe(await I(r.device,"fill",[String(i.x),String(i.y),n],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(a,i)=>oe(await I(r.device,"type",[i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),artifacts:eV("interaction commands",{plural:!0}),sessions:{get:r=>r===e.sessionName?{name:e.sessionName,appBundleId:t.appBundleId,appName:t.appName,snapshot:t.snapshot,metadata:{surface:t.surface}}:void 0,set:r=>{r.snapshot&&(t.snapshot=r.snapshot,e.sessionStore.set(e.sessionName,t))}},policy:j()})}function oe(e){return e&&"object"==typeof e?e:void 0}function ot(e){return"ref"===e.kind?{ref:or(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function or(e){return e?.startsWith("@")?e.slice(1):e}async function oa(e){switch(e.req.command){case"press":case"click":return await oi(e);case"fill":return await on(e);default:return null}}async function oi(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n="click"===t.command?"click":"press";if(!i)return eK("SESSION_NOT_FOUND","No active session. Run open first.");let o=n9(i,n);if(o)return o;if(!Q("press",i.device))return eK("UNSUPPORTED_OPERATION","press is not supported on this device");let s=eN(t.flags),l=R(s);if("primary"!==s){let e=X({commandLabel:n,platform:i.device.platform,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return eK(e.code,e.message,e.details)}let d=function(e,t){let r=eW(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.length>1?e.slice(1).join(" ").trim():""}};let i=e.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:i}}:{ok:!1,response:eK("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(t.positionals??[],n);if(!d.ok)return d.response;if("ref"===d.target.kind){let r=e.refSnapshotFlagGuardResponse("press",t.flags);if(r)return r}return await oo(e,{run:async e=>{let a={session:r,requestId:t.meta?.requestId,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap};return"click"===n?await e.interactions.click(d.target,a):await e.interactions.press(d.target,a)},afterRun:async e=>{var t;await ef(i,(t=d.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{let n="point"===r.kind?await n8({session:i,flags:t.flags,sessionStore:a,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):n6(i.snapshot?.nodes??[]),o=n4({data:r.backendResult,fallbackX:r.point.x,fallbackY:r.point.y,referenceFrame:n,extra:{...ot(r),...l}});return{result:o,responseData:o}}})}async function on(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=n9(i,"fill");if(e)return e}if(i&&!Q("fill",i.device))return eK("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return eK("SESSION_NOT_FOUND","No active session. Run open first.");let n=function(e){let t=e[0]??"";if(t.startsWith("@")){let r=e.length>=3?e[1]:"",a=e.length>=3?e.slice(2).join(" "):e.slice(1).join(" ");return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:r},text:a}:{ok:!1,response:eK("INVALID_ARGS","fill requires text after ref")}}let r=eW(e);if(r){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:r.x,y:r.y},text:t}:{ok:!1,response:eK("INVALID_ARGS","fill requires text after coordinates")}}let a=V(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:eK("INVALID_ARGS","fill requires x y text, @ref text, or selector text")};let i=a.rest.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:a.selectorExpression},text:i}:{ok:!1,response:eK("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!n.ok)return n.response;if("ref"===n.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r}return await oo(e,{run:async e=>await e.interactions.fill(n.target,n.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:n6(i.snapshot?.nodes??[]),r=n4({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...ot(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:or(e.target?.kind==="ref"?e.target.ref:void 0),x:e.point.x,y:e.point.y}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function oo(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eK("SESSION_NOT_FOUND","No active session. Run open first.");let a=n7(e),i=Date.now();try{let n=await t.run(a);await t.afterRun?.(n);let o=Date.now(),{result:s,responseData:l}=await t.buildPayloads(n);return n3({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:i,actionFinishedAt:o})}catch(t){let e=tc(t);if(ej(e))throw e;return{ok:!1,error:tf(t)}}}async function os(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 en({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}let ol=/\bis(?:n't| not)\s+responding\b/i,od=/^close app$/i;async function ou(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await oc(t),r=function(e){if(oh(e))return e.find(e=>{let t=om(e);return t.length>0&&od.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=k(r.rect),n=await tu("adb",eC(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return e2({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 of(t))return e2({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eD(t.device,t.appBundleId),!await op(t,t.appBundleId)))return e2({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return e2({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 e2({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 N(et((await Y(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function of(e){for(let t=0;t<12;t+=1){if(!oh(await oc(e)))return!0;await og(500)}return!oh(await oc(e))}async function op(e,t){for(let r=0;r<12;r+=1){if((await eI(e.device)).package===t)return!0;await og(500)}return(await eI(e.device)).package===t}function om(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 oh(e){return e.some(e=>{let t=om(e);return t.length>0&&ol.test(t)})}function og(e){return new Promise(t=>setTimeout(t,e))}async function ow(e){let t=await oa({...e,captureSnapshotForSession:os,refSnapshotFlagGuardResponse:O});if(t)return t;switch(e.req.command){case"type":return await oy({...e,captureSnapshotForSession:os});case"get":return await eo(e);case"is":return await e_(e);default:return null}}async function oy(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eK("SESSION_NOT_FOUND","No active session. Run open first.");if(!Q("type",i.device))return eK("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await ou({session:i}))return eK("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=n7(e),s=Date.now();try{let e=await o.interactions.typeText(n,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),d={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...ee(e.message??`Typed ${Array.from(e.text).length} chars`)};return n3({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:d,responseData:d,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:tf(e)}}}function ov(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 oI(e){let{req:t,leaseRegistry:r}=e,a=ov(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 oS(e,t){if(!t)return[];let r=[],a=e.device,i=w(t.platform);if(i&&!e7(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=ed(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oA(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 ob=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function o_(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:s}=e,l=ec({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let o={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?oN(await I(t.device,"screenshot",[],i,o)):oN(await I(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:i,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new tp("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-screenshot-")),r=o.join(t,"screenshot.png")),await n.mkdir(o.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await n.mkdtemp(o.join(c.tmpdir(),`${e.prefix}-`));return{path:o.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}}},sessions:{get:e=>e===r?{name:r,appBundleId:t.appBundleId,metadata:{surface:t.surface}}:void 0,set:()=>{}},policy:j()});return await l.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function oN(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let ok=[255,59,48,255],ox=[255,214,10,255],oM=[0,0,0,255],oD={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 oP(e){let t=U(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oR(r)&&o$(r.rect)&&(!t||oF(r.rect)>oF(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&&o$(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 o$(e.rect)&&!("image"===T((t=e).type??"")&&!oO(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oE)||oC(e.identifier);return oL(e)?t:t&&function(e){let t=T(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 oL(e)&&!oR(e)}(t)&&o$(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(oL(t)&&!oR(t)&&o$(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&o$(r.rect))return r;if(t.hittable&&o$(t.rect)&&!oR(t))return t;let a=e3(e,t);return a?.rect&&o$(a.rect)&&!oR(a)?a:null}(e.nodes,a);if(!o?.rect||!o$(o.rect))continue;let s=function(e,t,r){let a=oT(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=oT(a);if(!i)continue;let n=function(e){let t=0;return T(e.type??"").includes("text")&&(t+=2),oE(e.label)&&(t+=2),oE(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oT(t)??ei(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),oL(t)&&(a+=3),oL(e)&&(a+=2),r&&(a+=2),oC(t.identifier)&&(a+=1),oO(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return oV({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 oV({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(!o$(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)=>oF(e.overlayRect)-oF(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oU(e.overlayRect,r.overlayRect)||oU(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oF(r.overlayRect)<oF(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:oG(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:oG(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:k(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,i;(function(e,t,r){for(let a=0;a<2;a+=1)oq(e,t.x,t.x+t.width-1,t.y+a,r),oq(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),oH(e,t.x+a,t.y,t.y+t.height-1,r),oH(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,ok),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oj(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:oj(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)oB(e,t+o,r+n,i)})(e,i,o,a,ox),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oD[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]&&oB(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,oM)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,m.sync.write(t)),r}function oL(e){let t=[e.type,e.role,e.subrole].map(e=>T(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 oR(e){let t=[e.type,e.role,e.subrole].map(e=>T(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oO(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oE(e){var t;let r;return!!oO(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oC(e){var t;return"string"==typeof e&&!!oE(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oT(e){let t=[e.label,e.value].find(oE);return t?t.trim():oC(e.identifier)?e.identifier.trim():void 0}function o$(e){return!!(e&&e.width>0&&e.height>0)}function oF(e){return e.width*e.height}function oU(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 oG(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oV(e,t,r){let a=oj(e.x,0,Math.max(0,t-1)),i=oj(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:oj(e.width,1,n),height:oj(e.height,1,o)}}function oj(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oq(e,t,r,a,i){for(let n=t;n<=r;n+=1)oB(e,n,a,i)}function oH(e,t,r,a,i){for(let n=r;n<=a;n+=1)oB(e,t,n,i)}function oB(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 oz=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),oK=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),oW=new Set(oK),oJ=new Map;function oZ(e,t,r,a){let i=eX().requestId;return{...eP(e,t,r,a,i),requestId:i}}async function oX(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 ep(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function oY(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await oI({req:t,leaseRegistry:n});if(l)return l;let d=await i4({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await E({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await nj({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await i3({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await ow({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:s});return p||null}async function oQ(e){var t,r;let a,i,n,o,s,l,d,{req:u,session:c,logPath:f,sessionStore:p}=e,m=u.command;if(!Q(m,c.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${m} is not supported on this device`}};if("android"===c.device.platform&&c.recording&&"record"!==m&&"failed"===await ou({session:c}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:h,resolvedOut:g,recordedPositionals:w,recordedFlags:y}=(a=(t=u).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tC.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tC.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?o:i,d="screenshot"===a&&s?{...t.flags??{},out:s}:t.flags??{},{resolvedPositionals:o,resolvedOut:s,recordedPositionals:l,recordedFlags:d}),v=Date.now(),S={...oZ(f,u.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},A="screenshot"===m?await o_({session:c,sessionName:e.sessionName,outPath:h[0]??g,outputPlacement:"screenshot"!==(r=u).command?"default":(r.positionals??[])[0]?"positional":r.flags?.out?"out":"default",dispatchContext:S}):await I(c.device,m,h,g,{...S});return"screenshot"===m&&u.flags?.overlayRefs&&"string"==typeof A?.path&&await o0(c,A,f),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=nB(e.snapshot),n={...a??{}},o=nX(n.direction)??nX(r[0]);if(!o)return a;let s=nY(n.amount)??nY(r[1]),l=nY(n.pixels),d=n1(n,[]),u=nY(n.referenceWidth),c=nY(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??nK;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=x({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);nW(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:A,actionStartedAt:v,actionFinishedAt:Date.now(),flags:u.flags??{}}),K(m)&&tn(c,m),{ok:!0,data:A??{}}}async function o0(e,t,r){let a=eM(await eL({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oP({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function o1(e){i.existsSync(e)&&i.unlinkSync(e)}function o2(e){if(!i.existsSync(e))return null;try{let t=JSON.parse(i.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function o4(e){let t=o2(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function o3(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:o5,infoPath:o8,lockPath:o6,logPath:o9,sessionsDir:o7}=ti(process.env.AGENT_DEVICE_STATE_DIR),se=to(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var st=o7;if(i.existsSync(st))for(let e of i.readdirSync(st,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=o.join(st,e.name,t$);if(i.existsSync(t))try{let e=tF(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=te(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=y(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 sr=new tC(o7),sa=new rz({maxActiveSimulatorLeases:o3(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:o3(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:o3(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:o3(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),si=e9(),sn=a.randomBytes(24).toString("hex"),so=te(process.pid)??void 0,ss=ew(),sl=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:n}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await tt({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:tf(new tp("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=J(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=eb(r);if(r&&!a)throw new tp("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new tp("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);e2({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=ov(r);oK.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=oW.has(l)?null:await oX(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=eU(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?oS(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?!L(i):"apple"!==i||!L(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of ob){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 ob)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new tp("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oA).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=eX();if(!t.ok){e2({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=ts({force:!0})??void 0;return{ok:!1,error:tf(new tp(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 e2({level:"info",phase:"request_success"}),ts(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let s=(a=e,i=t,n=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||n.some(e=>e?.field==="path")||"string"!=typeof i.path||n.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:o.basename(a.meta?.clientArtifactPaths?.path??i.path)}),n.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,n);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||oz.has(l)||function(e,t){let r=oS(e,t);if(0!==r.length){var a;let t,i,n;throw new tp("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(oA).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await oY({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...oZ(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 oQ({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await ea(oJ,c,f)}catch(r){e2({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=eX(),t=ts({force:!0})??void 0;return{ok:!1,error:tf(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:o9,token:sn,sessionStore:sr,leaseRegistry:sa,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{rg(t)},9e5);return r.unref(),rh.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){i.existsSync(e)||i.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return i.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=o2(t);if(o?.pid&&o.pid!==process.pid&&A(o.pid,o.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(o5,o6,{pid:process.pid,version:si,startedAt:Date.now(),processStartTime:so})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===se||"dual"===se){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))eH(e);e2({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await e$(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){e2({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),W(o),eO(o))throw z();i=await sl(e)}catch(e){i={ok:!1,error:tf(e)}}finally{r-=1,o&&(a.delete(o),eQ(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 tp("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===se||"dual"===se){let e=await rU({handleRequest:sl,token:sn});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 tp("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:sn,version:si,codeSignature:ss,processStartTime:so},i.existsSync(o5)||i.mkdirSync(o5,{recursive:!0}),i.writeFileSync(o9,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",i.writeFileSync(o8,JSON.stringify({port:a.socketPort,httpPort:a.httpPort,transport:n,token:a.token,pid:process.pid,version:a.version,codeSignature:a.codeSignature,processStartTime:a.processStartTime,stateDir:o5},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
33
+ `.trim();async function nn(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,o=0;for(let t=0;t<n;t+=1){let t=0;try{t=i.statSync(e).size}catch{t=0}if(t>0&&t===r){if((o+=1)>=2)return}else o=0;r=t,await G(a)}}async function no(e){try{var t,r;let a,i=await F("swift",["-",e],{stdin:ni,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 nl(e);return!1}catch(t){if(t instanceof T&&"TOOL_MISSING"===t.code)return nl(e);throw t}}async function ns(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await no(e))return;await G(r)}}function nl(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(a.push(o),1===n){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nd(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nu(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nc(e){let t=o.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new T("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 nf(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await nn(t),await ns(t);let s=i.mkdtempSync(o.join(c.tmpdir(),"agent-device-record-overlay-")),l=o.join(s,`input${o.extname(t)||".mp4"}`),d=o.join(s,o.basename(t)),u=o.join(s,"home"),f=o.join(s,"module-cache");i.copyFileSync(t,l),i.mkdirSync(u,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await F("xcrun",["swift",r,"--input",l,"--output",d,...a],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await ns(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof T?a:new T("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new T("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function np(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nf({videoPath:r,scriptPath:t??=nc("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function nm(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nf({videoPath:r,scriptPath:e??=nc("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function nh(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await nf({videoPath:t,scriptPath:r??=nc("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function ng(e){return e instanceof Error?e.message:String(e)}function nw(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function ny(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:n}=e,o=function(e){var t,r,a;let n,o,{recording:s,trimStartMs:l}=e,d=(n=nd((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?nu(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):nu(r))},i.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:a});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: ${ng(e)}`}}}async function nv(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 nS(e,t,r){for(let a=0;a<40;a+=1){if(!await nv(e,t,r))return!0;await G(250)}return!await nv(e,t,r)}async function nI(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 G(250)}}async function nA(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 nv(e,t,a))break;if(i+1>=2)return!0;await G(250)}return!1}async function nb(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{i.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",a,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=nw(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(P({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return i.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;P({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1}})}e<1&&await G(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 n_(e){let{deps:t,deviceId:r,quality:a}=e;if(void 0===a||a>=10)return;let i=await t.runCmd("adb",["-s",r,"shell","wm","size"],{allowFailure:!0}),n=i.stdout.match(/Override size:\s*(\d+)x(\d+)/)??i.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==i.exitCode||!n)throw Error(`failed to resolve Android screen size for recording quality: ${nw(i,"adb shell wm size")}`);return{width:nN(Number(n[1]),a),height:nN(Number(n[2]),a)}}function nN(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nk(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function nx(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return P({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 nv(e,t,r))&&await nS(e,t,r)}async function nM(e){var t;let r,a,{deps:i,device:n,recordingBase:o}=e,s="failed to start recording: Android screenrecord did not begin producing frames";try{r=await n_({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return eH("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),a=`agent-device-recording-${t}.mp4`,[`/sdcard/${a}`,`/data/local/tmp/${a}`])){let t=await i.runCmd("adb",["-s",n.id,"shell",function(e,t){let r=["screenrecord"];return t&&r.push("--size",`${t.width}x${t.height}`),r.push(e),`${r.join(" ")} >/dev/null 2>&1 & echo $!`}(e,r)],{allowFailure:!0});if(0!==t.exitCode){s=`failed to start recording: ${nw(t,"adb shell screenrecord")}`;continue}let a=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!a){s="failed to start recording: adb did not return a valid Android screenrecord pid",await nk(i,n.id,e);continue}if(P({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nA(i,n.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...o,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await nx(i,n.id,a),await nk(i,n.id,e)}return eH("COMMAND_FAILED",s)}async function nD(e){let t,r,{deps:a,device:i,recording:n}=e;P({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(P({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 nv(a,i.id,n.remotePid)&&!await nx(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nw(o,"adb shell kill")}`):await nS(a,i.id,n.remotePid)||await nx(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nI(a,i.id,n.remotePath);let e=await nb({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),eH("COMMAND_FAILED",e);await ny({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return eH("COMMAND_FAILED",t);if(r)return eH("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});P({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: ${nw(e,"adb shell rm")}`)}}function nP(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nL(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nR(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nP(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nL(t,i,r))}catch(e){P({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:ng(e)}})}}async function nO(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=nL(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,fps:d,quality:u.quality,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(!ng(a).toLowerCase().includes("recording already in progress"))return eH("COMMAND_FAILED",`failed to start recording: ${ng(a)}`);P({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:ng(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 eH("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 eH("COMMAND_FAILED",`failed to start recording: ${ng(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function nC(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,quality:s.quality,appBundleId:l},nL(t,i,r))}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${ng(e)}`)}return{platform:"macos-runner",...s}}async function nE(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nP(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nL(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:ng(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of ee)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 eH("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 ny({recording:o,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function n$(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nP(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nL(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:ng(e)}})}return await ny({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nT(e){for(let t=0;t<2;t+=1){try{if(i.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await G(250)}return Date.now()}async function nU(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await nR({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",X(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await nT(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nP(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 nF(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return eH("INVALID_ARGS","recording already in progress");let c=r.flags?.fps,f=r.flags?.quality;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return eH("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return eH("INVALID_ARGS","quality must be an integer between 5 and 10");if(!e2("record",l))return eH("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tU.expandHome(p,r.meta?.cwd),h={outPath:m,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),quality:r.flags?.quality,showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(i.mkdirSync(o.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nP(s);if(!e)return eH("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nO({req:r,activeSession:s,sessionStore:n,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nP(s);if(!e)return eH("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nC({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await nU({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:h,resolvedOut:m}):await nM({deps:u,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,n.set(a,s),n.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??p,showTouches:t.showTouches}})}async function nG(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nD({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;if(0!==i.exitCode)return eH("COMMAND_FAILED",`failed to stop recording: ${nw(i,"simctl recordVideo")}`);if(void 0!==a.quality&&a.quality<10)try{await t.resizeRecording({videoPath:a.outPath,quality:a.quality,targetLabel:"iOS recording"})}catch(e){a.overlayWarning=`failed to resize recording: ${ng(e)}`}return await ny({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nV(e){var t;let r,{req:a,activeSession:i,device:n,logPath:s,deps:l}=e;if(!i.recording)return eH("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await nE({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await n$({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):await nG({deps:l,device:n,recording:d});return c||(u?eH("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nd(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nj(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:F,runCmdBackground:U,runIosRunnerCommand:eB,waitForStableFile:nn,isPlayableVideo:no,trimRecordingStart:np,resizeRecording:nh,overlayRecordingTouches:nm},o=a.get(r),s=o?.device??await eh(t.flags??{});o||await ez(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return eH("INVALID_ARGS","record requires start|stop");if("start"===d)return nF({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await nV({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 nq(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,s=t.command;if("record"===s)return nj({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return eH("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return eH("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=tU.expandHome(e);return i.mkdirSync(o.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return eH("INVALID_ARGS","no active trace");let l=n.trace.outPath;if(t.positionals?.[1]){let e=tU.expandHome(t.positionals[1]);i.mkdirSync(o.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nH(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 nB=new WeakMap;function nK(e){if(!e)return;let t=nB.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)&&nz(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(nz);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 nB.set(e,r),r}function nz(e){return!!e&&e.width>0&&e.height>0}let nW={referenceWidth:1e3,referenceHeight:1e3};function nJ(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=nQ(p.effectiveDurationMs)??nQ(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:nQ(p.gestureStartUptimeMs),gestureEndUptimeMs:nQ(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:nQ(p.gestureStartUptimeMs),gestureEndUptimeMs:nQ(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===nQ(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=n0(nQ(t.count),1)??1,r=!0===t.doubleTap,a=n0(nQ(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 nH(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nH(h),y=(l=e.snapshot,u=nQ((d=p).referenceWidth),c=nQ(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:nK(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=n1(t,e);if(!i)return[];let{x:n,y:o}=i,s=n0(nQ(t.count),1)??1,l=n0(nQ(t.intervalMs),0)??0,d=!0===t.doubleTap,u=n0(nQ(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(nX(t,n,o,u,a));continue}c.push(nZ(t,n,o,a)),d&&c.push(nZ(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=n1(t,e);if(!i)return[];let{x:n,y:o}=i;return[nZ(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=n1(t,e);if(!n)return[];let{x:o,y:s}=n;return[nX(r,o,s,n3(a,[nQ(t.durationMs),nQ(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=n2(t,e),o=nY(t.contentDirection)??nY(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=n3(a,[],250),f=nQ(t.amount)??nQ(e[1]),p=nQ(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=n2(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=n3(a,[nQ(t.effectiveDurationMs),nQ(t.durationMs),nQ(e[4])],250),c=n0(nQ(t.count),1)??1,f=n0(nQ(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=n1(t,e,1),o=nQ(t.scale)??nQ(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:n3(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),P({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:w,gestureDurationMs:g,kinds:v.map(e=>e.kind)}}))}function nZ(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function nX(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function nY(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 nQ(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 n0(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function n1(e,t,r=0){let a=nQ(e.x)??nQ(t[r]),i=nQ(e.y)??nQ(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function n2(e,t){let r=nQ(e.x1)??nQ(t[0]),a=nQ(e.y1)??nQ(t[1]),i=nQ(e.x2)??nQ(t[2]),n=nQ(e.y2)??nQ(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 n3(e,t,r){return n0(e,1)??t.map(e=>n0(e,1)).find(e=>void 0!==e)??r}function n8(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??{},...tr(c)}}function n4(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}),ef(a)&&e9(t,a),nJ(t,a,i,o,n??{},l,d),{ok:!0,data:s}}async function n5(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 eb(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=nK(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=nK(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function n9(e){try{return await n5(e)}catch(t){P({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function n6(e){return nK({nodes:e,createdAt:0})}function n7(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:eH("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.`)}function oe(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new T("SESSION_NOT_FOUND","No active session. Run open first.");return y({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,i)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0})}),tap:async(a,i)=>ot(await er(r.device,"press",[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(a,i,n)=>ot(await er(r.device,"fill",[String(i.x),String(i.y),n],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(a,i)=>ot(await er(r.device,"type",[i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),artifacts:eF("interaction commands",{plural:!0}),sessions:{get:r=>r===e.sessionName?{name:e.sessionName,appBundleId:t.appBundleId,appName:t.appName,snapshot:t.snapshot,metadata:{surface:t.surface}}:void 0,set:r=>{r.snapshot&&(t.snapshot=r.snapshot,e.sessionStore.set(e.sessionName,t))}},policy:w()})}function ot(e){return e&&"object"==typeof e?e:void 0}function or(e){return"ref"===e.kind?{ref:oa(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function oa(e){return e?.startsWith("@")?e.slice(1):e}async function oi(e){switch(e.req.command){case"press":case"click":return await on(e);case"fill":return await oo(e);default:return null}}async function on(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n="click"===t.command?"click":"press";if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let o=n7(i,n);if(o)return o;if(!e2("press",i.device))return eH("UNSUPPORTED_OPERATION","press is not supported on this device");let s=eM(t.flags),l=en(s);if("primary"!==s){let e=ed({commandLabel:n,platform:i.device.platform,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return eH(e.code,e.message,e.details)}let d=function(e,t){let r=eq(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.length>1?e.slice(1).join(" ").trim():""}};let i=e.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:i}}:{ok:!1,response:eH("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(t.positionals??[],n);if(!d.ok)return d.response;if("ref"===d.target.kind){let r=e.refSnapshotFlagGuardResponse("press",t.flags);if(r)return r}return await os(e,{run:async e=>{let a={session:r,requestId:t.meta?.requestId,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap};return"click"===n?await e.interactions.click(d.target,a):await e.interactions.press(d.target,a)},afterRun:async e=>{var t;await eg(i,(t=d.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{let n="point"===r.kind?await n9({session:i,flags:t.flags,sessionStore:a,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):n6(i.snapshot?.nodes??[]),o=n8({data:r.backendResult,fallbackX:r.point.x,fallbackY:r.point.y,referenceFrame:n,extra:{...or(r),...l}});return{result:o,responseData:o}}})}async function oo(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=n7(i,"fill");if(e)return e}if(i&&!e2("fill",i.device))return eH("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let n=function(e){let t=e[0]??"";if(t.startsWith("@")){let r=e.length>=3?e[1]:"",a=e.length>=3?e.slice(2).join(" "):e.slice(1).join(" ");return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:r},text:a}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after ref")}}let r=eq(e);if(r){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:r.x,y:r.y},text:t}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after coordinates")}}let a=ta(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:eH("INVALID_ARGS","fill requires x y text, @ref text, or selector text")};let i=a.rest.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:a.selectorExpression},text:i}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!n.ok)return n.response;if("ref"===n.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r}return await os(e,{run:async e=>await e.interactions.fill(n.target,n.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:n6(i.snapshot?.nodes??[]),r=n8({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...or(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:oa(e.target?.kind==="ref"?e.target.ref:void 0),x:e.point.x,y:e.point.y}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function os(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let a=oe(e),i=Date.now();try{let n=await t.run(a);await t.afterRun?.(n);let o=Date.now(),{result:s,responseData:l}=await t.buildPayloads(n);return n4({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:i,actionFinishedAt:o})}catch(t){let e=E(t);if(eG(e))throw e;return{ok:!1,error:$(t)}}}async function ol(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 ek({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}let od=/\bis(?:n't| not)\s+responding\b/i,ou=/^close app$/i;async function oc(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await of(t),r=function(e){if(og(e))return e.find(e=>{let t=oh(e);return t.length>0&&ou.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=tm(r.rect),n=await F("adb",K(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return P({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 op(t))return P({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 om(t,t.appBundleId)))return P({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return P({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 P({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 of(e){return tp(tf((await em(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function op(e){for(let t=0;t<12;t+=1){if(!og(await of(e)))return!0;await G(500)}return!og(await of(e))}async function om(e,t){for(let r=0;r<12;r+=1){if((await eI(e.device)).package===t)return!0;await G(500)}return(await eI(e.device)).package===t}function oh(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 og(e){return e.some(e=>{let t=oh(e);return t.length>0&&od.test(t)})}async function ow(e){let t=await oi({...e,captureSnapshotForSession:ol,refSnapshotFlagGuardResponse:ei});if(t)return t;switch(e.req.command){case"type":return await oy({...e,captureSnapshotForSession:ol});case"get":return await ev(e);case"is":return await ex(e);default:return null}}async function oy(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");if(!e2("type",i.device))return eH("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await oc({session:i}))return eH("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=oe(e),s=Date.now();try{let e=await o.interactions.typeText(n,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),d={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...tr(e.message??`Typed ${Array.from(e.text).length} chars`)};return n4({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:d,responseData:d,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:$(e)}}}function ov(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 oS(e){let{req:t,leaseRegistry:r}=e,a=ov(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 oI(e,t){if(!t)return[];let r=[],a=e.device,i=e4(t.platform);if(i&&!e1(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=B(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oA(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 ob=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function o_(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:s}=e,l=y({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let o={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?oN(await er(t.device,"screenshot",[],i,o)):oN(await er(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:i,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new T("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-screenshot-")),r=o.join(t,"screenshot.png")),await n.mkdir(o.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await n.mkdtemp(o.join(c.tmpdir(),`${e.prefix}-`));return{path:o.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}}},sessions:{get:e=>e===r?{name:r,appBundleId:t.appBundleId,metadata:{surface:t.surface}}:void 0,set:()=>{}},policy:w()});return await l.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,maxSize:s.screenshotMaxSize,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function oN(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let ok=[255,59,48,255],ox=[255,214,10,255],oM=[0,0,0,255],oD={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 oP(e){let t=tt(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oR(r)&&oT(r.rect)&&(!t||oU(r.rect)>oU(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&&oT(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 oT(e.rect)&&!("image"===tc((t=e).type??"")&&!oO(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oC)||oE(e.identifier);return oL(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 oL(e)&&!oR(e)}(t)&&oT(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(oL(t)&&!oR(t)&&oT(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oT(r.rect))return r;if(t.hittable&&oT(t.rect)&&!oR(t))return t;let a=ti(e,t);return a?.rect&&oT(a.rect)&&!oR(a)?a:null}(e.nodes,a);if(!o?.rect||!oT(o.rect))continue;let s=function(e,t,r){let a=o$(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=o$(a);if(!i)continue;let n=function(e){let t=0;return tc(e.type??"").includes("text")&&(t+=2),oC(e.label)&&(t+=2),oC(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(o$(t)??td(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),oL(t)&&(a+=3),oL(e)&&(a+=2),r&&(a+=2),oE(t.identifier)&&(a+=1),oO(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return oV({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 oV({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(!oT(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)=>oU(e.overlayRect)-oU(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oF(e.overlayRect,r.overlayRect)||oF(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oU(r.overlayRect)<oU(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:oG(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:oG(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:tm(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,i;(function(e,t,r){for(let a=0;a<2;a+=1)oq(e,t.x,t.x+t.width-1,t.y+a,r),oq(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),oH(e,t.x+a,t.y,t.y+t.height-1,r),oH(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,ok),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oj(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:oj(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)oB(e,t+o,r+n,i)})(e,i,o,a,ox),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oD[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]&&oB(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,oM)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,m.sync.write(t)),r}function oL(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 oR(e){let t=[e.type,e.role,e.subrole].map(e=>tc(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oO(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oC(e){var t;let r;return!!oO(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oE(e){var t;return"string"==typeof e&&!!oC(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function o$(e){let t=[e.label,e.value].find(oC);return t?t.trim():oE(e.identifier)?e.identifier.trim():void 0}function oT(e){return!!(e&&e.width>0&&e.height>0)}function oU(e){return e.width*e.height}function oF(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 oG(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oV(e,t,r){let a=oj(e.x,0,Math.max(0,t-1)),i=oj(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:oj(e.width,1,n),height:oj(e.height,1,o)}}function oj(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oq(e,t,r,a,i){for(let n=t;n<=r;n+=1)oB(e,n,a,i)}function oH(e,t,r,a,i){for(let n=r;n<=a;n+=1)oB(e,t,n,i)}function oB(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 oK=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),oz=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),oW=new Set(oz),oJ=new Map;function oZ(e,t,r,a){let i=k().requestId;return{...eR(e,t,r,a,i),requestId:i}}async function oX(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||r6(e.flags))try{let t=await eh(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function oY(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await oS({req:t,leaseRegistry:n});if(l)return l;let d=await i8({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await eo({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await nq({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await i4({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await ow({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:s});return p||null}async function oQ(e){var t,r;let a,i,n,o,s,l,d,{req:u,session:c,logPath:f,sessionStore:p}=e,m=u.command;if(!e2(m,c.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${m} is not supported on this device`}};if("android"===c.device.platform&&c.recording&&"record"!==m&&"failed"===await oc({session:c}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:h,resolvedOut:g,recordedPositionals:w,recordedFlags:y}=(a=(t=u).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tU.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tU.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?o:i,d="screenshot"===a&&s?{...t.flags??{},out:s}:t.flags??{},{resolvedPositionals:o,resolvedOut:s,recordedPositionals:l,recordedFlags:d}),v=Date.now(),S={...oZ(f,u.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},I="screenshot"===m?await o_({session:c,sessionName:e.sessionName,outPath:h[0]??g,outputPlacement:"screenshot"!==(r=u).command?"default":(r.positionals??[])[0]?"positional":r.flags?.out?"out":"default",dispatchContext:S}):await er(c.device,m,h,g,{...S});return"screenshot"===m&&u.flags?.overlayRefs&&"string"==typeof I?.path&&await o0(c,I,f),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=nK(e.snapshot),n={...a??{}},o=nY(n.direction)??nY(r[0]);if(!o)return a;let s=nQ(n.amount)??nQ(r[1]),l=nQ(n.pixels),d=n2(n,[]),u=nQ(n.referenceWidth),c=nQ(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??nW;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=e6({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);nJ(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:I,actionStartedAt:v,actionFinishedAt:Date.now(),flags:u.flags??{}}),ef(m)&&e9(c,m),{ok:!0,data:I??{}}}async function o0(e,t,r){let a=eP(await eO({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oP({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function o1(e){i.existsSync(e)&&i.unlinkSync(e)}function o2(e){if(!i.existsSync(e))return null;try{let t=JSON.parse(i.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function o3(e){let t=o2(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function o8(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:o4,infoPath:o5,lockPath:o9,logPath:o6,sessionsDir:o7}=_(process.env.AGENT_DEVICE_STATE_DIR),se=x(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var st=o7;if(i.existsSync(st))for(let e of i.readdirSync(st,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=o.join(st,e.name,tG);if(i.existsSync(t))try{let e=tV(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=L(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=O(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{tq(t)}}let sr=new tU(o7),sa=new rW({maxActiveSimulatorLeases:o8(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),si=v(),sn=a.randomBytes(24).toString("hex"),so=L(process.pid)??void 0,ss=S(),sl=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:n}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await b({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:$(new T("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=A(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=I(r);if(r&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new T("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);P({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=ov(r);oz.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=oW.has(l)?null:await oX(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=eU(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?oI(t,a):function(e,t,r){var a,i;let n=[],o=e4(t);if(void 0!==e.platform&&o&&(a=e4(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!e3(i):"apple"!==i||!e3(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of ob){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 ob)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new T("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oA).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=k();if(!t.ok){P({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=N({force:!0})??void 0;return{ok:!1,error:$(new T(C(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 P({level:"info",phase:"request_success"}),N(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let s=(a=e,i=t,n=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||n.some(e=>e?.field==="path")||"string"!=typeof i.path||n.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:o.basename(a.meta?.clientArtifactPaths?.path??i.path)}),n.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,n);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||oK.has(l)||function(e,t){let r=oI(e,t);if(0!==r.length){var a;let t,i,n;throw new T("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(oA).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await oY({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...oZ(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 oQ({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await ey(oJ,c,f)}catch(r){P({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=k(),t=N({force:!0})??void 0;return{ok:!1,error:$(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:o6,token:sn,sessionStore:sr,leaseRegistry:sa,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{ry(t)},9e5);return r.unref(),rw.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){i.existsSync(e)||i.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return i.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=o2(t);if(o?.pid&&o.pid!==process.pid&&R(o.pid,o.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(o4,o9,{pid:process.pid,version:si,startedAt:Date.now(),processStartTime:so})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===se||"dual"===se){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))eV(e);P({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await eT(),!(r<=0));)await G(200)}catch(e){P({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),ec(o),eC(o))throw eu();i=await sl(e)}catch(e){i={ok:!1,error:$(e)}}finally{r-=1,o&&(a.delete(o),eJ(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 T("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===se||"dual"===se){let e=await rV({handleRequest:sl,token:sn});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 T("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:sn,version:si,codeSignature:ss,processStartTime:so},i.existsSync(o4)||i.mkdirSync(o4,{recursive:!0}),i.writeFileSync(o6,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",i.writeFileSync(o5,JSON.stringify({port:a.socketPort,httpPort:a.httpPort,transport:n,token:a.token,pid:process.pid,version:a.version,codeSignature:a.codeSignature,processStartTime:a.processStartTime,stateDir:o4},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
36
36
  `),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${t}
37
- `)}catch(t){let e=tc(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
38
- `),r))try{t.close(()=>{})}catch{}o1(o8),o4(o6),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(),sr.toArray()))sr.writeSessionLog(e);await ey(),o1(o8),o4(o6),process.exit(0)}};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof tp?e:tc(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 tp?t:tc(t);process.stderr.write(`Daemon error: ${r.message}
37
+ `)}catch(t){let e=E(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
38
+ `),r))try{t.close(()=>{})}catch{}o1(o5),o3(o9),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(),sr.toArray()))sr.writeSessionLog(e);await ew(),o1(o5),o3(o9),process.exit(0)}};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof T?e:E(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 T?t:E(t);process.stderr.write(`Daemon error: ${r.message}
40
40
  `),s()})}();