agent-device 0.14.8 → 0.15.0

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 (49) hide show
  1. package/README.md +8 -6
  2. package/android-snapshot-helper/README.md +4 -2
  3. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.8.apk → agent-device-android-snapshot-helper-0.15.0.apk} +0 -0
  4. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.15.0.apk.sha256 +1 -0
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.8.manifest.json → agent-device-android-snapshot-helper-0.15.0.manifest.json} +6 -6
  6. package/dist/src/1769.js +7 -0
  7. package/dist/src/2151.js +429 -0
  8. package/dist/src/221.js +4 -4
  9. package/dist/src/2842.js +1 -0
  10. package/dist/src/3572.js +1 -0
  11. package/dist/src/4057.js +1 -1
  12. package/dist/src/840.js +2 -0
  13. package/dist/src/9542.js +2 -2
  14. package/dist/src/9639.js +2 -2
  15. package/dist/src/9818.js +1 -1
  16. package/dist/src/android-adb.d.ts +49 -11
  17. package/dist/src/android-adb.js +1 -1
  18. package/dist/src/android-snapshot-helper.d.ts +35 -2
  19. package/dist/src/cli.js +60 -57
  20. package/dist/src/contracts.d.ts +2 -0
  21. package/dist/src/finders.d.ts +2 -0
  22. package/dist/src/index.d.ts +25 -22
  23. package/dist/src/internal/companion-tunnel.js +1 -1
  24. package/dist/src/internal/daemon.js +51 -23
  25. package/dist/src/remote-config.d.ts +17 -14
  26. package/dist/src/selectors.d.ts +3 -0
  27. package/dist/src/server.js +2 -20
  28. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +7 -1
  29. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +210 -56
  30. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +890 -99
  31. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +94 -7
  32. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +8 -0
  33. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +24 -0
  34. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +2 -0
  35. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +185 -0
  36. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +1 -2
  37. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +26 -0
  38. package/package.json +25 -11
  39. package/server.json +3 -3
  40. package/skills/agent-device/SKILL.md +6 -1
  41. package/skills/dogfood/SKILL.md +3 -1
  42. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.8.apk.sha256 +0 -1
  43. package/dist/src/180.js +0 -1
  44. package/dist/src/6108.js +0 -26
  45. package/dist/src/6642.js +0 -1
  46. package/dist/src/7462.js +0 -1
  47. package/dist/src/8809.js +0 -8
  48. package/dist/src/command-schema.js +0 -381
  49. package/skills/react-devtools/SKILL.md +0 -48
@@ -1,16 +1,34 @@
1
- let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import s from"node:path";import{spawn as o}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{once as f}from"node:events";import{Transform as p}from"node:stream";import{pipeline as m}from"node:stream/promises";import h from"node:fs/promises";import{setTimeout as g}from"node:timers/promises";import{PNG as w}from"pngjs";import y from"node:net";import{resolveUserPath as v}from"../3267.js";import{withDiagnosticsScope as S,flushDiagnosticsToSessionFile as I,getDiagnosticsMeta as A,emitDiagnostic as b}from"../7599.js";import{trimRuntimeValue as _,readProcessCommand as N,resolveRuntimeTransportHints as M,isAgentDeviceDaemonProcess as x,readProcessStartTime as D}from"../8656.js";import{withAndroidAdbProvider as k,pullAndroidAdbFile as P,resolveAndroidAdbProvider as R,resolveAndroidAdbExecutor as L}from"../9639.js";import{androidDeviceForSerial as O,runAndroidAdb as E,resolveIosSimulatorDeviceSetPath as C,classifyAndroidAppTarget as $,resolveIosDeviceDeepLinkBundleId as T,parseSerialAllowlist as F,getAndroidAppState as U,resolveAndroidSerialAllowlist as V,isDeepLinkTarget as G,openAndroidApp as j,formatAndroidInstalledPackageRequiredMessage as q}from"../8809.js";import{streamAndroidLogcatWithAdb as H,captureAndroidLogcatWithAdb as B}from"../6642.js";import{toAppErrorCode as K,asAppError as z,normalizeError as W,AppError as J}from"../9152.js";import{sleep as Z,resolveTimeoutMs as X}from"../4829.js";import{runCmdBackground as Y,runCmd as Q}from"../9818.js";import{IOS_RUNNER_CONTAINER_BUNDLE_IDS as ee,resolveAppleSimulatorSetPathForSelector as et,buildSimctlArgs as er,dispatchCommand as ea,refSnapshotFlagGuardResponse as ei,buttonTag as en,handleSnapshotCommands as es,withTargetDeviceResolutionScope as eo,shutdownSimulator as el,stopIosRunnerSession as ed,localCommandPolicy as eu,getClickButtonValidationError as ec,createRequestCanceledError as ef,isNavigationSensitiveAction as ep,registerRequestAbort as em,errorResponse as eh,resolveIosDevicectlHint as eg,snapshotAndroid as ew,resolveTargetDevice as ey,withKeyedLock as ev,setSessionSnapshot as eS,dispatchGetViaRuntime as eI,assertAndroidPressStayedInApp as eA,stopAllIosRunnerSessions as eb,runMacOsAlertAction as e_,createAgentDevice as eN,getAndroidScreenSize as eM,readTextForNode as ex,captureSnapshot as eD,dispatchIsViaRuntime as ek,resolveClickButton as eP,IOS_DEVICECTL_DEFAULT_HINT as eR,buildSnapshotState as eL,context_contextFromFlags as eO,captureSnapshotData as eE,resolveRequestTrackingId as eC,isRequestCanceled as e$,resolvePayloadInput as eT,abortAllIosRunnerSessions as eF,getRunnerSessionSnapshot as eU,createUnsupportedArtifactAdapter as eV,isAndroidEscapeError as eG,markRequestCanceled as ej,dispatchFindReadOnlyViaRuntime as eq,runIosRunnerCommand as eH,ensureDeviceReady as eB,readInfoPlistString as eK,clearRequestCanceled as ez,buildSimctlArgsForDevice as eW,getActiveAndroidSnapshotFreshness as eJ,parseXmlDocumentSync as eZ,resolveFrontmostMacOsApp as eX,IOS_SIMCTL_LIST_TIMEOUT_MS as eY,matchesPlatformSelector as eQ,isCommandSupportedOnDevice as e0,listIosDeviceApps as e1,isApplePlatform as e2,listIosDeviceProcesses as e8,normalizePlatformSelector as e3,getRequestSignal as e5,decodePng as e4,buildScrollGesturePlan as e6,markAndroidSnapshotFreshness as e9}from"../6108.js";import{normalizeTenantId as e7,withSuccessText as te,resolveDaemonPaths as tt,resolveSessionIsolationMode as tr,resolveDaemonServerMode as ta,successText as ti,resolveInstallFromSourceResultTarget as tn,resolveDeployResultTarget as ts,resolveDaemonCodeSignature as to}from"../180.js";import{parseSessionSurface as tl}from"../7462.js";import{runBatch as td,mergeParentFlags as tu}from"../1231.js";import{splitSelectorFromArgs as tc,findNearestHittableAncestor as tf,extractNodeText as tp,splitIsSelectorArgs as tm,tryParseSelectorChain as th,resolveSelectorChain as tg,resolveRefLabel as tw,buildSelectorChainForNode as ty,normalizeType as tv,pruneGroupNodes as tS}from"../940.js";import{attachRefs as tI,centerOfRect as tA}from"../4057.js";import{findBestMatchesByLocator as tb,parseFindArgs as t_}from"../7556.js";import{readVersion as tN}from"../9671.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 tx(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tD=/^-?\d+(\.\d+)?$/,tk=/^[^\s"\\]+$/,tP=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tR=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tL=new Map([["--delay-ms","delayMs"]]);function tO(e){return"click"===e||"press"===e}function tE(e){return"type"===e||"fill"===e}function tC(e){return tT(e,tF)}function t$(e){return JSON.stringify(e)}function tT(e,t){return t(e)?e:t$(e)}function tF(e){return tU(e)&&e.startsWith("@")||tD.test(e)}function tU(e){return tk.test(e)}function tV(e,t){let r=t.flags??{};if(tO(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}tE(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tG(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",tT(t.metroHost,tU)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tT(t.bundleUrl,tU)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tT(t.launchUrl,tU)))}function tj(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tT(r,tU)),a))e.push(tC(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 tq(e,t){let r=[],a={},i=tO(e)?tP:"swipe"===e?tR:tE(e)?tL:void 0;for(let n=0;n<t.length;n+=1){let s=t[n];if(tO(e)&&"--double-tap"===s){a.doubleTap=!0;continue}if(tO(e)&&"--button"===s&&n+1<t.length){let e=t[n+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),n+=1;continue}let o=i?.get(s);if(o&&n+1<t.length){let e=tB(t[n+1]);if(null!==e){a[o]=e,n+=1;continue}}if("swipe"===e&&"--pattern"===s&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(s)}return{positionals:r,flags:a}}function tH(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=tB(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 tB(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tK(e,t){for(let r of t.positionals??[])e.push(tC(r));t.flags?.relaunch&&e.push("--relaunch"),tG(e,t.runtime)}class tz{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=tz.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 tW)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),b({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=s.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(tO(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tC(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tC(a)),tV(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tC(r)),tV(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tC(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tC(a)),e.positionals.length>1&&t.push(tC(i)),tV(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tC(r)),t.push(tC(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tC(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",tC(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tC(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 tK(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tT(r,tU)),tG(t,e.flags),t.join(" ")}if("record"===e.command)return tj(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tC(r));return tV(t,e),t.join(" ")}(i));return`${r.join("\n")}
2
- `}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=tz.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return s.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return s.join(this.sessionsDir,tz.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return s.join(this.sessionsDir,tz.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return v(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tz.expandHome(e.saveScriptPath);i.existsSync(this.sessionsDir)||i.mkdirSync(this.sessionsDir,{recursive:!0});let t=tz.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return s.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&&(tO(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(tO(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(tO(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 tW=["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"],tJ="app-log.pid";function tZ(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 tX(e,t){if(!e)return;let r=s.dirname(e);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:D(t)??void 0,command:N(t)??void 0};i.writeFileSync(e,`${JSON.stringify(a)}
3
- `)}function tY(e){if(e&&i.existsSync(e))try{i.unlinkSync(e)}catch{}}async function tQ(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}function t0(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 t1(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 t2(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new J("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function t8(e,t){let r=(await L(O(e))(["shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function t3(e,t){var r,a;let i;t2(t);let n=await t8(e,t),s=L(O(e)),o=await B(s,{lines:4e3,timeoutMs:3e3}).catch(()=>"");if(0===o.trim().length)return null;let l=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,t,n);if(0===l.length)return null;let d=(r=o,a=t,i=new Set(l),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===d.trim().length?null:{pid:n,text:d,recoveredPids:l}}async function t5(e,t,r,a,i){let n,s,o="recovering",l=!1,d=(async()=>{try{for(;!l;){let d=await t8(e,t);if(!d){o="recovering",await Z(1e3);continue}let u=R(O(e)),c=H(u,{pid:d});n=c;let f=t0(r,{redactionPatterns:a});if(s=t1(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&tX(i,c.pid),o="active",await s,tY(i),n=void 0,s=void 0,l)break;o="recovering",await Z(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tY(i)}})();return{backend:"android",getState:()=>o,startedAt:Date.now(),wait:d,stop:async()=>{l=!0,n&&!n.killed&&n.kill("SIGINT"),s&&await tQ(s),n&&!n.killed&&n.kill("SIGKILL"),await tQ(d),tY(i)}}}function t4(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function t6(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=er(["spawn",t,"log","show","--style","compact","--info","--predicate",t4(r)],{simulatorSetPath:i});"number"==typeof a&&Number.isFinite(a)&&a>0?n.push("--start",`@${Math.floor(a/1e3)}`):n.push("--last","5m");let s=await Q("xcrun",n,{allowFailure:!0,timeoutMs:4e3});if(0!==s.exitCode||0===s.stdout.trim().length)return null;let o=s.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===o.length?null:{text:`${o.join("\n")}
5
- `,recoveredLineCount:o.length}}async function t9(e,t,r,a,i,n){let s="active",l=o("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return er(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",t4(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=t0(r,{redactionPatterns:a});"number"==typeof l.pid&&tX(n,l.pid);let u=t1(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(s="failed"),tY(n),e));return{backend:"ios-simulator",getState:()=>s,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tQ(u),l.killed||l.kill("SIGKILL"),await tQ(u),tY(n)}}}async function t7(e,t,r,a){let i="active",n=o("log",["stream","--style","compact","--predicate",t4(e)],{stdio:["ignore","pipe","pipe"]}),s=t0(t,{redactionPatterns:r});"number"==typeof n.pid&&tX(a,n.pid);let l=t1(n,t,{endStreamOnClose:!0,writer:s}).then(e=>(0!==e.exitCode&&(i="failed"),tY(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tQ(l),n.killed||n.kill("SIGKILL"),await tQ(l),tY(a)}}}async function re(e,t,r,a){let i="active",n=o("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),s=t0(t,{redactionPatterns:r});"number"==typeof n.pid&&tX(a,n.pid);let l=t1(n,t,{endStreamOnClose:!0,writer:s}).then(e=>(0!==e.exitCode&&(i="failed"),tY(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tQ(l),n.killed||n.kill("SIGKILL"),await tQ(l),tY(a)}}}let rt=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),rr=/https?:\/\/[^\s"'<>\])]+/i,ra=[/\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 ri(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>rs(e)));for(let e of t.entries){let t=rs(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function rn(e,t){let r=rg(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=rg(t?.maxPayloadChars,2048,64,16384),s=rg(t?.maxScanLines,4e3,100,2e4),o=e.split("\n"),l=Math.max(0,o.length-s),d=o.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 s=e[t]?.trim();if(!s)return null;let o=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}}(s),l=rf(o,["method","httpMethod"]),d=rf(o,["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}(o,["status","statusCode","responseCode"]),c=rt.exec(s),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(s),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=rr.exec(s),h=d??m?.[0];if(!h)return null;let g=u??rl(s)??void 0;if(!(l||f?.[1]||c?.[1]||void 0!==g||/\bURL["'=: ]+https?:\/\//i.test(s)||/\bheaders?["'=: ]+/i.test(s)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(s)))return null;let w={method:p,url:h,status:g,timestamp:rd(s),packetId:ru(s)??void 0,durationMs:rc(s)??void 0,raw:rh(s,n),line:r};if("android"===a&&function(e,t,r){let a=ro(t,r,5),i=e.packetId??a.map(e=>ru(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?ro(t,r,12).filter(e=>ru(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>rd(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>rl(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>rc(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 rm(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(s,o);e&&(w.headers=rh(e,n))}if("body"===i||"all"===i){let e=rp(s,o,["requestBody","body","payload","request"]),t=rp(s,o,["responseBody","response"]);e&&(w.requestBody=rh(e,n)),t&&(w.responseBody=rh(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:s}}}function rs(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function ro(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 rl(e){for(let t of ra){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function rd(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 ru(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function rc(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 rf(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 rp(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return rm(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 rm(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function rh(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function rg(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function rw(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 ry(e){let t=s.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:rw("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:rw("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function rv(e){var t,r,a,n;let s,o,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},s=rg(t?.maxEntries,25,1,200),o=t?.include??"summary",l=rg(t?.maxPayloadChars,2048,64,16384),d=rg(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?rn(i.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:o,limits:{maxEntries:s,maxPayloadChars:l,maxScanLines:d}}),I=[],A=await rS({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await t3(u.id,c);if(e){let t=rn(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(S=ri(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 rA({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=ri(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 rS(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 o=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tZ(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}(s.join(s.dirname(a),tJ));if(!o)return null;let l=await t8(t.id,r);return l&&l!==o?{reason:"stale-active",trackedPid:o}:null}async function rI(e,t,r,a){ry(r);let n=i.createWriteStream(r,{flags:"a"}),s=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 re(e.id,n,s,a):await t9(e.id,t,n,s,e.simulatorSetPath,a);if("android"===e.platform)return t2(t),await t5(e.id,t,n,s,a);if("macos"===e.platform)return await t7(t,n,s,a);throw n.end(),new J("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rA(e){let t=await t6({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:rn(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 rb(e){await e.stop(),await tQ(e.wait)}async function r_(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 t=await E(e,["shell","echo","ok"],{allowFailure:!0,timeoutMs:1e3});r.adbAvailable=0===t.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await E(e,["shell","pidof",t],{allowFailure:!0,timeoutMs:1e3})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await Q("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 Q("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await Q("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rN(e){let t=s.dirname(e),r=s.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(s.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rM=new Map;function rx(e){let t=rM.get(e);if(t&&(clearTimeout(t.timer),rM.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rD=new Map;function rk(e,t){let r=rD.get(e);if(!r)throw new J("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new J("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rP(e){let t=rD.get(e);t&&(clearTimeout(t.timer),rD.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rR(e){let t=await rL(e);await Q("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=s.join(e.tempDir,t);if(!i.existsSync(r))throw new J("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rL(e){let t=await Q("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new J("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 J("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(rO),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 J("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new J("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 J("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 J("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,s=i;if(n!==s&&!n.startsWith(`${s}/`))throw new J("INVALID_ARGS",`Archive entry must stay inside top-level "${s}" bundle: ${n}`)}for(let t of(await Q("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new J("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function rO(e){if(e.includes("\0"))throw new J("INVALID_ARGS",`Invalid archive entry: ${e}`);if(s.posix.isAbsolute(e))throw new J("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=s.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new J("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rE=X(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function rC(e,t){return new Promise((r,a)=>{let n,s=!1,o=0,l=i.createWriteStream(t),d=e=>{if(!s){if(s=!0,n&&clearTimeout(n),e)return void r$(l,t).finally(()=>a(e));r()}},u=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let t=new J("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rE});"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t),c.destroy(t),d(t)},rE)},c=new p({transform(e,t,r){u();let a=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e,t);(o+=a)>0x80000000?r(new J("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")):r(null,e)}});e.on("aborted",()=>{d(new J("COMMAND_FAILED","Artifact transfer was interrupted"))}),u(),m(e,c,l).then(()=>d(),e=>d(e))})}async function r$(e,t){if(e.destroy(),!e.closed)try{await f(e,"close")}catch{}await i.promises.rm(t,{force:!0}).catch(()=>{})}async function rT(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new J("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new J("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 J("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=s.basename(t);if(!r||"."===r||".."===r)throw new J("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),o=(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(s.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=s.join(o,n);return await rC(e,t),{artifactPath:t,tempDir:o}}let t=s.join(o,"artifact.tar");await rC(e,t);let a=await rR({archivePath:t,tempDir:o,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:o}}catch(e){throw i.rmSync(o,{recursive:!0,force:!0}),e}}let rF=new Set(["agent_device.command","agent-device.command"]),rU=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rV=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rG={"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"},rj=new Set([...rF,...rU,...rV,...Object.keys(rG)]);function rq(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rH(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rB(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function rK(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 rz(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rW(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}function rJ(e,t){let r="string"==typeof e[t]?e[t].trim():"";if(!r)throw new J("INVALID_ARGS",`Invalid params: source.${t} is required for github-actions-artifact sources`);return r}function rZ(e,t){let r=e[t],a="number"==typeof r?r:"string"==typeof r?Number(r):NaN;if(!Number.isInteger(a))throw new J("INVALID_ARGS",`Invalid params: source.${t} must be an integer`);return a}async function rX(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=W(new J("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rq(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=W(new J(K(r.code,"UNAUTHORIZED"),r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rq(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=e7(r.tenantId);if(!e){let e=W(new J("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rq(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rY(){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=s.isAbsolute(t)?t:s.resolve(t);try{e=await import(u(a).href)}catch(e){throw new J("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 J("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rQ(e){let t=await rY(),{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 r0(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/artifacts/"))return void r1(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||rH(i,rq(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,s;try{a=JSON.parse(n)}catch{rH(i,rq(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rH(i,rq(a.id??null,-32600,"Invalid Request"),400);if(!rj.has(a.method))return void rH(i,rq(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rH(i,rq(a.id??null,-32602,"Invalid params"),400);try{var o;let n=a.params,l=function(e,t,r){if(rF.has(e))return{token:rK(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(rU.has(e)){let e,a=rz(t,"platform");if("ios"!==a&&"android"!==a)throw new J("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:rK(t,r),session:rz(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rz(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new J("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new J("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 J("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 J("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 J("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}if("github-actions-artifact"===t.kind)return function(e){let t,r=rJ(e,"owner"),a=rJ(e,"repo"),i=void 0!==e.artifactId,n=void 0!==e.runId,s=void 0!==e.artifactName;if(i&&(n||s))throw new J("INVALID_ARGS","Invalid params: source must specify either artifactId or artifactName, not both");if(!i&&n&&!s)throw new J("INVALID_ARGS","Invalid params: source.artifactName is required when source.runId is specified");if(!i&&!s)throw new J("INVALID_ARGS","Invalid params: source must specify artifactId or artifactName");return i?{kind:"github-actions-artifact",owner:r,repo:a,artifactId:rZ(e,"artifactId")}:(n&&(t=rZ(e,"runId")),{kind:"github-actions-artifact",owner:r,repo:a,...n?{runId:t}:{},artifactName:rJ(e,"artifactName")})}(t);throw new J("INVALID_ARGS",'Invalid params: source.kind must be "url", "path", or "github-actions-artifact"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rW(t,"retentionMs")}}}if(rV.has(e)){let e=rz(t,"materializationId")?.trim();if(!e)throw new J("INVALID_ARGS","Invalid params: materializationId is required");return{token:rK(t,r),session:rz(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rz(t,"requestId"),materializationId:e}}}let a=rG[e];if(a)return{token:rK(t,r),session:rz(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rz(t,"tenantId")??rz(t,"tenant"),runId:rz(t,"runId"),leaseId:rz(t,"leaseId"),leaseTtlMs:rW(t,"ttlMs"),leaseBackend:rz(t,"backend")}};throw new J("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(o=a.method,rF.has(o)&&("string"!=typeof l.command||0===l.command.length))return void rH(i,rq(a.id??null,-32602,"Invalid params: command is required"),400);s=eC(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:s},em(s);let d=()=>{i.writableFinished||ej(s)};e.on("aborted",d),i.on("close",d);let u=await rX(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rH(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 rH(i,{jsonrpc:"2.0",id:a.id??null,result:c});rH(i,rq(a.id??null,-32e3,c.error.message,c.error),rB(c.error.code))}catch(t){let e=W(t);rH(i,rq(a.id??null,-32e3,e.message,e),rB(e.code))}finally{ez(s)}})})}async function r0(e,t,r,i){try{var n;let s,o,l=rK({},e.headers),d=r2(l,i);if(d){t.statusCode=rB(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await rX(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 rT(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},s=a.randomUUID(),(o=setTimeout(()=>{rP(s)},3e5)).unref(),rD.set(s,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:o}),s);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:f}))}catch(r){let e=W(r);t.statusCode=rB(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function r1(e,t,r,a){let n=e.url?.slice("/artifacts/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let s=rK({},e.headers),o=r2(s,a);if(o){t.statusCode=rB(o.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:o.message,code:o.code}));return}let l=await rX(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:s,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=rM.get(e);if(!r)throw new J("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new J("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw rx(e),new J("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=W(e);t.statusCode=rB(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&rx(n)}),u.pipe(t)}catch(r){let e=W(r);t.statusCode=rB(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function r2(e,t){return t&&e!==t?W(new J("UNAUTHORIZED","Invalid token")):null}function r8(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function r3(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function r5(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 J("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class r4{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=r5(e.backend),r=e7(e.tenantId);if(!r)throw new J("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=r8(e.runId);if(!i)throw new J("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),s=this.bindingKey(r,i,t),o=this.runBindings.get(s);if(o){let e=this.leases.get(o);if(e)return this.refreshLease(e,n);this.runBindings.delete(s)}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(s,d.leaseId),{...d}}heartbeatLease(e){let t=r3(e.leaseId);if(!t)throw new J("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new J("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=r3(e.leaseId);if(!t)throw new J("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=r5(e.backend),r=e7(e.tenantId);if(!r)throw new J("INVALID_ARGS","tenant isolation requires tenant id.");let a=r8(e.runId);if(!a)throw new J("INVALID_ARGS","tenant isolation requires run id.");let i=r3(e.leaseId);if(!i)throw new J("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new J("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new J("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 J("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 J("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=e7(t),i=r8(r);if(t&&!a)throw new J("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new J("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 J("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let r6=X(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),r9=new Map;async function r7(e){let t=await h.mkdtemp(s.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await ar(e.installablePath,s.join(t,"installable")),i=e.archivePath?await ar(e.archivePath,s.join(t,"archive")):void 0,n=a.randomUUID(),o=e.ttlMs??r6,l=Date.now()+o,d=setTimeout(()=>{ae(n)},o);return r9.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 h.rm(t,{recursive:!0,force:!0}),e}}async function ae(e,t){let r=r9.get(e);if(!r)throw new J("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new J("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),r9.delete(e),await h.rm(r.rootPath,{recursive:!0,force:!0})}async function at(e){let t=Array.from(r9.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await ae(e)}))}async function ar(e,t){let r=await h.stat(e);await h.mkdir(t,{recursive:!0});let a=s.join(t,s.basename(e));return r.isDirectory()?await h.cp(e,a,{recursive:!0}):await h.copyFile(e,a),a}async function aa(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 J("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await eB(e.session.device),e.session.device}if(!r)throw new J("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await ey(e.flags??{});return await eB(a),a}async function ai(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,s,o=(n=function(e){let t=e.meta?.installSource;if(!t)throw new J("INVALID_ARGS","install_from_source requires a source payload");switch(t.kind){case"url":if(!t.url||0===t.url.trim().length)throw new J("INVALID_ARGS","install_from_source url source requires a non-empty url");return t;case"path":if(!t.path||0===t.path.trim().length)throw new J("INVALID_ARGS","install_from_source path source requires a non-empty path");return t;case"github-actions-artifact":throw new J("UNSUPPORTED_OPERATION","install_from_source github-actions-artifact sources require a compatible remote daemon");default:throw new J("UNSUPPORTED_OPERATION",`install_from_source ${String(t.kind)} sources require a compatible remote daemon`)}}(t),(s=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:rk(s,t.meta?.tenantId)},cleanup:()=>{rP(s)}}:{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 J("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await aa({session:i,flags:t.flags});if(!e0("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("../6108.js"),{prepareIosInstallArtifact:s}=await import("../6108.js"),c=await s(o.source,{signal:u});try{if(l.enabled&&(e=await r7({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 J("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let s={...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}:{}},o=te(s,an(s));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:o}),{ok:!0,data:o}}catch(r){throw e&&await ae(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),o.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("../8809.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("../6108.js"),p=await c(o.source,{signal:u});try{l.enabled&&(e=await r7({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 J("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:s}=await import("../6108.js"),o=s(n),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...o?{appName:o}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=te(u,an(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await ae(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),o.cleanup()}}catch(e){return{ok:!1,error:W(e)}}}function an(e){return`Installed: ${tn(e)}`}async function as(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new J("INVALID_ARGS","release_materialized_paths requires a materializationId");return await ae(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:W(e)}}}let ao=X(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),al=X(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function ad(e,t,r){return t||au(r)?null:eh("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function au(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function ac(e){return"ios"===e.platform&&"simulator"===e.kind}async function af(e,t){ac(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function ap(e){let t=au(e.flags)||!e.session?await ey(e.flags??{}):await am(e.session.device);return!1!==e.ensureReady&&await eB(t),t}async function am(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 ey(t)}catch(e){if(!(e instanceof J)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await ey({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function ah(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 ag="shared_prefs/ReactNativeDevPrefs.xml",aw="debug_http_host",ay="dev_server_https",av="RCT_jsLocation",aS="RCT_packager_scheme",aI="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",aA='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function ab(e){return void 0!==M(e)}async function a_(e){let{device:t,appId:r,runtime:a}=e;if(!r)return;let i=M(a);if(i){if("android"===t.platform)return void await aM(t,r,i);"ios"===t.platform&&"simulator"===t.kind&&await aP(t,r,i)}}async function aN(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await ax(t,r);"ios"===t.platform&&"simulator"===t.kind&&await aR(t,r)}}async function aM(e,t,r){var a,i,n,s,o,l;let d,u;aC(t);let c=(a=await aD(e,t),i=aw,n=`${r.host}:${r.port}`,d=` <string name="${a$(i)}">${a$(n)}</string>`,aO(aE(a,i),d));s=c,o=ay,l="https"===r.scheme,u=` <boolean name="${a$(o)}" value="${l?"true":"false"}" />`,c=aO(aE(s,o),u),await ak(e,t,c)}async function ax(e,t){aC(t);let r=await aD(e,t),a=aE(r,aw),i=aE(a,ay);i!==r&&await ak(e,t,i)}async function aD(e,t){let r=await E(e,["shell","run-as",t,"cat",ag],{allowFailure:!0});return 0!==r.exitCode?aA:aL(r.stdout)}async function ak(e,t,r){let a=["shell","run-as",t,"id"],i=await E(e,a,{allowFailure:!0});if(0!==i.exitCode){let e=aT(i.stdout,i.stderr);throw new J("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:a,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:e?aI:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await E(e,["shell","run-as",t,"mkdir","-p","shared_prefs"]),await E(e,["shell","run-as",t,"tee",ag],{stdin:r.trimEnd()})}catch(a){let e=z(a);if("TOOL_MISSING"===e.code)throw e;let r=aT("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new J("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?aI:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function aP(e,t,r){await Q("xcrun",eW(e,["spawn",e.id,"defaults","write",t,av,"-string",`${r.host}:${r.port}`])),await Q("xcrun",eW(e,["spawn",e.id,"defaults","write",t,aS,"-string",r.scheme]))}async function aR(e,t){await Q("xcrun",eW(e,["spawn",e.id,"defaults","delete",t,av]),{allowFailure:!0}),await Q("xcrun",eW(e,["spawn",e.id,"defaults","delete",t,aS]),{allowFailure:!0})}function aL(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
6
- `:aA}function aO(e,t){return aL(e).replace("</map>",`${t}
7
- </map>`)}function aE(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return aL(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function aC(e){if("binary"!==$(e))return;let t=q(e);throw new J("INVALID_ARGS",t,{package:e,hint:t})}function a$(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function aT(e,t){let r=`${e}
8
- ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}let aF=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function aU(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function aV(e,t){if(void 0!==e){if("string"!=typeof e)throw new J("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return _(e)}}function aG(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new J("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function aj(e){if("ios"===e||"android"===e)return e}async function aq(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!ab(r)||ab(a)||await aN({device:i.device,appId:i.appBundleId})}async function aH(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,s=(a.positionals?.[0]??"show").toLowerCase(),o=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(s))return eh("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===s){ab(l)&&o?.appBundleId&&await aN({device:o.device,appId:o.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===s)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let d=aj(e3(a.flags?.platform)??l?.platform??o?.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(o&&o.device.platform!==d)return eh("INVALID_ARGS",`runtime set targets ${d}, but session "${i}" is already bound to ${o.device.platform}.`);let u={platform:(t=a.flags,r={platform:d,metroHost:_(t?.metroHost),metroPort:aG(t?.metroPort),bundleUrl:_(t?.bundleUrl),launchUrl:_(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===aU(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 aB="open-command-roundtrip",aK="Not implemented for this platform in this release.",az=new Set(["app","desktop","frontmost-app"]);async function aW(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eX();return{appBundleId:t.bundleId,appName:t.appName}}function aJ(e){return Math.round(10*e)/10}function aZ(e){return Math.round(10*e)/10}let aX="adb-shell-dumpsys-gfxinfo-framestats";function aY(e,t,r){let a=t.get(r);if(void 0===a)return null;let i=Number(e[a]);return Number.isFinite(i)?i:null}function aQ(e){return 0===e.length?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function a0(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function a1(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`^\\s*${r}:\\s*([0-9][0-9,]*)`,"im"));if(a)return a2(a[1])??void 0}function a2(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}async function a8(e,t,r={}){var a,i,n,s,o,l,d,u;let c=L(e,r.adb);try{let d,u,f,p,m,h,g,w,y,v,S,I=(a=(await c(["shell","dumpsys","gfxinfo",t,"framestats"],{timeoutMs:15e3})).stdout,i=new Date().toISOString(),function(e,t){if(/no process found for:/i.test(e))throw new J("COMMAND_FAILED",`Android gfxinfo did not find a running process for ${t}`,{metric:"fps",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect."})}(a,t),f=function(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??"",r=a1(t,"Total frames rendered"),a=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(void 0===r||!a)return;let i=a2(a[1])??void 0,n=Number(a[2]);if(void 0===i||!Number.isFinite(n)||r<0)return;let s=a1(t,"Uptime"),o=a1(t,"Stats since");return{droppedFramePercent:aJ(n),droppedFrameCount:i,totalFrameCount:r,sampleWindowMs:function(e){let{uptimeMs:t,statsSinceNs:r}=e;if(void 0===t||void 0===r)return;let a=t-Math.round(r/1e6);return a>=0?a:void 0}({uptimeMs:s,statsSinceNs:o}),uptimeMs:s,statsSinceNs:o}}(a),p=function(e){let t=[],r=null;for(let i of e.split("\n")){var a;let e=i.trim();if(0===e.length||"---PROFILEDATA---"===e)continue;let n=e.split(",").map(e=>e.trim());if((a=n).includes("IntendedVsync")&&a.includes("FrameCompleted")){r=new Map(n.map((e,t)=>[e,t]));continue}let s=function(e,t){if(!t||e.length<t.size)return;let r=aY(e,t,"Flags"),a=aY(e,t,"IntendedVsync"),i=aY(e,t,"FrameCompleted");if(0===r&&null!==a&&null!==i&&!(a<=0)&&!(i<=a))return{intendedVsyncNs:a,frameCompletedNs:i,durationNs:i-a}}(n,r);s&&t.push(s)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}(a),m=function(e,t,r){let a=function(e){var t;let r=(t=e.map(e=>e.intendedVsyncNs),[...new Set(t.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)),a=[];for(let e=1;e<r.length;e+=1){let t=r[e]-r[e-1];t>=4e6&&t<=5e7&&a.push(t)}if(0!==a.length){let e,t;return e=[...a].sort((e,t)=>e-t),t=Math.floor(e.length/2),e.length%2==1?e[t]:(e[t-1]+e[t])/2}}(e);if(t||0!==e.length||function(e){throw new J("COMMAND_FAILED",`Failed to parse Android framestats output for ${e}`,{metric:"fps",package:e,hint:"Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging."})}(r),t||void 0!==a)return a;throw new J("COMMAND_FAILED",`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:"fps",package:r,hint:"Retry perf after a longer interaction window so consecutive Android frame timestamps are available."})}(p,f,t),h=Date.parse(i),g=function(e){let{frames:t,measuredAtMs:r,summary:a}=e,i=aQ(t),n=a?.statsSinceNs,s=n??i.firstFrameNs,o=a0(s,i.lastFrameNs),l=a?.sampleWindowMs??o;if(!Number.isFinite(r)||a?.uptimeMs===void 0||void 0===s)return{sampleWindowMs:l,windowStartNs:s};let d=r-a.uptimeMs;return{sampleWindowMs:l,windowStartNs:s,windowStartedAt:new Date(d+s/1e6).toISOString(),windowEndedAt:function(e){let{deviceBootWallClockMs:t,measuredAtMs:r,summaryStartNs:a,lastFrameNs:i}=e;return void 0!==a?new Date(r).toISOString():void 0===i?void 0:new Date(t+i/1e6).toISOString()}({deviceBootWallClockMs:d,measuredAtMs:r,summaryStartNs:n,lastFrameNs:i.lastFrameNs}),timestampSource:"estimated-from-device-uptime"}}({frames:p,measuredAtMs:h,summary:f}),w=function(e){let{frames:t,frameDeadlineNs:r,summaryDroppedFrameCount:a}=e;return void 0!==a?a<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,a).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs):void 0===r?[]:t.filter(e=>e.durationNs>r)}({frames:p,frameDeadlineNs:m,summaryDroppedFrameCount:f?.droppedFrameCount}),y=f?.sampleWindowMs??g.sampleWindowMs??function(e){if(0===e.length)return;let t=aQ(e);return a0(t.firstFrameNs,t.lastFrameNs)}(p),n=f,s=p,o=w,d=n?.totalFrameCount??s.length,u=n?.droppedFrameCount??o.length,v={totalFrameCount:d,droppedFrameCount:u,droppedFramePercent:n?.droppedFramePercent??(d>0?aJ(u/d*100):0)},S=function(e){let{droppedFrames:t,timing:r,measuredAtMs:a,summary:i}=e;if(0===t.length)return;let n=function(e){let{frames:t,windowStartNs:r,measuredAtMs:a,uptimeMs:i}=e;if(0===t.length||void 0===r)return[];let n=[],s=[];for(let e of t){let t=s.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){s.push(e);continue}n.push(s),s=[e]}return s.length>0&&n.push(s),n.map(e=>(function(e){let{frames:t,windowStartNs:r,measuredAtMs:a,uptimeMs:i}=e,n=Math.min(...t.map(e=>e.intendedVsyncNs)),s=Math.max(...t.map(e=>e.frameCompletedNs)),o=Math.max(0,Math.round((n-r)/1e6)),l=Math.max(o,Math.round((s-r)/1e6)),d=void 0!==i&&Number.isFinite(a)?a-i:void 0;return{startOffsetMs:o,endOffsetMs:l,startAt:void 0===d?void 0:new Date(d+n/1e6).toISOString(),endAt:void 0===d?void 0:new Date(d+s/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:aZ(Math.max(...t.map(e=>e.durationNs))/1e6)}})({frames:e,windowStartNs:r,measuredAtMs:a,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}({frames:t,windowStartNs:r.windowStartNs,measuredAtMs:a,uptimeMs:i?.uptimeMs});return n.length>0?n:void 0}({droppedFrames:w,timing:g,measuredAtMs:h,summary:f}),{...v,sampleWindowMs:y,...(l=m,{frameDeadlineMs:void 0===l?void 0:aZ(l/1e6),refreshRateHz:void 0===l?void 0:aZ(1e9/l)}),windowStartedAt:g.windowStartedAt,windowEndedAt:g.windowEndedAt,timestampSource:g.timestampSource,measuredAt:i,method:aX,source:f?"android-gfxinfo-summary":"framestats-rows",worstWindows:S&&S.length>0?S:void 0});return await a3(e,t,r),I}catch(e){throw d=t,(u=e)instanceof J?new J(u.code,u.message,{...u.details??{},metric:"fps",package:d},u):new J("COMMAND_FAILED",`Failed to sample Android fps for ${d}`,{metric:"fps",package:d},u)}}async function a3(e,t,r={}){let a=L(e,r.adb);try{await a(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let a5="adb-shell-dumpsys-cpuinfo",a4="adb-shell-dumpsys-meminfo";async function a6(e,t,r={}){let a=L(e,r.adb);try{let e=await a(["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,s;let e=r.trim();if(0===e.length)continue;let o=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!o)continue;let l=Number(o[1]),d=o[2];Number.isFinite(l)&&(n=d,s=t,n===s||n.startsWith(`${s}:`))&&(i+=l,a.add(d))}return{usagePercent:aJ(i),measuredAt:r,method:a5,matchedProcesses:[...a]}}(e.stdout,t,new Date().toISOString())}catch(e){throw a7("cpu",t,e)}}async function a9(e,t,r={}){let a=L(e,r.adb);try{let e=await a(["shell","dumpsys","meminfo",t],{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new J("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=ie(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!==it(e));if(!r)break;return it(r)??void 0}}(e);if(void 0===a)throw new J("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:ie(e,"TOTAL RSS"),measuredAt:r,method:a4}}(e.stdout,t,new Date().toISOString())}catch(e){throw a7("memory",t,e)}}function a7(e,t,r){return r instanceof J?new J(r.code,r.message,{...r.details??{},metric:e,package:t},r):new J("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function ie(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return it(a[1])??void 0}function it(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}async function ir(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return G(t)?"macos"===e.platform?void 0:"device"===e.kind?T(r,t):void 0:await ia(e,t)}async function ia(e,t){try{let{resolveIosApp:r}=await import("../6108.js");return await r(e,t)}catch{return}}async function ii(e,t){if(!("android"!==e.platform||!t||G(t)))try{let{resolveAndroidApp:r}=await import("../6108.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function is(e,t,r){if(r||"android"!==e.platform||!t||!G(t))return r;try{let{getAndroidAppState:t}=await import("../6108.js"),a=await t(e);return a.package?.trim()||r}catch{return r}}async function io(e,t,r,a){return await ir(e,t,r)??await a(e,t)??("android"===e.platform&&t&&G(t)?r:void 0)}function il(e){return eh("INVALID_ARGS",e)}function id(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=tl(r);if(!az.has(e))throw new J("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new J("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new J("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?tl(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new J("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 J?e.code:"INVALID_ARGS",String(e.message))}}function iu(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&G(r)?il("open --relaunch does not support URL targets."):"app"!==a?il("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===$(r)?il(q(r)):null:null}async function ic(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:s,existingSession:o}=e;await eB(i);let{appBundleId:l,appName:d}=await ip({device:i,surface:n,openTarget:s,existingAppBundleId:o?.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),s=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 J("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!aF.includes(e));if(i)throw new J("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${aF.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new J("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new J("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:aV(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new J("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return aG(e)}}(t.metroPort),bundleUrl:aV(t.bundleUrl,"bundleUrl"),launchUrl:aV(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:aj(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=aj(i);if(a.platform&&r&&!n)throw new J("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 J("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:s&&aU(s)>0?s:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=z(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(o){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await aq({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:o})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function ip(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await aW(r);return{appBundleId:n.appBundleId??await io(t,a,i,ii),appName:n.appName??a}}let im=new Map;async function ih(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await ed(t.id),await ea(t,"close",[r],a,i),await af(t,ao)}async function ig(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:s,openPositionals:o}=e,l=t?.launchUrl;if(!l||0===o.length||o.length>1)return;let d=o[0]?.trim();!d||G(d)||await ea(r,"open",[l],a.flags?.out,{...eO(i,a.flags,n,s)})}async function iw(e){var t,r,a,i;let{req:n,sessionName:s,sessionStore:o,logPath:l,device:d,openTarget:u,openPositionals:c,appName:f,surface:p,appBundleId:m,runtime:h,existingSession:g}=e,w=n.flags?.relaunch===!0,y=g?.trace?.outPath,v=m;if(w&&u){let e=v??u;await ih({device:d,closeTarget:e,outFlag:n.flags?.out,context:{...eO(l,n.flags,v??g?.appBundleId,y)}})}await a_({device:d,appId:v,runtime:h});let S=Date.now();await ea(d,"open",c,n.flags?.out,{...eO(l,n.flags,v)}),await ig({runtime:h,device:d,req:n,logPath:l,appBundleId:v,traceLogPath:y,openPositionals:c}),v=await is(d,u,v),"android"===d.platform&&v&&await a3(d,v);let I=u?(t=v,{durationMs:Math.max(0,Date.now()-S),measuredAt:new Date().toISOString(),method:aB,appTarget:u,appBundleId:t}):void 0;if(await af(d,al),e$(n.meta?.requestId)){let e=ef();return eh(e.code,e.message,e.details)}g&&e9(g,"open",g.snapshot);let A=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:s,saveScript:o}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:s,recordSession:t.recordSession||o,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:s,recordSession:o,actions:[]}}({existingSession:g,sessionName:s,device:d,surface:p,appBundleId:v,appName:f,saveScript:!!n.flags?.saveScript});void 0!==n.runtime&&(r=o,a=s,(i=h)&&(0===aU(i)?r.clearRuntimeHints(a):r.setRuntimeHints(a,i)));let b=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:s,runtime:o,runtimeHintCount:l}=e,d={session:t,surface:i};return r&&(d.appName=r),a&&(d.appBundleId=a),n&&(d.startup=n),o&&l(o)>0&&(d.runtime=o),s&&(d.platform=s.platform,d.target=s.target??"mobile",d.device=s.name,d.id=s.id,d.kind=s.kind,"android"===s.platform&&(d.serial=s.id)),s?.platform==="ios"&&(d.device_udid=s.id,d.ios_simulator_device_set=s.simulatorSetPath??null),{...d,...ti(`Opened: ${r??a??t}`)}}({sessionName:s,appName:f,appBundleId:v,surface:p,startup:I,device:d,runtime:h,runtimeHintCount:aU});return o.recordAction(A,{command:"open",positionals:c,flags:n.flags??{},runtime:void 0!==n.runtime?h:void 0,result:b}),o.set(s,A),{ok:!0,data:b}}async function iy(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,s=t.positionals?.[0],o=s??(n?e.appName:void 0),l=id(e.device,t.flags?.surface,o,e.surface);if("string"!=typeof l)return l;if(!o&&"app"===l)return n?il("open --relaunch requires an app name or an active session app."):il("Session already active. Close it first or pass a new --session name.");let d=iu({shouldRelaunch:n,openTarget:o,surface:l,device:e.device});if(d)return d;let u=await am(e.device),c=await ic({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:o,existingSession:e});return"response"===c.type?c.response:await iw({req:t,sessionName:r,sessionStore:i,logPath:a,device:u,openTarget:o,openPositionals:s?t.positionals??[]:o?[o]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let n=t.flags?.relaunch===!0,s=t.positionals?.[0];if(n&&!s)return il("open --relaunch requires an app argument.");let o=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&G(r)?il("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===$(r)?il(q(r)):null:null}({shouldRelaunch:n,openTarget:s,platform:t.flags?.platform==="android"?"android":void 0});if(o)return o;let l=await ey(t.flags??{}),d=id(l,t.flags?.surface,s);if("string"!=typeof d)return d;let u=iu({shouldRelaunch:n,openTarget:s,surface:d,device:l});return u||await ev(im,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 ic({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:s});return"response"===n.type?n.response:await iw({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:s,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:d})})}async function iv(e){let t=await E(e,["emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function iS(e){let{device:t,shutdownRequested:r}=e;if(r&&(ac(t)||"android"===t.platform&&"emulator"===t.kind))try{return ac(t)?await el(t):await iv(t)}catch(t){let e=W(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function iI(e){if(await ed(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await e_("dismiss",t).catch(t=>{b({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function iA(e,t){e.appLog&&await rb(e.appLog),e2(e.device.platform)&&await iI(e),await at(t).catch(()=>{})}async function ib(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 rb(n.appLog),t.positionals&&t.positionals.length>0&&(e2(n.device.platform)&&await iI(n),await ea(n.device,"close",t.positionals,t.flags?.out,{...eO(a,t.flags,n.appBundleId,n.trace?.outPath)}),await af(n.device,ao)),e2(n.device.platform)&&await iI(n),ab(i.getRuntimeHints(r))&&n.appBundleId&&await aN({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...ti(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await at(r).catch(()=>{}),i.delete(r);let s=await iS({device:n.device,shutdownRequested:t.flags?.shutdown});return s?{ok:!0,data:te({session:r,shutdown:s},`Closed: ${r}`)}:{ok:!0,data:{session:r,...ti(`Closed: ${r}`)}}}let i_={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("../6108.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("../6108.js");return await a(e,t,r)}},iN={ios:async(e,t,r)=>{let{installIosApp:a}=await import("../6108.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("../6108.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function iM(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:s}=e,o=n.get(a),l=t.flags??{},d=ad(r,o,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?rk(f,t.meta?.tenantId):tz.expandHome(c);if(!i.existsSync(a))return eh("INVALID_ARGS",`App binary not found: ${a}`);let d=await ap({session:o,flags:l,ensureReady:!1});if(!e0(r,d))return eh("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await s.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 s.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??ts(p)}`));return o&&n.recordAction(o,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&rP(f)}}async function ix(e,t,r){return await td(e,t,r)}async function iD(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:s,reuseExisting:o,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new J("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:s??void 0};if(o){let e=await ik({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await iP({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await iR(t,u),a=!0)}else t=(await iP({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await iR(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...s?{simulatorSetPath:s}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function ik(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await Q("xcrun",er(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:eY});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||iL(a).includes(iL(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 iP(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await Q("xcrun",er(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new J("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 s=String(n.stdout??"").trim();if(!s)throw new J("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:s}}async function iR(e,t){let r=await Q("xcrun",er(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:eY});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 iL(e){return e.toLowerCase().replace(/[._-]/g,"")}async function iO(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,i=C(e.iosSimulatorDeviceSet);if(!r)return eh("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await iD({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:eB});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=z(t);return eh(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=V(t.flags?.androidDeviceAllowlist),a=e3(t.flags?.platform),i=et({simulatorSetPath:C(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("../8809.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("../6108.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("../8809.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("../6108.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,s=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:s}}}catch(t){let e=z(t);return eh(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=ad(t.command,e,i);if(n)return n;let s=await ap({session:e,flags:i,ensureReady:!0});if(!e0("apps",s))return eh("UNSUPPORTED_OPERATION","apps is not supported on this device");let o=t.flags?.appsFilter??"all";if(e2(s.platform)){let{listIosApps:e}=await import("../6108.js");return{ok:!0,data:{apps:(await e(s,o)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await import("../6108.js");return{ok:!0,data:{apps:(await l(s,o)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function iE(e){let{ensureAndroidEmulatorBooted:t}=await import("../8809.js");return await t(e)}let iC='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',i$='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function iT(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},s=e3(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return eh("SESSION_NOT_FOUND","ios"===s?`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 o=ad("appstate",i,n);if(o)return o;let l=e2(i?.device.platform)&&function(e,t){if(!t)return!1;if(!au(e))return!0;let r=e3(e?.platform);return!(r&&!eQ(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"===s&&!l)return eh("SESSION_NOT_FOUND",iC);if("macos"===s&&!l)return eh("SESSION_NOT_FOUND",i$);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 ap({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return eh("SESSION_NOT_FOUND",iC);if("macos"===d.platform)return eh("SESSION_NOT_FOUND",i$);let{getAndroidAppState:u}=await import("../6108.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function iF(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},s=ad(t.command,i,n);if(s)return s;let o="android"===(e3(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!o)return eh("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=ah({flags:n,sessionDevice:i?.device}),u=o&&!!d,c=!1;try{e=await ap({session:i,flags:n,ensureReady:!1})}catch(r){let t=z(r);if(o&&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 iE({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(o&&l){if("android"!==e.platform||"emulator"!==e.kind)return eh("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=ah({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 iE({avdName:t,serial:n.serial,headless:!0})}await eB(e)}else("android"!==e.platform||!0!==e.booted)&&await eB(e);return e0("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 iT({req:t,sessionName:r,sessionStore:a}):null}function iU(e,t){for(let r of e){if(t(r))return r;let e=iU(r.children,t);if(e)return e}}function iV(e,t){let r=[];for(let a of e)t(a)&&r.push(a),r.push(...iV(a.children,t));return r}function iG(e,t){let r=iU(e,e=>"schema"===e.name&&e.attributes.name===t);return r?r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}):[]}function ij(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 iq(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:ij(e):null}let iH="xctrace-animation-hitches";function iB(e,t){let r=eZ(e),a=iG(r,t);return{rows:0===a.length?[]:iV(r,e=>"row"===e.name),schema:a}}function iK(e,t){for(let r of e)iK(r.children,t),r.attributes.id&&t.set(r.attributes.id,{numberValue:ij(r),process:iz(r)})}function iz(e){if(!e||e.children.some(e=>"sentinel"===e.name))return null;let t=ij(iU(e.children,e=>"pid"===e.name)),r=(e.attributes.fmt??"").replace(/\s+\(\d+\)$/,"").trim();return null===t&&0===r.length?null:{pid:t??void 0,name:r.length>0?r:void 0}}let iW="ps-process-snapshot",iJ="ps-process-snapshot",iZ="xctrace-activity-monitor",iX="xctrace-activity-monitor";async function iY(e,t){if("ios"===e.platform&&"device"===e.kind)return await i9(e,t);let r=await i6(e,t),a=await ni(e,r);if(0===a.length)throw new J("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();return nn({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:[r.executableName],cpuMethod:iW,memoryMethod:iJ})}async function iQ(e,t){var r;let a,i,n,o,l,u;if("ios"!==e.platform||"device"!==e.kind)throw new J("COMMAND_FAILED","Apple frame-health sampling is currently available only on connected iOS devices.",{metric:"fps",platform:e.platform,deviceKind:e.kind});let c=await i7(e,t),f=await i0(e,t,c);return a=iB((r={hitchesXml:f.hitchesXml,frameLifetimesXml:f.frameLifetimesXml,displayInfoXml:f.displayInfoXml,processIds:c.map(e=>e.pid),processNames:tx(c.map(e=>s.basename(d(e.executable)))),windowStartedAt:f.windowStartedAt,windowEndedAt:f.windowEndedAt,measuredAt:f.windowEndedAt}).frameLifetimesXml,"hitches-frame-lifetimes").rows.length,i=function(e){if(!e)return;let{rows:t,schema:r}=iB(e,"device-display-info"),a=r.indexOf("max-refresh-rate");if(a<0)return;let i=new Map;for(let e of t){iK(e.children,i);let t=iq(e.children[a],i);if(null!==t&&t>0)return t}}(r.displayInfoXml),o=(n=(function(e){let t,r,a=eZ(e),i=Object.values(r={start:(t=iG(a,"hitches")).indexOf("start"),duration:t.indexOf("duration"),process:t.indexOf("process"),isSystem:t.indexOf("is-system")}).every(e=>e>=0)?r:null;if(!i)return[];let n=new Map;return iV(a,e=>"row"===e.name).map(e=>(function(e,t,r){var a,i,n;let s;if(iK(e.children,r),!0===(a=e.children[t.isSystem],null===(s=iq(a,r))?null:0!==s))return null;let o=iq(e.children[t.start],r),l=iq(e.children[t.duration],r);if(null===o||null===l)return null;let d=(i=e.children[t.process],n=r,i?i.attributes.ref?n.get(i.attributes.ref)?.process??null:iz(i):null);return{startNs:o,durationNs:l,pid:d?.pid,processName:d?.name}})(e,i,n)).filter(e=>!!e)})(r.hitchesXml).filter(e=>{var t,a,i;return t=e,a=r.processIds,i=r.processNames,!!(void 0!==t.pid&&a.includes(t.pid))||!!t.processName&&i.includes(t.processName)})).length,l=Math.max(0,Math.round(Date.parse(r.windowEndedAt)-Date.parse(r.windowStartedAt))),u=function(e,t){if(0===e.length)return[];let r=[...e].sort((e,t)=>e.startNs-t.startNs),a=[],i=[];for(let e of r){let t=i.at(-1);if(!t||e.startNs-(t.startNs+t.durationNs)<=5e8){i.push(e);continue}a.push(i),i=[e]}return i.length>0&&a.push(i),a.map(e=>{var r,a;let i,n,s,o;return r=e,a=t,i=Math.min(...r.map(e=>e.startNs)),n=Math.max(...r.map(e=>e.startNs+e.durationNs)),o=Math.max(s=Math.max(0,Math.round(i/1e6)),Math.round(n/1e6)),{startOffsetMs:s,endOffsetMs:o,startAt:new Date(a+s).toISOString(),endAt:new Date(a+o).toISOString(),missedDeadlineFrameCount:r.length,worstFrameMs:aJ(Math.max(...r.map(e=>e.durationNs))/1e6)}}).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}(n,Date.parse(r.windowStartedAt)),{droppedFramePercent:a>0?aJ(o/a*100):0,droppedFrameCount:o,totalFrameCount:a,sampleWindowMs:l,windowStartedAt:r.windowStartedAt,windowEndedAt:r.windowEndedAt,measuredAt:r.measuredAt,method:iH,matchedProcesses:[...new Set(n.map(e=>e.processName).filter(e=>"string"==typeof e&&e.length>0))],frameDeadlineMs:void 0===i?void 0:aJ(1e3/i),refreshRateHz:i,worstWindows:u.length>0?u:void 0}}async function i0(e,t,r){let a=await n.mkdtemp(s.join(c.tmpdir(),"agent-device-ios-frame-perf-")),i=s.join(a,"animation-hitches.trace"),o=s.join(a,"hitches.xml"),l=s.join(a,"frame-lifetimes.xml"),d=s.join(a,"display-info.xml");try{let a=await i1({device:e,appBundleId:t,tracePath:i,template:"Animation Hitches",duration:"2s",targetPids:r.map(e=>e.pid),validateTraceOutput:!0,failureMessage:`Failed to record iOS frame-health sample for ${t}`});await i3(e,t,i,"hitches",o),await i3(e,t,i,"hitches-frame-lifetimes",l);let s=await i5(e,t,i,"device-display-info",d);return{windowStartedAt:a.startedAt,windowEndedAt:a.endedAt,hitchesXml:await n.readFile(o,"utf8"),frameLifetimesXml:await n.readFile(l,"utf8"),displayInfoXml:s?await n.readFile(d,"utf8"):void 0}}finally{await n.rm(a,{recursive:!0,force:!0}).catch(()=>{})}}async function i1(e){let{device:t,appBundleId:r,tracePath:a,template:i,duration:n}=e,s=e.allProcesses?["--all-processes"]:(e.targetPids??[]).flatMap(e=>["--attach",String(e)]),o=["xctrace","record","--template",i,"--device",t.id,...s,"--time-limit",n,"--output",a,"--quiet","--no-prompt"],l=await i2(o,e.tracePath);if(0===l.result.exitCode)return e.validateTraceOutput&&await i8(e,l.result.stdout,l.result.stderr),{startedAt:l.startedAt,endedAt:l.endedAt,capturedAtMs:l.capturedAtMs};throw new J("COMMAND_FAILED",e.failureMessage,{cmd:"xcrun",args:o,exitCode:l.result.exitCode,stdout:l.result.stdout,stderr:l.result.stderr,appBundleId:r,deviceId:t.id,hint:no(l.result.stdout,l.result.stderr)})}async function i2(e,t){let r;for(let a=1;a<=3;a+=1){a>1&&(await n.rm(t,{recursive:!0,force:!0}).catch(()=>{}),await new Promise(e=>setTimeout(e,1500)));let i=new Date().toISOString(),s=await Q("xcrun",e,{allowFailure:!0,timeoutMs:6e4});if(r={result:s,startedAt:i,endedAt:new Date().toISOString(),capturedAtMs:Date.now()},0===s.exitCode||!function(e){let t=`${e.stdout}
9
- ${e.stderr}`.toLowerCase();return t.includes("_lockkperf")||t.includes("could not lock kperf")||t.includes("likely another session just started")}(s))break}return r}async function i8(e,t,r){let a=await n.stat(e.tracePath).catch(()=>null);if(!(a?.isDirectory()===!0?(await n.readdir(e.tracePath).catch(()=>[])).length>0:(a?.size??0)>0))throw new J("COMMAND_FAILED",`${e.failureMessage}: xctrace produced no trace data`,{tracePath:e.tracePath,appBundleId:e.appBundleId,deviceId:e.device.id,stdout:t,stderr:r,hint:"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf."})}async function i3(e,t,r,a,i){let n=["xctrace","export","--input",r,"--xpath",`/trace-toc/run/data/table[@schema="${a}"]`,"--output",i],s=await Q("xcrun",n,{allowFailure:!0,timeoutMs:15e3});if(0!==s.exitCode)throw new J("COMMAND_FAILED",`Failed to export iOS device ${a} data`,{cmd:"xcrun",args:n,exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr,appBundleId:t,deviceId:e.id,hint:no(s.stdout,s.stderr)})}async function i5(e,t,r,a,i){try{return await i3(e,t,r,a,i),!0}catch{return!1}}async function i4(e){let t=eZ(e),r=iG(t,"activity-monitor-process-live");if(0===r.length)throw new J("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.indexOf("pid"),i=r.indexOf("process"),n=r.indexOf("cpu-total"),s=r.indexOf("memory-real");if(a<0||i<0||n<0||s<0)throw new J("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let o=iV(t,e=>"row"===e.name),l=[],d=new Map;for(let e of o){var u,c;let t=e.children;if(0===t.length)continue;for(let e of t){let t=iU(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);d.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&d.set(e.attributes.id,{numberValue:ij(e),processName:ns(e)})}let r=iq(t[a],d),o=(u=t[i],c=d,u?u.attributes.ref?c.get(u.attributes.ref)?.processName??null:ns(u):null);null!==r&&Number.isFinite(r)&&o&&l.push({pid:r,processName:o,cpuTimeNs:iq(t[n],d),residentMemoryBytes:iq(t[s],d)})}return l}async function i6(e,t){let r="macos"===e.platform?await nr(t):await na(e,t),a="macos"===e.platform?s.join(r,"Contents","Info.plist"):s.join(r,"Info.plist"),i=await eK(a,"CFBundleExecutable");if(!i)throw new J("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?s.join(r,"Contents","MacOS",i):s.join(r,i)}}async function i9(e,t){let r=await i7(e,t),a=await ne(e,t),i=await ne(e,t),n=nt(await i4(a.xml),r,t,e),s=nt(await i4(i.xml),r,t,e),o=i.capturedAtMs-a.capturedAtMs;if(o<=0)throw new J("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===s.cpuTimeNs||null===s.residentMemoryBytes)throw new J("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 nn({usagePercent:Math.max(0,s.cpuTimeNs-n.cpuTimeNs)/(1e6*o)*100,residentMemoryKb:s.residentMemoryBytes/1024,measuredAt:new Date(i.capturedAtMs).toISOString(),matchedProcesses:s.matchedProcesses,cpuMethod:iZ,memoryMethod:iX})}async function i7(e,t){let r=(await e1(e,"all")).find(e=>e.bundleId===t);if(!r)throw new J("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new J("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await e8(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new J("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 ne(e,t){let r=await n.mkdtemp(s.join(c.tmpdir(),"agent-device-ios-perf-")),a=s.join(r,"sample.trace"),i=s.join(r,"activity-monitor-process-live.xml");try{let r=await i1({device:e,appBundleId:t,tracePath:a,template:"Activity Monitor",duration:"1s",allProcesses:!0,failureMessage:`Failed to record iOS device Activity Monitor sample for ${t}`});return await i3(e,t,a,"activity-monitor-process-live",i),{capturedAtMs:r.capturedAtMs,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function nt(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>s.basename(d(e.executable)))),o=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===o.length)throw new J("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 o){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:nl(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:nl(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:tx(u.map(e=>e.processName))}}async function nr(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await Q("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new J("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 J("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function na(e,t){let r=eW(e,["get_app_container",e.id,t,"app"]),a=await Q("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new J("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 J("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function ni(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:eW(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]),s=Number(a[3]),o=a[4].trim();Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(s)&&t.push({pid:i,cpuPercent:n,rssKb:s,command:o})}return t})((await Q("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=function(e){let[t=""]=e.trim().split(/\s+/,1);return t}(r),!!(a.executablePath&&(r===a.executablePath||i===a.executablePath||r.startsWith(`${a.executablePath} `)))||s.basename(i)===a.executableName})}function nn(e){return{cpu:{usagePercent:aJ(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 ns(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function no(e,t){let r=eg(e,t);if(r)return r;let a=`${e}
10
- ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?eR: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 nl(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function nd(e,t={}){var r,a,i;let n,s,o,l,d=(o=(s=(n=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===aB&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:aB,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)}((r=e).actions)).at(-1))?{available:!0,lastDurationMs:s.durationMs,lastMeasuredAt:s.measuredAt,method:aB,sampleCount:n.length,samples:n}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:aB},{session:r.name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{startup:o,fps:{available:!1,reason:"Dropped-frame sampling is currently available only on Android."},memory:{available:!1,reason:aK},cpu:{available:!1,reason:aK}},sampling:{startup:{method:aB,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:a4,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:a5,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:aX,description:"Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.",unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}};var t=e.device;let r="ios"===t.platform&&"device"===t.kind?{method:iH,description:"Rendered-frame hitch health from xctrace Animation Hitches on connected iOS devices. Dropped frames are counted from native hitch rows for the attached app process, with total frames from the same trace frame-lifetime table.",unit:"percent",primaryField:"droppedFramePercent",window:"short 2s xctrace Animation Hitches record of the active app process",resetsAfterRead:!1}:{method:iH,description:"Unavailable on iOS simulators and macOS because local Apple tooling does not expose reliable app frame hitches for these targets.",unit:"percent",primaryField:"droppedFramePercent"};if("ios"===t.platform&&"device"===t.kind)return{fps:r,memory:{method:iX,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:iZ,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let a="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{fps:r,memory:{method:iJ,description:`Resident memory snapshot from ${a}`,unit:"kB"},cpu:{method:iW,description:`Recent CPU usage snapshot from ${a}`,unit:"percent"}}}(r)}});return"android"!==(a=e).device.platform&&"ios"!==a.device.platform&&"macos"!==a.device.platform||(e.appBundleId?"android"===e.device.platform?await nu(d,e,t):await nc(d,e):(i=d,l="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.",i.metrics.fps={available:!1,reason:l},i.metrics.memory={available:!1,reason:l},i.metrics.cpu={available:!1,reason:l})),d}async function nu(e,t,r){let a=await nf(t,r);e.metrics.memory=nh(a.memory),e.metrics.cpu=nh(a.cpu),e.metrics.fps=ng(nh(a.fps),t)}async function nc(e,t){let r=await np(t);e.metrics.memory=nh(r.memory),e.metrics.cpu=nh(r.cpu),e.metrics.fps=ng(nh(r.fps),t)}async function nf(e,t){let r=e.appBundleId,a={adb:t.androidAdb},[i,n,s]=await Promise.allSettled([a9(e.device,r,a),a6(e.device,r,a),a8(e.device,r,a)]);return{memory:i,cpu:n,fps:s}}async function np(e){let t=e.appBundleId,r=await nm(iQ(e.device,t)),a=await nm(iY(e.device,t));if("fulfilled"===a.status){let e=a.value;return{memory:{status:"fulfilled",value:e.memory},cpu:{status:"fulfilled",value:e.cpu},fps:r}}return{memory:{status:"rejected",reason:a.reason},cpu:{status:"rejected",reason:a.reason},fps:r}}async function nm(e){try{return{status:"fulfilled",value:await e}}catch(e){return{status:"rejected",reason:e}}}function nh(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=W(e.reason);return{available:!1,reason:t.message,error:t}}function ng(e,t){var r,a;let i,n;if(!0!==e.available)return e;let s=(r=t.actions,i=nw((a=e).windowStartedAt),n=nw(a.windowEndedAt)??nw(a.measuredAt),void 0===i||void 0===n?[]:r.filter(e=>e.ts>=i&&e.ts<=n).map(e=>({command:e.command,at:new Date(e.ts).toISOString(),offsetMs:Math.max(0,Math.round(e.ts-i)),target:function(e){let t=e.result;if(t)for(let e of["refLabel","ref","appName","appBundleId"]){let r=t[e];if("string"==typeof r&&r.length>0)return r}}(e)})).slice(-12));return 0===s.length?e:{...e,relatedActions:s}}function nw(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let ny=["path","start","stop","doctor","mark","clear"],nv=`logs requires ${ny.slice(0,-1).join(", ")}, or ${ny.at(-1)}`,nS=["dump","log"],nI=`network requires ${nS.join(" or ")}`,nA=["summary","headers","body","all"],nb=`network include mode must be one of: ${nA.join(", ")}`;async function n_(e){let{req:t}=e;return"perf"===t.command?nN(e):"logs"===t.command?nM(e):"network"===t.command?nR(e):null}async function nN(e){let{sessionName:t,sessionStore:r,androidAdbExecutor:a}=e,i=r.get(t);if(!i)return eh("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await nd(i,{androidAdb:a})}}catch(e){return{ok:!1,error:W(e)}}}async function nM(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(!e0("logs",n.device))return eh("UNSUPPORTED_OPERATION","logs is not supported on this device");let s=(t.positionals?.[0]??"path").toLowerCase(),o=!!t.flags?.restart;return ny.includes(s)?o&&"clear"!==s?eh("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===s?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"===s?nx(n,r,a):"mark"===s?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",s=r.resolveAppLogPath(t);return ry(s),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
11
- `,i.appendFileSync(s,a,"utf8"),{ok:!0,data:{path:s,marked:!0}}}(t,r,a):"clear"===s?nD(n,r,a,o):"start"===s?nk(n,r,a):"stop"===s?nP(n,r,a):eh("INVALID_ARGS",nv):eh("INVALID_ARGS",nv)}async function nx(e,t,r){let a=r.resolveAppLogPath(t),i=await r_(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 nD(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:rN(i)};e.appLog&&await rb(e.appLog);let n=rN(i),s=r.resolveAppLogPidPath(t);try{let a=await rI(e.device,e.appBundleId,i,s);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:W(a)}}}async function nk(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 rI(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:W(e)}}}async function nP(e,t,r){if(!e.appLog)return eh("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rb(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function nR(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(!e0("network",i.device))return eh("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!nS.includes(n))return eh("INVALID_ARGS",nI);let s=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(s)||s<1||s>200)return eh("INVALID_ARGS","network dump limit must be an integer in range 1..200");let o=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 nA.includes(a)?{ok:!0,include:a}:eh("INVALID_ARGS",nb)}(t);if(!o.ok)return o;let{include:l}=o,d=await rv({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:s,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 nL=/^[A-Z_][A-Z0-9_]*$/,nO=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-((?:[^}\\]|\\.)*))?\}/g,nE="AD_VAR_";function nC(e){return e.startsWith("AD_")}function n$(e){return new J("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function nT(e,t,r){return e.replace(nO,(e,a,i,n)=>{if(a)return"${";if(!i)return e;if(Object.prototype.hasOwnProperty.call(t.values,i))return t.values[i];if(void 0!==n)return n.replace(/\\(.)/g,"$1");throw new J("INVALID_ARGS",`Unresolved variable \${${i}} at ${r.file}:${r.line}.`)})}function nF(e,t,r){if(!e)return e;let a={...e};for(let[e,i]of Object.entries(a))"string"==typeof i&&(a[e]=nT(i,t,r));return a}let nU=new Set(["ios","android","macos","linux"]);function nV(e){let t=e.split(/\r?\n/),r={};for(let e=0;e<t.length;e+=1){let a=t[e].trim();if(0===a.length||a.startsWith("#"))continue;if(nG(a)){!function(e,t,r){let{key:a,value:i}=function(e,t){let r=e.slice(3).replace(/^[\s]+/,""),a=r.indexOf("=");if(a<=0)throw new J("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let i=r.slice(0,a);if(!nL.test(i))throw new J("INVALID_ARGS",`Invalid env key "${i}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(i.startsWith("AD_"))throw new J("INVALID_ARGS",`Invalid env key "${i}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${i} to avoid the AD_ prefix.`);return{key:i,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new J("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(r.slice(a+1),t)}}(t,r),n=e.env??{};if(Object.prototype.hasOwnProperty.call(n,a))throw new J("INVALID_ARGS",`Duplicate env directive "${a}" on line ${r}.`);n[a]=i,e.env=n}(r,a,e+1);continue}if(!a.startsWith("context "))break;let i=a.match(/(?:^|\s)platform=([^\s]+)/);if(i){let e=i[1];e&&nU.has(e)&&nj(r,"platform",e)}let n=a.match(/(?:^|\s)timeout=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=1&&nj(r,"timeoutMs",Math.floor(e))}let s=a.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&nj(r,"retries",Math.floor(e))}}return r}function nG(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function nj(e,t,r){let a=e[t];if(void 0!==a)throw new J("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 nq(e){return!!e&&!Number.isNaN(Number(e))}let nH=/[*?[\]{}]/;async function nB(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:s,artifactsDir:o,runReplay:l,cleanupSession:d}=e;em(i);let u=new Set,c=!1,f=l({filePath:r,sessionName:a,platform:s,requestId:i,artifactsDir:o,artifactPaths:u}).catch(e=>{let t=z(e);return eh(t.code,t.message)}).finally(()=>{ez(i)});try{return"number"==typeof n?await Promise.race([f,new Promise(e=>{t=setTimeout(()=>{c=!0,ej(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,[...u]))},n)})]):await f}finally{t&&clearTimeout(t),c&&(await nK(f)||b({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await d(a)}catch(e){b({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:z(e).message}})}}}async function nK(e){return await Promise.race([e.then(()=>!0),g(2e3).then(()=>!1)])}async function nz(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 o,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(),o=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tz.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>s.join(n,e));if(t.isFile()){if(".ad"!==s.extname(n))throw new J("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!nH.test(r)&&(a=n,!nH.test(a)))throw new J("INVALID_ARGS",`test input not found: ${e}`);let o=s.isAbsolute(n)?n:e;return i.globSync(o,{cwd:s.isAbsolute(n)?void 0:t}).map(e=>s.isAbsolute(e)?e:s.resolve(t,e)).filter(e=>".ad"===s.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>s.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of o){var d,u;let t=nV(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 J("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(o=t.meta?.requestId,(o?.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=tz.expandHome(t??".agent-device/test-artifacts",r);return s.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 nW({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=z(t);return eh(e.code,e.message)}}async function nW(e){var t,r;let a,n,{entry:o,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=s.join(h,(t=o.path,(0===(n=c?s.relative(c,t):s.basename(t)).length||n.startsWith("..")?s.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=s.basename(r,s.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,d,o.path,u,e),n=s.join(v,`attempt-${I}`);r=o.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,s.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eC(`${t??r}:test:${i+1}:${s.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:o.path,caseIndex:u,attemptIndex:e}),h=await nB({filePath:o.path,sessionName:t,requestId:c,timeoutMs:m,platform:o.metadata.platform,artifactsDir:n,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:o,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=s.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}`}(s.basename(n),a),o=s.join(t,e);s.resolve(n)!==s.resolve(o)&&i.copyFileSync(n,o),r.push(o)}return r}(d,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${o}`,`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=>s.basename(e)).join(", ")}`);let f=s.join(l,"result.txt"),p=`${c.join("\n")}
12
- `;i.writeFileSync(f,p),t.ok||i.writeFileSync(s.join(l,"failure.txt"),p)}({response:h,filePath:o.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:o.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:o.path,session:S,status:"failed",durationMs:A,attempts:I,artifactsDir:v,error:b}}function nJ(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=tc(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 nZ(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(tO(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let n=i.get(r);if(!n)return null;let s=(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),tO(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}=tm(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=nJ(e.positionals??[]);r&&t.push(r)}return tx(t).filter(e=>e.trim().length>0)})(t).map(e=>th(e)).filter(e=>null!==e);if(0===s.length)return null;let o=tO(t.command)||"fill"===t.command,l=tO(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await nX(n,t,a,o,i);for(let e of s){let r=tg(d.nodes,e,{platform:n.device.platform,requireRect:o,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=ty(r.node,n.device.platform,{action:tO(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tO(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}=tm(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}=nJ(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function nX(e,t,r,a,i){let n=await ea(e.device,"snapshot",[],t.flags?.out,{...eO(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),s=n?.nodes??[],o={nodes:tI(t.flags?.snapshotRaw?s:tS(s)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return eS(e,o),i.set(e.name,e),o}async function nY(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o}=e,l=t.positionals?.[0];if(!l)return eh("INVALID_ARGS","replay requires a path");let d="",u=new Set;try{var c;let e;d=tz.expandHome(l,t.meta?.cwd);let f=i.readFileSync(d,"utf8"),p=f.trimStart()[0];if("{"===p||"["===p)return eh("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let m=nV(f),h=function(e){let t=[],r=[],a=e.split(/\r?\n/),i=!1;for(let e=0;e<a.length;e+=1){let n=a[e],s=n.trim();if(0===s.length||s.startsWith("#"))continue;if(nG(s)){if(i)throw new J("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let o=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 J("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=tH(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=tH(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(tO(a)){let e=tq(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],s=e.positionals[1];return nq(r)&&nq(s)&&e.positionals.length>=2?n.positionals=[r,s]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tq(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=tq(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 J("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}(n);o&&(t.push(o),r.push(e+1),i=!0)}return{actions:t,actionLines:r}}(f),g=h.actions,w=h.actionLines;if(t.flags?.replayUpdate===!0&&m.env&&Object.keys(m.env).length>0)return eh("INVALID_ARGS","replay -u does not yet preserve env directives. Temporarily remove the env lines, run replay -u, then restore them.");if(t.flags?.replayUpdate===!0&&function(e){for(let t of e){for(let e of t.positionals??[])if("string"==typeof e&&e.includes("${"))return!0;if(t.flags){for(let e of Object.values(t.flags))if("string"==typeof e&&e.includes("${"))return!0}if(t.runtime){for(let e of Object.values(t.runtime))if("string"==typeof e&&e.includes("${"))return!0}}return!1}(g))return eh("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let y=function(e){let t={};if(e.builtins)for(let[r,a]of Object.entries(e.builtins))t[r]=a;for(let r of[e.fileEnv,e.shellEnv,e.cliEnv])if(r)for(let[e,a]of Object.entries(r)){if(nC(e))throw n$(e);t[e]=a}return{values:t}}({builtins:function(e){let{req:t,sessionName:r,metadata:a,resolvedPath:i}=e,n=t.flags??{},o=t.meta?.cwd??process.cwd(),l={AD_SESSION:r,AD_FILENAME:s.relative(o,i)||i},d=n.platform??a.platform;d&&(l.AD_PLATFORM=d);let u=n.device;"string"==typeof u&&u.length>0&&(l.AD_DEVICE=u);let c=n.artifactsDir;return"string"==typeof c&&c.length>0&&(l.AD_ARTIFACTS=c),l}({req:t,sessionName:r,metadata:m,resolvedPath:d}),fileEnv:m.env,shellEnv:function(e){let t={};for(let[r,a]of Object.entries(e)){if("string"!=typeof a||!r.startsWith(nE))continue;let e=r.slice(nE.length);0!==e.length&&nL.test(e)&&(nC(e)||(t[e]=a))}return t}(function(e){let t=e.flags?.replayShellEnv;if(t&&"object"==typeof t&&!Array.isArray(t)){let e={};for(let[r,a]of Object.entries(t))"string"==typeof a&&(e[r]=a);return e}return process.env}(t)),cliEnv:function(e){let t={};for(let r of e){let e=r.indexOf("=");if(e<=0)throw new J("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let a=r.slice(0,e);if(!nL.test(a))throw new J("INVALID_ARGS",`Invalid -e key "${a}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(nC(a))throw n$(a);t[a]=r.slice(e+1)}return t}((c=t,e=c.flags?.replayEnv,Array.isArray(e)?e.filter(e=>"string"==typeof e):[]))}),v=t.flags?.replayUpdate===!0,S=0;for(let e=0;e<g.length;e+=1){let i=g[e];if(!i||"replay"===i.command)continue;let s=await nQ({req:t,sessionName:r,action:i,scope:y,filePath:d,line:w[e]??0,invoke:o});if(s.ok){n1(s).forEach(e=>u.add(e));continue}if(!v)return n0(s,i,e,d,[...u]);let l=await nZ({action:i,sessionName:r,logPath:a,sessionStore:n});if(!l)return n0(s,i,e,d,[...u]);if(g[e]=l,!(s=await nQ({req:t,sessionName:r,action:l,scope:y,filePath:d,line:w[e]??0,invoke:o})).ok)return n0(s,l,e,d,[...u]);n1(s).forEach(e=>u.add(e)),S+=1}return v&&S>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",tC(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tK(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tT(r,tU));return tG(t,e.flags),t.join(" ")}if("record"===e.command)return tj(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tC(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(tC(r));return tV(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
13
- `,s=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(s,n),i.renameSync(s,e)}(d,g,n.get(r)),{ok:!0,data:{replayed:g.length,healed:S,session:r,artifactPaths:[...u]}}}catch(t){let e=z(t);return eh(e.code,e.message,u.size>0?{artifactPaths:[...u]}:void 0)}}async function nQ(e){var t,r;let{req:a,sessionName:i,action:n,scope:s,filePath:o,line:l,invoke:d}=e,u=(t={file:o,line:l},{...n,positionals:(n.positionals??[]).map(e=>nT(e,s,t)),flags:nF(n.flags,s,t)??{},runtime:nF(n.runtime,s,t)});return await d({token:a.token,session:i,command:u.command,positionals:u.positionals??[],flags:(r=a.flags,tu(r,{...u.flags??{}})),runtime:u.runtime,meta:a.meta})}function n0(e,t,r,a,i=[]){let n;if(e.ok)return e;let s=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${s} (${n=(t.positionals??[]).map(e=>tC(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:s,action:t.command,positionals:t.positionals??[],artifactPaths:i}}}}function n1(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 n2(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await nY({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await nz({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:s,requestId:o,artifactsDir:l,artifactPaths:d})=>{let u=function(e){let{parentFlags:t,platform:r,artifactsDir:a}=e;return void 0===r&&void 0===a?t:{...t??{},...void 0!==r?{platform:r}:{},...void 0!==a?{artifactsDir:a}:{}}}({parentFlags:t.flags,platform:s,artifactsDir:l});return await nY({req:{...t,command:"replay",session:r,positionals:[e],flags:u,meta:o?{...t.meta??{},requestId:o}:t.meta},sessionName:r,logPath:a,sessionStore:i,invoke:async e=>{var t;return t=await n(e),d&&n1(t).forEach(e=>d.add(e)),t}})},cleanupSession:async e=>{i.get(e)&&await ib({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let n8=new Set(["session_list","ensure-simulator","devices","apps"]),n3=new Set(["boot","appstate"]),n5=new Set(["perf","logs","network"]),n4=new Set(["replay","test"]);async function n6(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:s,recordPositionals:o,deriveNextSession:l}=e,d=i.get(r),u=t.flags??{},c=ad(n,d,u);if(c)return c;let f=await ap({session:d,flags:u,ensureReady:!0});if(!e0(n,f))return eh("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await ea(f,n,s,t.flags?.out,{...eO(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:o??s,flags:t.flags??{},result:p??{}}),e!==d&&i.set(r,e)}return{ok:!0,data:p??{}}}async function n9(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),s=t.flags??{},o=ad("clipboard",n,s);if(o)return o;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 ap({session:n,flags:s,ensureReady:!0});if(!e0("clipboard",d))return eh("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await ea(d,"clipboard",t.positionals??[],t.flags?.out,{...eO(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 n7(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,androidAdbExecutor:s}=e;if(n8.has(t.command))return await iO({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await aH({req:t,sessionName:r,sessionStore:i});if(n3.has(t.command))return await iF({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await n9({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"!==e3((t.flags??{}).platform)?await n6({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(n5.has(t.command))return await n_({req:t,sessionName:r,sessionStore:i,androidAdbExecutor:s});if("install"===t.command||"reinstall"===t.command)return await iM({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?iN:i_});if("install_source"===t.command)return await ai({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await as({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),s=t.positionals?.[1]?.trim();return n&&s?await n6({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=eT(s,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tz.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,s]}):eh("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await n6({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 io(e.device,r,e.appBundleId,ii)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await iy({req:t,sessionName:r,logPath:a,sessionStore:i}):n4.has(t.command)?await n2({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await ix(t,r,n):"close"===t.command?await ib({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function se(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,s=t.command;if("find"!==s)return null;let o=t.positionals??[];if(0===o.length)return eh("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=t_(o);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 eq({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 ey(t.flags??{});m||await eB(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&&!eJ(m))return{nodes:v};let{snapshot:n}=await eD({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),s=n.nodes;return y=e,v=s,m&&(eS(m,n),i.set(r,m)),{nodes:s,truncated:n.truncated,backend:n.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:s,locator:l,query:d};if("wait"===u)return st(I,S,l,d,f);let{nodes:A}=await S(),b=tb(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,M;let e;return _=b.matches,N=l,M=d,e=_.slice(0,8).map(e=>{let t=tp(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eh("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${M}". Use a more specific locator or selector.`,{locator:N,query:M,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 D="click"===u||"focus"===u||"fill"===u||"type"===u?tf(A,x)??x:x,k=`@${D.ref}`,P={node:x,resolvedNode:D,ref:k,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},R={exists:()=>sr(I),get_text:()=>sa(I,P),get_attrs:()=>si(I,P),click:()=>sn(I,P),fill:()=>ss(I,P,c),focus:()=>so(I,P),type:()=>sl(I,P,c)}[u];return R?R():null}async function st(e,t,r,a,i){let{req:n,sessionStore:s,session:o,command:l}=e,d=i??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(tb(e,r,a,{requireRect:!1}).matches[0])return o&&s.recordAction(o,{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 Z(300)}return eh("COMMAND_FAILED","find wait timed out")}async function sr(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 sa(e,t){let{req:r,sessionStore:a,session:i,command:n,device:s,logPath:o}=e,l=await ex({device:s,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eO(o,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 si(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 sn(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,invoke:s,command:o,locator:l,query:d}=e,u=await s({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let c=t.resolvedNode.rect?tA(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:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:f}}async function ss(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:s,invoke:o,command:l}=e;if(!r)return eh("INVALID_ARGS","find fill requires text");let d=await o({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&s&&n.recordAction(s,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function so(e,t){let{req:r,sessionStore:a,session:i,device:n,command:s,logPath:o}=e,l=t.node.rect?tA(t.node.rect):null;if(!l)return eh("COMMAND_FAILED","matched element has no bounds");let d=await ea(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eO(o,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function sl(e,t,r){let{req:a,sessionStore:i,session:n,device:s,command:o,logPath:l}=e;if(!r)return eh("INVALID_ARGS","find type requires text");let d=t.node.rect?tA(t.node.rect):null;if(!d)return eh("COMMAND_FAILED","matched element has no bounds");await ea(s,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eO(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await ea(s,"type",[r],a.flags?.out,{...eO(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:o,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let sd=`
1
+ let e,t,r,n;import{__webpack_require__ as a}from"../rslib-runtime.js";import i,{createHash as o}from"node:crypto";import s,{existsSync as l,promises as u}from"node:fs";import d,{hostname as c}from"node:os";import p from"node:path";import f from"node:net";import{AsyncLocalStorage as m}from"node:async_hooks";import{XMLParser as h}from"fast-xml-parser";import w from"node:http";import{fileURLToPath as g,pathToFileURL as y}from"node:url";import"node:https";import{once as v}from"node:events";import{Transform as I}from"node:stream";import{pipeline as A}from"node:stream/promises";import S from"node:fs/promises";import{PNG as b}from"pngjs";import{setTimeout as _}from"node:timers/promises";import{parseAllDocuments as N}from"yaml";import{toAppErrorCode as x,asAppError as M,normalizeError as D,AppError as k}from"../9152.js";import{runCmdBackground as E,runCmdStreaming as O,runCmd as P,whichCmd as C,resolveExecutableOverridePath as L}from"../9818.js";import{runAndroidAdb as R,resolveIosSimulatorDeviceSetPath as T,dismissAndroidKeyboard as $,resolveIosDeviceDeepLinkBundleId as F,listAndroidDevices as U,classifyBootFailure as G,ensureAdb as V,streamAndroidLogcatWithAdb as j,writeAndroidClipboardText as B,openAndroidApp as q,closeAndroidApp as H,bootFailureHint as W,getAndroidKeyboardState as z,androidDeviceForSerial as K,openAndroidDevice as J,listAndroidApps as X,parseSerialAllowlist as Y,getAndroidAppState as Z,classifyAndroidAppTarget as Q,captureAndroidLogcatWithAdb as ee,isAndroidInputMethodOwnedNode as et,resolveAndroidSerialAllowlist as er,createAppResolutionCache as en,isDeepLinkTarget as ea,readAndroidClipboardText as ei,formatAndroidInstalledPackageRequiredMessage as eo}from"../1769.js";import{isEnvTruthy as es,assertResolvedAppsFilter as el,retryWithPolicy as eu,withRetry as ed,TIMEOUT_PROFILES as ec,Deadline as ep}from"../840.js";import{sleep as ef,resolveTimeoutMs as em,resolveTimeoutSeconds as eh}from"../4829.js";import{readProcessStartTime as ew,trimRuntimeValue as eg,readProcessCommand as ey,resolveRuntimeTransportHints as ev,isProcessGroupAlive as eI,isAgentDeviceDaemonProcess as eA,isProcessAlive as eS}from"../8656.js";import{withDiagnosticsScope as eb,getDiagnosticsMeta as e_,flushDiagnosticsToSessionFile as eN,withDiagnosticTimer as ex,emitDiagnostic as eM}from"../7599.js";import{readVersion as eD,findProjectRoot as ek}from"../9671.js";import{resolveUserPath as eE}from"../3267.js";import{resolveDaemonCodeSignature as eO,DAEMON_COMMAND_GROUPS as eP,readLocationCoordinate as eC,PUBLIC_COMMANDS as eL,normalizeTenantId as eR,INTERACTION_COMMAND_CAPABILITIES as eT,resolveSessionIsolationMode as e$,parseTimeout as eF,appendScreenshotScriptFlags as eU,successText as eG,readScreenshotScriptFlag as eV,screenshotOptionsFromFlags as ej,requireLocationCoordinates as eB,parseWaitPositionals as eq,resolveDeployResultTarget as eH,screenshotFlagsFromOptions as eW,withSuccessText as ez,resolveDaemonPaths as eK,typeCommandDefinition as eJ,INTERNAL_COMMANDS as eX,resolveDaemonServerMode as eY,resolveInstallFromSourceResultTarget as eZ,fillCommandCodec as eQ,splitNonEmptyTrimmedLines as e0,interactionTargetCodec as e1,SCREENSHOT_ACTION_FLAG_KEYS as e2}from"../3572.js";import{withAndroidAdbProvider as e3,pullAndroidAdbFile as e5,resolveAndroidTextInjector as e4,resolveAndroidAdbProvider as e8,resolveAndroidAdbExecutor as e6}from"../9639.js";import{isScrollableType as e9}from"../2842.js";import{parseUiHierarchy as e7,ensureAndroidSnapshotHelper as te,parseUiHierarchyTree as tt,captureAndroidSnapshotWithHelper as tr,parseAndroidSnapshotHelperManifest as tn,androidUiNodes as ta,forgetAndroidSnapshotHelperInstall as ti,buildUiHierarchySnapshot as to}from"../221.js";import{findMistargetedTypeRefToken as ts,isSupportedPredicate as tl,parseSessionSurface as tu,CAPTURE_COMMAND_CAPABILITIES as td,isMacOsSettingSupported as tc,resolveRectCenter as tp,applyCommandDefaults as tf,deriveMobileSnapshotHiddenContentHints as tm,SETTINGS_INVALID_ARGS_MESSAGE as th,normalizeSnapshotTree as tw,createAgentDevice as tg,evaluateIsPredicate as ty,getUnsupportedMacOsSettingMessage as tv,localCommandPolicy as tI,requireIntInRange as tA,parseDeviceRotation as tS,decodePng as tb,SELECTOR_COMMAND_CAPABILITIES as t_,SESSION_LIFECYCLE_COMMAND_CAPABILITIES as tN}from"../2151.js";import{snapshotPresentationOptionsFromFlags as tx,normalizeRef as tM,findNodeByRef as tD,buildSnapshotPresentationKey as tk,centerOfRect as tE,attachRefs as tO}from"../4057.js";import{materializeInstallablePath as tP,isTrustedInstallSourceUrl as tC}from"../989.js";import{splitSelectorFromArgs as tL,findNearestHittableAncestor as tR,extractNodeText as tT,extractNodeReadText as t$,tryParseSelectorChain as tF,findNodeByLabel as tU,resolveRefLabel as tG,splitIsSelectorArgs as tV,resolveSelectorChain as tj,buildSelectorChainForNode as tB,normalizeType as tq,pruneGroupNodes as tH}from"../940.js";import{findBestMatchesByLocator as tW,parseFindArgs as tz}from"../7556.js";import{runBatch as tK,mergeParentFlags as tJ}from"../1231.js";var tX={};a.r(tX),a.d(tX,{TM:()=>uc,installIosApp:()=>uf,installIosInstallablePath:()=>uh,YO:()=>uI,L5:()=>uu,IJ:()=>ud,TJ:()=>uy,J7:()=>uw,reinstallIosApp:()=>um,resolveIosApp:()=>ul,kc:()=>l2,Cm:()=>uv,ap:()=>ug});var tY={};a.r(tY),a.d(tY,{prepareIosInstallArtifact:()=>ln});var tZ={};a.r(tZ),a.d(tZ,{ensureBootedSimulator:()=>s7,SA:()=>lt,EB:()=>s6,N3:()=>le});let tQ=new Set,t0=new Map,t1="request_canceled",t2="request canceled";function t3(e,t){if("string"==typeof e&&e.length>0)return e;let r=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",n=Math.random().toString(36).slice(2,10);return`req:${r}:${process.pid}:${Date.now()}:${n}`}function t5(e){if(!e)return;!function(e){if(e.size<=5e4)return;let t=0;for(let r of e.keys()){if(t>=1e4)break;e.delete(r),t++}}(t0);let t=new AbortController;t0.set(e,t),tQ.has(e)&&t.abort()}function t4(e){e&&(!function(e){if(e.size<=5e4)return;let t=0;for(let r of e){if(t>=1e4)break;e.delete(r),t++}}(tQ),tQ.add(e),t0.get(e)?.abort())}function t8(e){e&&(tQ.delete(e),t0.delete(e))}function t6(e){return!!e&&tQ.has(e)}function t9(e){if(e)return t0.get(e)?.signal}function t7(){return new k("COMMAND_FAILED",t2,{reason:t1})}function re(e){if(t6(e))throw t7()}function rt(e){return e instanceof k&&"COMMAND_FAILED"===e.code&&(e.details?.reason===t1||e.message===t2)}function rr(e,t=e=>e){let r=new m;return{resolve:n=>n?t(n):r.getStore()??e,run:async(e,n)=>e?await r.run(t(e),n):await n(),hasScope:()=>!!r.getStore()}}function rn(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}function ra(e,t){return{openBundle:async(t,r)=>{var n,a;let i;await e("open",(n=t,a=r,i=["-b",n],a&&i.push(a),i))},openTarget:async t=>{await e("open",[t])},readClipboard:async()=>{let t=await e("pbpaste",[],{allowFailure:!0});if(0!==t.exitCode)throw new k("COMMAND_FAILED","Failed to read macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")},writeClipboard:async t=>{let r=await e("pbcopy",[],{allowFailure:!0,stdin:t});if(0!==r.exitCode)throw new k("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})},readDarkMode:async()=>{let t=await e("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==t.exitCode)throw new k("COMMAND_FAILED","Failed to read macOS appearance",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.trim().toLowerCase();if("true"===r)return!0;if("false"===r)return!1;throw new k("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${t.stdout.trim()}`)},setDarkMode:async t=>{let r=`tell application "System Events" to tell appearance preferences to set dark mode to ${t?"true":"false"}`,n=await e("osascript",["-e",r],{allowFailure:!0});if(0!==n.exitCode)throw new k("COMMAND_FAILED","Failed to set macOS appearance",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})},listApps:async r=>await ri(e,t,r)}}async function ri(e,t,r){let n=["/Applications","/System/Applications",p.join(d.homedir(),"Applications")],a=new Set;for(let t of n){let r=await u.stat(t).catch(()=>null);if(!r?.isDirectory())continue;let n=await e("find",[t,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===n.exitCode)for(let e of n.stdout.split("\n")){let t=e.trim();t&&a.add(t)}}return rn((await Promise.all(Array.from(a).map(async e=>{let r=await ro(e,t).catch(()=>({})),n=r.bundleId;return n?{bundleId:n,name:r.appName??p.basename(e,".app")}:null}))).filter(e=>null!==e).sort((e,t)=>e.name.localeCompare(t.name)),r)}async function ro(e,t){for(let r of[p.join(e,"Contents","Info.plist"),p.join(e,"Info.plist")]){let e=await t(r),n=rs(e,"CFBundleIdentifier"),a=rs(e,"CFBundleDisplayName"),i=rs(e,"CFBundleName");if(n||a||i)return{bundleId:n,appName:a??i}}return{}}function rs(e,t){let r=e?.[t];return"string"==typeof r&&r.trim()?r.trim():void 0}let rl={runCommand:P,simctl:{run:async(e,t)=>await P("xcrun",["simctl",...e],t)},devicectl:{run:async(e,t)=>await P("xcrun",["devicectl",...e],t)},plist:{readJson:async e=>await rw(P,e)},macosHost:ra(P,async e=>await rw(P,e)),whichCommand:C},ru=rr(rl,function(e){return"function"==typeof e?rd({runCommand:e}):rd(e)});function rd(e={}){let t={...rl,...e},r=e.plist??{readJson:async e=>await rw(t.runCommand,e)};return{...t,simctl:e.simctl??{run:async(e,r)=>await t.runCommand("xcrun",["simctl",...e],r)},devicectl:e.devicectl??{run:async(e,r)=>await t.runCommand("xcrun",["devicectl",...e],r)},plist:r,macosHost:e.macosHost??ra(t.runCommand,async e=>await r.readJson(e))}}function rc(e){return ru.resolve(e)}async function rp(e,t){return await ru.run(e,t)}async function rf(e,t,r){return await rc().runCommand(e,t,r)}async function rm(e,t){let r=rc(),[n,...a]=e;return"simctl"===n?await (r.simctl?.run(a,t)??r.runCommand("xcrun",e,t)):"devicectl"===n?await (r.devicectl?.run(a,t)??r.runCommand("xcrun",e,t)):await rf("xcrun",e,t)}async function rh(e){return await rc().plist?.readJson(e)??null}async function rw(e,t){try{let r=await e("plutil",["-convert","json","-o","-",t],{allowFailure:!0});if(0!==r.exitCode||!r.stdout.trim())return null;return JSON.parse(r.stdout)}catch{return null}}function rg(e,t={}){let r=T(t.simulatorSetPath);return r?["simctl","--set",r,...e]:["simctl",...e]}function ry(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:rg(t,{simulatorSetPath:e.simulatorSetPath})}let rv="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/ios-runner/derived, then retry.";function rI(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}function rA(e){return!(e instanceof k)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function rS(e){let{port:t,endpoints:r,logPath:n,lastError:a}=e,i="Runner did not accept connection";return new k("COMMAND_FAILED",i,{port:t,endpoints:r,logPath:n,lastError:a?String(a):void 0,reason:G({error:a,message:i,context:{platform:"ios",phase:"connect"}}),hint:W("IOS_RUNNER_CONNECT_TIMEOUT")})}async function rb(e){var t,r;let n,{session:a,port:i,logPath:o}=e,s=await a.testPromise,l="Runner did not accept connection (xcodebuild exited early)",u=G({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new k("COMMAND_FAILED",l,{port:i,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:u,hint:(t=s.stdout,r=s.stderr,(n=`${l}
2
+ ${t}
3
+ ${r}`.toLowerCase()).includes("device is busy")&&n.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":`${W("IOS_RUNNER_CONNECT_TIMEOUT")} ${rv}`)})}function r_(e){return"interactionFrame"===e||"snapshot"===e||"screenshot"===e||"findText"===e||"querySelector"===e||"readText"===e||"alert"===e||"uptime"===e}function rN(e){if(t6(e))throw t7()}let rx=em(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),rM=em(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),rD=em(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),rk=em(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),rE=em(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),rO=em(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),rP=em(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),rC=eh(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5),rL=new Map;async function rR(e,t,r,n,a=rx,i,o){let s=ep.fromTimeoutMs(a),{getEndpoints:l}=r$(e,t),{endpoints:u}=await l(s.remainingMs()),d=null,c=Math.max(1,Math.ceil(a/rD));try{return await eu(async({deadline:s})=>{if(s?.isExpired())throw new k("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:a});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await rb({session:i,port:t,logPath:n});let c=!1;if("device"===e.kind){let e=await l(s?.remainingMs());u=e.endpoints,c=e.cached}let p=c?u[0]:null,f=await rF(u,{command:r,port:t,timeoutMs:a,signal:o,attemptDeadline:s,onError:(t,r)=>{var n;d=r,"device"===e.kind&&t===p&&(n=e.id,rL.delete(n))}});if(f)return f;if("device"===e.kind&&c){var m;m=e.id,rL.delete(m),u=(await l(s?.remainingMs(),!0)).endpoints;let n=await rF(u,{command:r,port:t,timeoutMs:a,signal:o,attemptDeadline:s,onError:(e,t)=>{d=t}});if(n)return n}if(o?.aborted)throw t7();throw new k("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:u,lastError:d?String(d):void 0})},{maxAttempts:c,baseDelayMs:rk,maxDelayMs:rE,jitter:.2,shouldRetry:rA},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||rt(e))throw t7();d||(d=e)}if(o?.aborted)throw t7();if("simulator"===e.kind){let a=s.remainingMs();if(a<=0)throw rS({port:t,endpoints:u,logPath:n,lastError:d});let i=await rj(e,t,r,a,o);return new Response(i.body,{status:i.status})}throw rS({port:t,endpoints:u,logPath:n,lastError:d})}async function rT(e,t,r,n=rM,a){if(a?.aborted)throw t7();let i=ep.fromTimeoutMs(n),{getEndpoints:o}=r$(e,t),{endpoints:s}=await o(i.remainingMs()),l=s[0];if(!l)throw new k("COMMAND_FAILED","Runner command endpoint not available",{port:t,endpoints:s});let u=i.remainingMs();if(u<=0)throw new k("COMMAND_FAILED","Runner command deadline exceeded",{timeoutMs:n});return await rG(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},u,a)}function r$(e,t){let r;return{getEndpoints:async(n,a=!1)=>{var i,o,s;let l,u=await rU({device:e,timeoutBudgetMs:n,forceRefresh:a,requestTunnelIp:r,setRequestTunnelIp:e=>{r=e}});return{endpoints:(i=e,o=t,s=u.ip,l=[`http://127.0.0.1:${o}/command`],"device"!==i.kind||s&&l.unshift(`http://[${s}]:${o}/command`),l),cached:u.sharedCacheHit}}}}async function rF(e,t){let{command:r,port:n,timeoutMs:a,signal:i,attemptDeadline:o,onError:s}=t;for(let t of e)try{let e=o?.remainingMs()??a;if(e<=0)throw new k("COMMAND_FAILED","Runner connection deadline exceeded",{port:n,timeoutMs:a});return await rG(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},Math.min(rO,e),i)}catch(e){if(i?.aborted||rt(e))throw t7();s(t,e)}return null}async function rU(e){var t,r,n;let{device:a,timeoutBudgetMs:i,forceRefresh:o,requestTunnelIp:s,setRequestTunnelIp:l}=e;if("device"!==a.kind)return{ip:null,sharedCacheHit:!1};if(!o){let e,r=(t=a.id,(e=rL.get(t))?e.expiresAt<=Date.now()?(rL.delete(t),null):e.ip:null);if(r)return{ip:r,sharedCacheHit:!0};if(void 0!==s)return{ip:s,sharedCacheHit:!1}}let u=await rV(a.id,i);return l(u),u&&(r=a.id,n=u,rL.set(r,{ip:n,expiresAt:Date.now()+3e4})),{ip:u,sharedCacheHit:!1}}async function rG(e,t,r,n){let a=AbortSignal.timeout(r),i=n?AbortSignal.any([n,a]):a;return await fetch(e,{...t,signal:i})}async function rV(e,t){if("number"==typeof t&&t<=0)return null;let r="number"==typeof t?Math.max(1,Math.min(rP,t)):rP,n=p.join(d.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(r/1e3)),a=await rm(["devicectl","device","info","details","--device",e,"--json-output",n,"--timeout",String(t)],{allowFailure:!0,timeoutMs:r});if(0!==a.exitCode||!s.existsSync(n))return null;let i=JSON.parse(s.readFileSync(n,"utf8"));if(i.info?.outcome&&"success"!==i.info.outcome)return null;let o=(i.result?.connectionProperties?.tunnelIPAddress??i.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return o&&o.length>0?o:null}catch{return null}finally{rz(n)}}async function rj(e,t,r,n,a){let i=JSON.stringify(r),o=ry(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",i,`http://127.0.0.1:${t}/command`]),s=await rm(o,{allowFailure:!0,timeoutMs:n,signal:a}),l=s.stdout;if(0!==s.exitCode){let e=G({message:"Runner did not accept connection (simctl spawn)",stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});throw new k("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode,reason:e,hint:W(e)})}return{status:200,body:l}}async function rB(){return await new Promise((e,t)=>{let r=f.createServer();r.listen(0,"127.0.0.1",()=>{let n=r.address();if("object"==typeof n&&n?.port){let t=n.port;r.close(()=>e(t))}else r.close(()=>t(new k("COMMAND_FAILED","Failed to allocate port")))}),r.on("error",t)})}function rq(e,t,r,n){t&&rW(t,e),r&&rW(r,e),n&&process.stderr.write(e)}let rH=new Map;function rW(e,t){let r=(rH.get(e)??Promise.resolve()).catch(()=>{}).then(()=>s.promises.appendFile(e,t)).catch(()=>{}).finally(()=>{rH.get(e)===r&&rH.delete(e)});rH.set(e,r)}function rz(e){try{s.existsSync(e)&&s.unlinkSync(e)}catch{}}let rK=new m;async function rJ(e,t,r){let n=rK.getStore()??[];if(n.some(r=>r.locks===e&&r.key===t))return await r();let a=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>rK.run([...n,{locks:e,key:t}],r));return e.set(t,a),a.finally(()=>{e.get(t)===a&&e.delete(t)})}function rX(e){return"apple"===e||"ios"===e||"macos"===e}function rY(e,t){return!t||("apple"===t?rX(e):e===t)}function rZ(e){let{simulatorSetPath:t,platform:r,target:n}=e;if(t&&"macos"!==r&&"desktop"!==n)return t}async function rQ(e,t,r={}){let n=e,a=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(n=n.filter(e=>rY(e.platform,t.platform))),t.target&&(n=n.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=n.find(e=>e.id===t.udid&&rX(e.platform));if(!e)throw new k("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=n.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new k("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=a(t.deviceName),r=n.find(t=>a(t.name)===e);if(!r)throw new k("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return r}if(1===n.length)return n[0];if(0===n.length){var i;let e=r.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new k("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
4
+ xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new k("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=n.filter(e=>"device"!==e.kind);o.length>0&&(n=o);let s=n.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??n[0]}let r0=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function r1(e,t,r){if("macos"!==e.platform)return;if(0===t.length)throw new k("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:r});let n=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of n)if(!s.existsSync(e))throw new k("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:r});for(let e of n)if(!await r2(e)){await rf("codesign",["--remove-signature",e],{allowFailure:!0});try{await rf("codesign",["--force","--sign","-",e])}catch(n){let t=n instanceof k?n:new k("COMMAND_FAILED",String(n));throw new k("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:r,error:t.message,details:t.details})}}}async function r2(e){return 0===(await rf("codesign",["--verify","--deep","--strict",e],{allowFailure:!0})).exitCode}let r3=null;function r5(e){return function e(t){if(!Array.isArray(t))return[];let r=[];for(let n of t)if(!(!n||"object"!=typeof n||Array.isArray(n)))for(let[t,a]of Object.entries(n))":@"!==t&&"#text"!==t&&r.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[r,n]of Object.entries(e))"string"==typeof n&&(t[r]=n);return t}(n[":@"]),text:r8(a)??r8(n["#text"]),children:e(a)});return r}((r3??=new h({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function r4(e,t){for(let r of e){if("dict"===r.name)for(let e=0;e<r.children.length-1;e+=1){let n=r.children[e],a=r.children[e+1];n?.name==="key"&&n.text&&a&&t(n.text,a)}r4(r.children,t)}}function r8(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let r6=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]);async function r9(e){var t;let r=await r7(e);if(!r||0===r.length)return null;let n=p.dirname(e),a=new Set,i=function(e,t){let r=[],n=new Set,a=[];for(let i of e){if(i.startsWith("__TESTHOST__/")){a.push(i.slice(13));continue}if(!i.startsWith("__TESTROOT__/"))continue;let e=i.slice(13);r.push(p.join(t,e));let o=function(e){let t=/\.app(?:\/|$)/.exec(e);return t&&void 0!==t.index?e.slice(0,t.index+4):null}(e);o&&n.add(p.join(t,o))}return{testRootPaths:r,hostRoots:Array.from(n),hostRelativePaths:a}}(r,n);for(let e of i.testRootPaths){if(!s.existsSync(e))return null;a.add(e)}for(let e of(t=i).hostRelativePaths.map(e=>{let r=t.hostRoots.find(t=>s.existsSync(p.join(t,e)));return r?p.join(r,e):null})){if(!e)return null;a.add(e)}return Array.from(a)}async function r7(e){let t=await rh(e);if(t){var r,n,a,i=t;let e=new Set;for(let t of[a=i,...function(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!ne(e))continue;let t=e.TestTargets;Array.isArray(t)&&r.push(...t.filter(ne))}return r}(a),...Object.values(a).filter(e=>ne(e)&&"TestBundlePath"in e)])for(let r of function(e){let t=new Set;for(let[r,n]of Object.entries(e))if(r6.has(r)){if("string"==typeof n){t.add(n);continue}if(Array.isArray(n))for(let e of n)"string"==typeof e&&t.add(e)}return Array.from(t)}(t))e.add(r);return Array.from(e)}if("darwin"===process.platform)return null;try{let t;return r=s.readFileSync(e,"utf8"),n=r5(r),t=new Set,r4(n,(e,r)=>{if(r6.has(e)){if("string"===r.name&&r.text)return void t.add(r.text);if("array"===r.name)for(let e of r.children)"string"===e.name&&e.text&&t.add(e.text)}}),Array.from(t)}catch{return null}}function ne(e){return!!e&&"object"==typeof e}let nt="XCTestDevices",nr=".agent-device-backup",nn=".agent-device-xctestdevices-backup-",na=p.join(d.homedir(),".agent-device","ios-runner"),ni=".agent-device-runner-cache.json",no={PreferredScreenCaptureFormat:"screenshots",SystemAttachmentLifetime:"keepNever",UserAttachmentLifetime:"keepNever"},ns=new Map,nl=new Set;function nu(e){return e?.trim()??""}function nd(e=process.env){return nu(e.AGENT_DEVICE_IOS_BUNDLE_ID)||nu(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function nc(e=process.env){let t=nu(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${nd(e)}.uitests`}let np=function(e=process.env){let t=nd(e),r=nc(e);return Array.from(new Set([nu(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${r}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function nf(e=d.homedir()){return p.join(e,"Library","Developer","XCTestDevices")}async function nm(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let r=T(e.simulatorSetPath);if(!r)return null;let n=p.resolve(r),a=p.resolve(t.xctestDeviceSetPath??nf()),i=p.resolve(t.backupPath??function(e=nf()){return`${e}${nr}`}(a)),o=p.resolve(t.lockDirPath??function(e=d.homedir()){return p.join(e,".agent-device","xctest-device-set.lock")}()),l=t.ownerStartTime??ew(process.pid),u=await ng({lockDirPath:o,owner:{pid:t.ownerPid??process.pid,startTime:l,acquiredAtMs:t.nowMs??Date.now()}});try{if(nh({xctestDeviceSetPath:a,backupPath:i}),function(e,t){if(p.resolve(e)===p.resolve(t))return!0;try{return s.realpathSync.native(e)===s.realpathSync.native(t)}catch{return!1}}(n,a))return await u(),null;s.mkdirSync(n,{recursive:!0}),s.existsSync(a)&&s.renameSync(a,i),function(e){let{requestedSetPath:t,xctestDeviceSetPath:r}=e,n=p.dirname(r),a=p.join(n,`${nt}.agent-device-link-${process.pid}-${Date.now()}`);s.mkdirSync(n,{recursive:!0});try{s.symlinkSync(t,a,"dir"),s.renameSync(a,r)}catch(e){throw s.existsSync(a)&&nw(a),e}}({requestedSetPath:n,xctestDeviceSetPath:a})}catch(e){throw nh({xctestDeviceSetPath:a,backupPath:i}),await u(),new k("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:n,xctestDeviceSetPath:a,backupPath:i,error:String(e)})}let c=!1;return{release:async()=>{if(!c){c=!0;try{nh({xctestDeviceSetPath:a,backupPath:i})}finally{await u()}}}}}function nh(e){let{xctestDeviceSetPath:t,backupPath:r}=e,n=[r,...function(e){let t=p.dirname(e),r=p.basename(e).replace(nr,""),n=r===nt?nn:`${r}${nn}`;try{return s.readdirSync(t).filter(e=>e.startsWith(n)).sort().map(e=>p.join(t,e))}catch{return[]}}(r)],a=n.find(e=>s.existsSync(e)),i=s.existsSync(t)&&s.lstatSync(t).isSymbolicLink();if(a){if(i&&nw(t),s.existsSync(t))if(!i)return void eM({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:a}});else a!==r?s.rmSync(a,{recursive:!0,force:!0}):s.rmSync(r,{recursive:!0,force:!0});else s.mkdirSync(p.dirname(t),{recursive:!0}),s.renameSync(a,t);for(let e of n)e!==a&&s.existsSync(e)&&s.rmSync(e,{recursive:!0,force:!0});return}i&&(eM({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),nw(t))}function nw(e){!s.existsSync(e)||s.lstatSync(e).isSymbolicLink()&&s.unlinkSync(e)}async function ng(e){let{lockDirPath:t,owner:r}=e,n=p.join(t,"owner.json"),a=Date.now()+3e4;for(s.mkdirSync(p.dirname(t),{recursive:!0});Date.now()<a;)try{s.mkdirSync(t),function(e,t){let r=`${e}.${process.pid}.${Date.now()}.tmp`;s.writeFileSync(r,JSON.stringify(t),"utf8"),s.renameSync(r,e)}(n,r);let e=!1;return async()=>{e||(e=!0,s.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let r=null;try{r=s.statSync(e)}catch{return!0}let n=function(e){try{return JSON.parse(s.readFileSync(e,"utf8"))}catch{return null}}(t);if(n){var a;return!(Number.isInteger((a=n).pid)&&!(a.pid<=0)&&eS(a.pid)&&(!a.startTime||ew(a.pid)===a.startTime))&&(s.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-r.mtimeMs<5e3)&&(s.rmSync(e,{recursive:!0,force:!0}),!0)}(t,n))continue;await ef(100)}throw new k("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function ny(e,t){var r;let n,a=(r=e,(n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?p.resolve(n):"macos"===r.platform?p.join(na,"derived","macos"):"simulator"===r.kind?p.join(na,"derived"):p.join(na,"derived",r.kind)),o=ek();return await rJ(ns,a,async()=>{let r=function(e,t=ek()){var r;let n;return{schemaVersion:1,packageVersion:eD(),runnerSourceFingerprint:function(e){let t=p.join(e,"ios-runner","AgentDeviceRunner"),r=function(e){if(!s.existsSync(e))return[];let t=[],r=[e];for(;r.length>0;){let e=r.pop();for(let i of s.readdirSync(e,{withFileTypes:!0})){var n,a;let o=p.join(e,i.name);if(i.isDirectory()){if("xcuserdata"===i.name)continue;r.push(o);continue}i.isFile()&&(n=i.name,a=o,"project.pbxproj"===n?a.includes(`${p.sep}.xcodeproj${p.sep}`):[".swift",".plist",".entitlements",".xctestplan",".xcconfig",".storyboard",".xib"].includes(p.extname(n)))&&t.push(o)}}return t.sort((e,t)=>e.localeCompare(t))}(t),n=function(e,t){let r=i.createHash("sha256");for(let n of t){let t=p.relative(e,n),a=s.statSync(n);r.update(t),r.update("\0"),r.update(String(a.size)),r.update("\0"),r.update(String(Math.trunc(a.mtimeMs))),r.update("\0")}return r.digest("hex")}(t,r),a=nx.get(t);if(a?.fileStatsFingerprint===n)return a.sourceFingerprint;let o=i.createHash("sha256");for(let e of r){let r=p.relative(t,e);o.update(r),o.update("\0"),o.update(s.readFileSync(e)),o.update("\0")}let l=o.digest("hex");return nx.set(t,{fileStatsFingerprint:n,sourceFingerprint:l}),l}(t),platformName:nT(e),deviceKind:e.kind,target:e.target??"phone",buildDestinationFamily:"macOS"===(n=nT(r=e))?`platform=macOS,arch=${n$()}`:"simulator"===r.kind?`generic/platform=${n} Simulator`:`generic/platform=${n}`,runnerBundleBuildSettings:nG(process.env),runnerSigningBuildSettings:nU(process.env,"device"===e.kind,e.platform),runnerPerformanceBuildSettings:nV()}}(e,o);es(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(nq("clean","forced_clean",{derived:a}),nj(a),nv(a));let n=await nB({derived:a,projectRoot:o,expectedCacheMetadata:r,findXctestrun:t=>nM(t,e),xctestrunReferencesProjectRoot:nk,resolveExistingXctestrunProductPaths:r9});if("reuse_ready"!==n.reason&&nq("rebuild",n.reason,{derived:a,xctestrunPath:n.xctestrunPath}),"reuse_ready"===n.reason)try{return await r1(e,n.productPaths,n.xctestrunPath),nq("reuse","reuse_ready",{derived:a,xctestrunPath:n.xctestrunPath}),nA(a,nb(r,n.xctestrunPath,n.productPaths)),n.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof k))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&r0.has(t)}(e))throw e;nq("rebuild","repair_failed",{derived:a,xctestrunPath:n.xctestrunPath})}n.xctestrunPath&&(nj(a),nv(a));let l=p.join(o,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!s.existsSync(l))throw new k("COMMAND_FAILED","iOS runner project not found",{projectPath:l});await nR(e,l,a,t);let u=nM(a,e);if(!u)throw new k("COMMAND_FAILED","Failed to locate .xctestrun after build");let d=await r9(u);if(!d)throw new k("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:u});return await r1(e,d,u),nA(a,nb(r,u,d)),nq("build","built_new",{derived:a,xctestrunPath:u}),u})}function nv(e){try{if(!s.existsSync(e))return;if("derived"!==p.basename(e))return void s.rmSync(e,{recursive:!0,force:!0});for(let r of s.readdirSync(e,{withFileTypes:!0})){var t;t=r.name,nI.has(t)&&s.rmSync(p.join(e,r.name),{recursive:!0,force:!0})}}catch{}}let nI=new Set([ni,"Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function nA(e,t){s.mkdirSync(e,{recursive:!0}),s.writeFileSync(p.join(e,ni),`${JSON.stringify(t,null,2)}
5
+ `)}function nS(e){let{artifacts:t,...r}=e;return r}function nb(e,t,r){let n=function(e,t){let r=nN(e);if(null===r||0===t.length)return null;let n=[];for(let e of t){let t=nN(e);if(null===t)return null;n.push({path:e,mtimeMs:t})}return{xctestrunPath:e,xctestrunMtimeMs:r,productPaths:n}}(t,r);return n?{...e,artifacts:n}:e}function n_(e){return!(!e||"object"!=typeof e||Array.isArray(e))&&"string"==typeof e.path&&Number.isInteger(e.mtimeMs)}function nN(e){try{return Math.trunc(s.statSync(e).mtimeMs)}catch{return null}}let nx=new Map;function nM(e,t){if(!s.existsSync(e))return null;let r=[],n=[e];for(;n.length>0;){let e=n.pop();for(let t of s.readdirSync(e,{withFileTypes:!0})){let a=p.join(e,t.name);if(t.isDirectory()){n.push(a);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=s.statSync(a);r.push({path:a,mtimeMs:e.mtimeMs})}catch{}}}return 0===r.length?null:(r.sort((e,r)=>{if(t){let n=nD(r.path,t)-nD(e.path,t);if(0!==n)return n}return r.mtimeMs-e.mtimeMs||e.path.localeCompare(r.path)}),r[0]?.path??null)}function nD(e,t){var r;let n=0,a=e.toLowerCase();p.basename(a).startsWith("agentdevicerunner.env.")&&(n-=1e3),a.includes(`${p.sep}macos${p.sep}`)&&(n-=5e3);let i="macos"===(r=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===r.target?"simulator"===r.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===r.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>a.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>a.includes(e))&&(n-=2500),n}function nk(e,t){try{let r=s.readFileSync(e,"utf8"),n=new Set([t]);try{n.add(s.realpathSync(t))}catch{}for(let e of n)if(r.includes(e))return!0;return!1}catch{return!1}}async function nE(e,t,r){let n=p.dirname(e),a=r.replace(/[^a-zA-Z0-9._-]/g,"_"),i=p.join(n,`AgentDeviceRunner.env.${a}.json`),o=p.join(n,`AgentDeviceRunner.env.${a}.xctestrun`),s=await nO(e);return nC(s,e=>{var r,n;return r=e,n=t,void(r.EnvironmentVariables={...r.EnvironmentVariables??{},...n},r.UITestEnvironmentVariables={...r.UITestEnvironmentVariables??{},...n},r.UITargetAppEnvironmentVariables={...r.UITargetAppEnvironmentVariables??{},...n},r.TestingEnvironmentVariables={...r.TestingEnvironmentVariables??{},...n})}),nC(s,e=>Object.assign(e,no),{requireTestBundlePath:!0}),await nP(s,i,o),{xctestrunPath:o,jsonPath:i}}async function nO(e){let t=await rf("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode||!t.stdout.trim())throw new k("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:t.stderr});try{let e=JSON.parse(t.stdout);if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Root must be an object");return e}catch(t){throw new k("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}}async function nP(e,t,r){s.writeFileSync(t,JSON.stringify(e,null,2));let n=await rf("plutil",["-convert","xml1","-o",r,t],{allowFailure:!0});if(0!==n.exitCode)throw new k("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:r,stderr:n.stderr})}function nC(e,t,r={}){let n=e.TestConfigurations;if(Array.isArray(n))for(let e of n)e&&"object"==typeof e&&function(e,t,r){if(Array.isArray(e))for(let n of e){let e=nL(n,r);e&&t(e)}}(e.TestTargets,t,r);for(let r of Object.values(e)){let e=nL(r,{requireTestBundlePath:!0});e&&t(e)}}function nL(e,t){return!e||"object"!=typeof e||Array.isArray(e)||t.requireTestBundlePath&&!e.TestBundlePath?null:e}async function nR(e,t,r,n){let a=nG(process.env),i=nU(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=nV(),l=await nm(e);try{var u;let l;await O("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",nF(e),"1","-destination",(u=e,l=nT(u),"macOS"===l?`platform=macOS,arch=${n$()}`:"simulator"===u.kind?`platform=${l} Simulator,id=${u.id}`:`generic/platform=${l}`),"-derivedDataPath",r,...s,...a,...o,...i],{detached:!0,onSpawn:e=>{nl.add(e),e.on("close",()=>{nl.delete(e)})},onStdoutChunk:e=>{rq(e,n.logPath,n.traceLogPath,n.verbose)},onStderrChunk:e=>{rq(e,n.logPath,n.traceLogPath,n.verbose)}})}catch(i){let e,t,r=i instanceof k?i:new k("COMMAND_FAILED",String(i)),a=(e=r.details?JSON.stringify(r.details):"",((t=`${r.message}
6
+ ${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0)??rv);throw new k("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:r.message,details:r.details,logPath:n.logPath,hint:a})}finally{await l?.release()}}function nT(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new k("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"macos"===e.platform?"macOS":"macos"===(t=e.target)||"desktop"===t?"macOS":"tv"===t?"tvOS":"iOS"}function n$(){return"arm64"===process.arch?"arm64":"x86_64"}function nF(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function nU(e=process.env,t=!1,r="ios"){if("macos"===r)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let n=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",a=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return n&&o.push(`DEVELOPMENT_TEAM=${n}`),a&&o.push(`CODE_SIGN_IDENTITY=${a}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}function nG(e=process.env){let t=nd(e),r=nc(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${r}`]}function nV(){return["COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO"]}function nj(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return es(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new k("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}async function nB(e){var t,r;let n,a=(t=e.derived,r=e.expectedCacheMetadata,(n=function(e){try{let t=JSON.parse(s.readFileSync(p.join(e,ni),"utf8"));if(!t||"object"!=typeof t||Array.isArray(t))return null;return t}catch{return null}}(t))?JSON.stringify(nS(n))!==JSON.stringify(nS(r))?{ok:!1,reason:"cache_metadata_mismatch"}:{ok:!0,metadata:n}:{ok:!1,reason:"cache_metadata_missing"}),i=a.ok?function(e){var t;let r=e?.artifacts;if(!(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&"string"==typeof t.xctestrunPath&&Number.isInteger(t.xctestrunMtimeMs)&&Array.isArray(t.productPaths)&&t.productPaths.length>0&&t.productPaths.every(n_))||nN(r.xctestrunPath)!==r.xctestrunMtimeMs)return null;let n=[];for(let e of r.productPaths){if(nN(e.path)!==e.mtimeMs)return null;n.push(e.path)}return{xctestrunPath:r.xctestrunPath,productPaths:n}}(a.metadata):null,o=i?.xctestrunPath??e.findXctestrun(e.derived);if(!o)return{reason:"missing_xctestrun",xctestrunPath:null};let l=i?.xctestrunPath===o?i.productPaths:await e.resolveExistingXctestrunProductPaths(o);return l?e.xctestrunReferencesProjectRoot(o,e.projectRoot)?a.ok?{reason:"reuse_ready",xctestrunPath:o,productPaths:l}:{reason:a.reason,xctestrunPath:o,productPaths:l}:{reason:"project_root_mismatch",xctestrunPath:o,productPaths:l}:{reason:"missing_products",xctestrunPath:o,productPaths:[]}}function nq(e,t,r){eM({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...r}})}let nH=new Map,nW=new Map;async function nz(e,t){return await rJ(nW,e.id,async()=>{let r,n,a=nH.get(e.id);if(a){if(n0(a.child.pid))return eM({level:"debug",phase:"ios_runner_session_reuse",data:{deviceId:e.id,sessionId:a.sessionId,ready:a.ready}}),a;await n4({},"stop_stale_session",async()=>{await nX(e.id,a)})}let i={};await n4(i,"ensure_booted",async()=>{var t;await ("simulator"!==(t=e).kind?Promise.resolve():t.booted?(eM({level:"debug",phase:"ios_runner_startup_ensure_booted_skipped",data:{deviceId:t.id}}),Promise.resolve()):n2(t))}),t.cleanStaleBundles?await n4(i,"cleanup_stale_bundles",async()=>{await nK(e)}):(i.cleanup_stale_bundles=0,eM({level:"debug",phase:"ios_runner_startup_cleanup_stale_bundles_skipped"}));let o=await n4(i,"ensure_xctestrun",async()=>await ny(e,t)),s=await n4(i,"allocate_port",async()=>await rB()),{xctestrunPath:l,jsonPath:u}=await n4(i,"prepare_xctestrun_env",async()=>await nE(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`)),d=await n4(i,"simulator_set_redirect",async()=>await nm(e));try{({child:r,wait:n}=await n4(i,"launch_xcodebuild",()=>{let t;return E("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",nF(e),"1","-destination-timeout",String(rC),"-xctestrun",l,"-destination",(t=nT(e),"macOS"===t?`platform=macOS,arch=${n$()}`:"simulator"===e.kind?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0})}))}catch(e){throw await d?.release(),e}r.stdout?.on("data",e=>{rq(e,t.logPath,t.traceLogPath,t.verbose)}),r.stderr?.on("data",e=>{rq(e,t.logPath,t.traceLogPath,t.verbose)});let c={sessionId:`${e.id}:${s}:${Date.now()}`,device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:u,testPromise:n,child:r,ready:!1,startupTimings:i,simulatorSetRedirect:d??void 0};return nH.set(e.id,c),c})}async function nK(e){if("simulator"===e.kind)for(let t of np){let r=await rm(ry(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==r.exitCode){let e=`${r.stdout}
7
+ ${r.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}async function nJ(e,t){await rJ(nW,e.deviceId,async()=>{nH.get(e.deviceId)===e&&(eM({level:"warn",phase:"ios_runner_session_invalidated",data:{deviceId:e.deviceId,sessionId:e.sessionId,reason:t}}),await nX(e.deviceId,e,{graceful:!1,waitTimeoutMs:1e3}))})}async function nX(e,t,r={}){let n=t??nH.get(e);if(n){var a;if(!1!==r.graceful)try{await rR(n.device,n.port,{command:"shutdown"},void 0,15e3)}catch{await n1(n.child.pid,"SIGTERM")}else await n1(n.child.pid,"SIGTERM");try{await Promise.race([n.testPromise,new Promise(e=>setTimeout(e,r.waitTimeoutMs??1e4))])}catch{}(a=n.child.pid)&&(n0(a)||eI(a))&&await n1(n.child.pid,"SIGKILL"),rz(n.xctestrunPath),rz(n.jsonPath),await n.simulatorSetRedirect?.release(),nH.get(e)===n&&nH.delete(e)}}async function nY(e){await rJ(nW,e,async()=>{await nX(e)})}async function nZ(){let e=Array.from(nH.values()),t=Array.from(nl);await Promise.allSettled(e.map(async e=>{await n1(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await n1(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await n1(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await n1(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await n1(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await n1(e.pid,"SIGKILL"),nl.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function nQ(){await nZ();let e=Array.from(nH.keys());await Promise.allSettled(e.map(async e=>{await nY(e)}));let t=Array.from(nl);await Promise.allSettled(t.map(async e=>{try{await n1(e.pid,"SIGTERM"),await n1(e.pid,"SIGKILL")}finally{nl.delete(e)}}))}function n0(e){return!!e&&eS(e)}async function n1(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}try{process.kill(e,t)}catch{}let r="SIGINT"===t?"INT":"SIGTERM"===t?"TERM":"KILL";try{await rf("pkill",[`-${r}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function n2(e){await rm(ry(e,["bootstatus",e.id,"-b"]),{timeoutMs:rx})}async function n3(e,t,r,n,a,i){var o,s;if(o=t,s=r.command,o.startupTimingsReported||!o.startupTimings||(o.startupTimingsReported=!0,eM({level:"info",phase:"ios_runner_session_startup_timings",durationMs:Object.values(o.startupTimings).reduce((e,t)=>e+t,0),data:{command:s,sessionId:o.sessionId,ready:o.ready,timings:o.startupTimings}})),r_(r.command)){let o=await rR(e,t.port,r,n,a,t,i);return await n5(o,t,n)}let l=ep.fromTimeoutMs(a),u=t.ready?Math.min(5e3,l.remainingMs()):Math.min(rx,l.remainingMs()),d=await ex("ios_runner_readiness_preflight",async()=>await rR(e,t.port,{command:"uptime"},n,u,t,i),{command:r.command,sessionReady:t.ready,timeoutMs:u});await n5(d,t,n);let c=l.remainingMs();if(c<=0)throw new k("COMMAND_FAILED","Runner command deadline exceeded",{timeoutMs:a});let p=await ex("ios_runner_command_send",async()=>await rT(e,t.port,r,c,i),{command:r.command});return await n5(p,t,n)}async function n5(e,t,r){let n,a=await e.text();try{let e=JSON.parse(a);n=e&&"object"==typeof e?e:{}}catch{throw new k("COMMAND_FAILED","Invalid runner response",{text:a})}if(!n.ok){let e=n.error?.code;throw new k("string"==typeof e&&e.trim().length>0?x(e):"COMMAND_FAILED",("string"==typeof n.error?.message?n.error.message:void 0)??"Runner error",{runner:n,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:r})}return(t.ready=!0,n.data&&"object"==typeof n.data&&!Array.isArray(n.data))?n.data:{}}async function n4(e,t,r){let n=Date.now();try{return await r()}finally{let r=Date.now()-n;e[t]=r,eM({level:"debug",phase:`ios_runner_startup_${t}`,durationMs:r})}}let n8=new m;function n6(e,t={}){return void 0!==n9(e,t)}function n9(e,t={}){let r=n8.getStore();return r&&r.deviceId===e.id&&(r.requestId?r.requestId===t.requestId:!t.requestId)?r:void 0}async function n7(e,t,r){if(!e)return await r();let n={provider:ae(e),deviceId:t.deviceId,requestId:t.requestId};return await n8.run(n,r)}function ae(e){return"function"==typeof e?{runCommand:e}:e}async function at(e,t,r={}){if("ios"!==e.platform&&"macos"!==e.platform)throw new k("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new k("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);rN(r.requestId);let n=function(e,t,r,n={}){if(r)return ae(r);let a=n9(e,n);return a?ae(a.provider):ae(t)}(e,{runCommand:ar},void 0,{requestId:r.requestId});return r_(t.command)?ed(()=>(rN(r.requestId),n.runCommand(e,t,r)),{shouldRetry:e=>(rN(r.requestId),rI(e))}):n.runCommand(e,t,r)}async function ar(e,t,r){let n;rN(r.requestId);let a=t9(r.requestId);try{let i=(n=await nz(e,r)).ready?rM:rx;return await n3(e,n,t,r.logPath,i,a)}catch(o){let i=o instanceof k?o:new k("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===i.code&&"string"==typeof i.message&&i.message.includes("Runner did not accept connection")&&rA(i)&&n){rN(r.requestId),await nJ(n,"runner_connect_failed_before_command_send"),n=await nz(e,{...r,cleanStaleBundles:!0});try{return await n3(e,n,t,r.logPath,rx,a)}catch(e){throw rI(e instanceof k?e:new k("COMMAND_FAILED",String(e)))&&await nJ(n,"transport_error_after_retry_command_send"),e}}throw!n&&i.message.includes("Runner did not accept connection")&&await nY(e.id),n&&rI(i)&&await nJ(n,"transport_error_after_command_send"),o}}function an(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}let aa=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw",...e2,"relaunch","saveScript","noRecord","fps","quality","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"];function ai(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 ao(e){let t=new Set,r=[];for(let n of e)t.has(n)||(t.add(n),r.push(n));return r}let as=/^-?\d+(\.\d+)?$/,al=/^[^\s"\\]+$/,au=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),ad=new Map([["--count","count"],["--pause-ms","pauseMs"]]),ac=new Map([["--delay-ms","delayMs"]]);function ap(e){return"click"===e||"press"===e}function af(e){return"type"===e||"fill"===e}function am(e){return aw(e,ag)}function ah(e){return JSON.stringify(e)}function aw(e,t){return t(e)?e:ah(e)}function ag(e){return ay(e)&&e.startsWith("@")||as.test(e)}function ay(e){return al.test(e)}function av(e,t){let r=t.flags??{};if(ap(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}af(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function aI(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",aw(t.metroHost,ay)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",aw(t.bundleUrl,ay)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",aw(t.launchUrl,ay)))}function aA(e,t){let r=[],n={},a=ap(e)?au:"swipe"===e?ad:af(e)?ac:void 0;for(let i=0;i<t.length;i+=1){let o=t[i];if(ap(e)&&"--double-tap"===o){n.doubleTap=!0;continue}if(ap(e)&&"--button"===o&&i+1<t.length){let e=t[i+1];("primary"===e||"secondary"===e||"middle"===e)&&(n.clickButton=e),i+=1;continue}let s=a?.get(o);if(s&&i+1<t.length){let e=ab(t[i+1]);if(null!==e){n[s]=e,i+=1;continue}}if("swipe"===e&&"--pattern"===o&&i+1<t.length){let e=t[i+1];("one-way"===e||"ping-pong"===e)&&(n.pattern=e),i+=1;continue}r.push(o)}return{positionals:r,flags:n}}function aS(e){let t=[],r={};for(let n=0;n<e.length;n+=1){let a=e[n];if("--platform"===a&&n+1<e.length){let t=e[n+1];("ios"===t||"android"===t)&&(r.platform=t),n+=1;continue}if("--metro-host"===a&&n+1<e.length){r.metroHost=e[n+1],n+=1;continue}if("--metro-port"===a&&n+1<e.length){let t=ab(e[n+1]);null!==t&&(r.metroPort=t),n+=1;continue}if("--bundle-url"===a&&n+1<e.length){r.bundleUrl=e[n+1],n+=1;continue}if("--launch-url"===a&&n+1<e.length){r.launchUrl=e[n+1],n+=1;continue}t.push(a)}return{positionals:t,flags:r}}function ab(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function a_(e,t={}){let r=[e.command];if("snapshot"===e.command)e.flags?.snapshotInteractiveOnly&&r.push("-i"),e.flags?.snapshotCompact&&r.push("-c"),"number"==typeof e.flags?.snapshotDepth&&r.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&r.push("-s",am(e.flags.snapshotScope)),e.flags?.snapshotRaw&&r.push("--raw");else if("open"===e.command){for(let t of e.positionals??[])r.push(am(t));e.flags?.relaunch&&r.push("--relaunch"),aI(r,e.runtime)}else if("runtime"===e.command)!function(e,t,r={}){let n=t.positionals??[];for(let t of r.includeAllPositionals?n:n.slice(0,1))e.push(aw(t,ay));aI(e,t.flags)}(r,e,{includeAllPositionals:t.runtimeIncludeAllPositionals});else if("record"===e.command)!function(e,t){let[r,...n]=t.positionals??[];for(let t of(r&&e.push(aw(r,ay)),n))e.push(am(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")}(r,e);else if("screenshot"===e.command){for(let t of e.positionals??[])r.push(am(t));eU(r,e.flags)}else{for(let t of e.positionals??[])r.push(am(t));av(r,e)}return r.join(" ")}class aN{sessionsDir;constructor(e){this.sessionsDir=e}write(e){let t;try{if(!e.recordSession)return{written:!1};t=this.resolveScriptPath(e);let r=p.dirname(t);s.existsSync(r)||s.mkdirSync(r,{recursive:!0});let n=function(e){var t=e,r=function(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let n=function(e){let t=function(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];return t.length>0?t.join(" || "):void 0}(e);if(t&&ax(e.command))return ap(e.command)?{...e,positionals:[t]}:"fill"===e.command?function(e,t){let r=ai(e);return r.length>0?{...e,positionals:[t,r]}:void 0}(e,t):function(e,t){let r=e.positionals?.[0];return"text"===r||"attrs"===r?{...e,positionals:[r,t]}:void 0}(e,t)}(r);if(n){t.push(n);continue}let a=function(e,t){if(!ax(t.command))return;let r=t.result?.refLabel;if("string"!=typeof r||0===r.trim().length)return;let n=r.trim();return{ts:t.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:n},result:{scope:n}}}(e,r);a&&t.push(a),t.push(r)}return t}(e);let n=[],a=t.device.kind?` kind=${t.device.kind}`:"";for(let e of(n.push(`context platform=${t.device.platform} device=${ah(t.device.name)}${a} theme=unknown`),r))e.flags?.noRecord||n.push(function(e){var t,r;let n=(t=[e.command],r=e,ap(r.command)?function(e,t){let r=t.positionals?.[0];if(r){if(r.startsWith("@"))return e.push(am(r)),aM(e,t),av(e,t),e.join(" ");if(1===t.positionals.length)return e.push(am(r)),av(e,t),e.join(" ")}}(t,r):"fill"===r.command?function(e,t){let r=t.positionals?.[0];if(!r?.startsWith("@"))return;e.push(am(r)),aM(e,t);let n=t.positionals.slice(1).join(" ");return t.positionals.length>1&&e.push(am(n)),av(e,t),e.join(" ")}(t,r):"get"===r.command?function(e,t){let r=t.positionals?.[0],n=t.positionals?.[1];if(r&&n)return e.push(am(r)),e.push(am(n)),n.startsWith("@")&&aM(e,t),e.join(" ")}(t,r):void 0);return n||a_(e)}(e));return`${n.join("\n")}
8
+ `}(e);return s.writeFileSync(t,n),{written:!0,path:t}}catch(r){return eM({level:"warn",phase:"session_script_write_failed",data:{session:e.name,path:t,error:r instanceof Error?r.message:String(r)}}),{written:!1}}}resolveScriptPath(e){if(e.saveScriptPath)return eE(e.saveScriptPath,{cwd:void 0});s.existsSync(this.sessionsDir)||s.mkdirSync(this.sessionsDir,{recursive:!0});let t=an(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return p.join(this.sessionsDir,`${t}-${r}.ad`)}}function ax(e){return ap(e)||"fill"===e||"get"===e}function aM(e,t){let r=t.result?.refLabel;"string"==typeof r&&r.trim().length>0&&e.push(am(r))}class aD{sessions=new Map;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new aN(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=eE(t.flags.saveScript,{cwd:void 0}))),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 aa)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),eM({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){let t=this.scriptWriter.write(e);t.written&&eM({level:"info",phase:"session_script_written",data:{session:e.name,path:t.path}})}defaultTracePath(e){let t=an(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return p.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return p.join(this.sessionsDir,an(e),"app.log")}resolveAppLogPidPath(e){return p.join(this.sessionsDir,an(e),"app-log.pid")}static expandHome(e,t){return eE(e,{cwd:t})}}let ak="app-log.pid";function aE(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 aO(e,t){if(!e)return;let r=p.dirname(e);s.existsSync(r)||s.mkdirSync(r,{recursive:!0});let n={pid:t,startTime:ew(t)??void 0,command:ey(t)??void 0};s.writeFileSync(e,`${JSON.stringify(n)}
9
+ `)}function aP(e){if(e&&s.existsSync(e))try{s.unlinkSync(e)}catch{}}async function aC(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}function aL(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],n="",a=n=>{(!(r.length>0)||r.some(e=>n.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}(n,t.redactionPatterns))};return{onChunk:e=>{let t=`${n}${e}`.split("\n");for(let e of(n=t.pop()??"",t))a(`${e}
10
+ `)},flush:()=>{n&&(a(n),n="")}}}function aR(e,t,r){let n=e.stdout,a=e.stderr;return n&&a?(n.setEncoding("utf8"),a.setEncoding("utf8"),n.on("data",r.writer.onChunk),a.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(n=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),n({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}function aT(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new k("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function a$(e,t){let r=(await e6(K(e))(["shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function aF(e,t){var r,n;let a;aT(t);let i=await a$(e,t),o=e6(K(e)),s=await ee(o,{lines:4e3,timeoutMs:3e3}).catch(()=>"");if(0===s.trim().length)return null;let l=function(e,t,r){let n=new Set;for(let a of(r&&n.add(r),e.split("\n")))if(a.includes(t))for(let e of function(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=[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")],a=[];for(let t of n){let r=t.exec(e),n=r?.[1];n&&/^\d+$/.test(n)&&a.push(n)}return a}(a,t))n.add(e);return[...n]}(s,t,i);if(0===l.length)return null;let u=(r=s,n=t,a=new Set(l),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(n))return!0;let i=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!i&&a.has(i)}).join("\n"));return 0===u.trim().length?null:{pid:i,text:u,recoveredPids:l}}async function aU(e,t,r,n,a){let i,o,s="recovering",l=!1,u=(async()=>{try{for(;!l;){let u=await a$(e,t);if(!u){s="recovering",await ef(1e3);continue}let d=e8(K(e)),c=j(d,{pid:u});i=c;let p=aL(r,{redactionPatterns:n});if(o=aR(c,r,{endStreamOnClose:!1,writer:p}),"number"==typeof c.pid&&aO(a,c.pid),s="active",await o,aP(a),i=void 0,o=void 0,l)break;s="recovering",await ef(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),aP(a)}})();return{backend:"android",getState:()=>s,startedAt:Date.now(),wait:u,stop:async()=>{l=!0,i&&!i.killed&&i.kill("SIGINT"),o&&await aC(o),i&&!i.killed&&i.kill("SIGKILL"),await aC(u),aP(a)}}}function aG(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function aV(e){let{deviceId:t,appBundleId:r,startedAt:n,simulatorSetPath:a}=e,i=rg(["spawn",t,"log","show","--style","compact","--info","--predicate",aG(r)],{simulatorSetPath:a});"number"==typeof n&&Number.isFinite(n)&&n>0?i.push("--start",`@${Math.floor(n/1e3)}`):i.push("--last","5m");let o=await rm(i,{allowFailure:!0,timeoutMs:4e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=o.stdout.split("\n").map(e=>e.trimEnd()).filter(e=>{let t=e.trim();return t.length>0&&!t.startsWith("Timestamp Ty Process[PID:TID]")});return 0===s.length?null:{text:`${s.join("\n")}
11
+ `,recoveredLineCount:s.length}}async function aj(e,t,r,n,a,i){return aH({backend:"ios-simulator",cmd:"xcrun",args:function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:n}=e;return rg(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",aG(r)],{simulatorSetPath:n})}({deviceId:e,appBundleId:t,simulatorSetPath:a}),stream:r,redactionPatterns:n,pidPath:i})}async function aB(e,t,r,n){return aH({backend:"macos",cmd:"log",args:["stream","--style","compact","--predicate",aG(e)],stream:t,redactionPatterns:r,pidPath:n})}async function aq(e,t,r,n){return aH({backend:"ios-device",cmd:"xcrun",args:["devicectl","device","log","stream","--device",e],stream:t,redactionPatterns:r,pidPath:n})}function aH(e){let t="active",r=E(e.cmd,e.args,{allowFailure:!0,captureOutput:!1});r.wait.catch(()=>{});let n=r.child,a=aL(e.stream,{redactionPatterns:e.redactionPatterns});"number"==typeof n.pid&&aO(e.pidPath,n.pid);let i=aR(n,e.stream,{endStreamOnClose:!0,writer:a}).then(r=>(0!==r.exitCode&&(t="failed"),aP(e.pidPath),r),r=>{throw t="failed",aP(e.pidPath),r});return{backend:e.backend,getState:()=>t,startedAt:Date.now(),wait:i,stop:async()=>{n.killed||n.kill("SIGINT"),await aC(i),n.killed||n.kill("SIGKILL"),await aC(i),aP(e.pidPath)}}}let aW=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),az=/https?:\/\/[^\s"'<>\])]+/i,aK=[/\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 aJ(e,t,r=e.limits.maxEntries){let n=[...e.entries],a=new Set(n.map(e=>aY(e)));for(let e of t.entries){let t=aY(e);if(!a.has(t)&&(a.add(t),n.push(e),n.length>=r))break}return{...e,matchedLines:n.length,entries:n}}function aX(e,t){let r=a6(t?.maxEntries,25,1,200),n=t?.backend,a=t?.include??"summary",i=a6(t?.maxPayloadChars,2048,64,16384),o=a6(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),u=s.slice(l),d=[];for(let e=u.length-1;e>=0&&d.length<r;e-=1){let t=u[e];if(!t?.trim())continue;let r=function(e,t,r,n,a,i){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let n=e.slice(t,r+1);try{let e=JSON.parse(n);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=a3(s,["method","httpMethod"]),u=a3(s,["url","requestUrl"]),d=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=aW.exec(o),p=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),f=(l??p?.[1]??c?.[1])?.toUpperCase(),m=az.exec(o),h=u??m?.[0];if(!h)return null;let w=d??aQ(o)??void 0;if(!(l||p?.[1]||c?.[1]||void 0!==w||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let g={method:f,url:h,status:w,timestamp:a0(o),packetId:a1(o)??void 0,durationMs:a2(o)??void 0,raw:a8(o,i),line:r};if("android"===n&&function(e,t,r){let n=aZ(t,r,5),a=e.packetId??n.map(e=>a1(e)).find(e=>"string"==typeof e&&e.length>0);a&&(e.packetId=a);let i=a?aZ(t,r,12).filter(e=>a1(e)===a):n;e.timestamp||(e.timestamp=i.map(e=>a0(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=i.map(e=>aQ(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=i.map(e=>a2(e)).find(e=>"number"==typeof e))}(g,e,t),"headers"===a||"all"===a){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return a4(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(g.headers=a8(e,i))}if("body"===a||"all"===a){let e=a5(o,s,["requestBody","body","payload","request"]),t=a5(o,s,["responseBody","response"]);e&&(g.requestBody=a8(e,i)),t&&(g.responseBody=a8(t,i))}return g}(u,e,l+e+1,n,a,i);r&&d.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:u.length,matchedLines:d.length,entries:d,include:a,limits:{maxEntries:r,maxPayloadChars:i,maxScanLines:o}}}function aY(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function aZ(e,t,r){let n=[],a=Math.max(0,t-r),i=Math.min(e.length-1,t+r);for(let t=a;t<=i;t+=1){let r=e[t]?.trim();r&&n.push(r)}return n}function aQ(e){for(let t of aK){let r=t.exec(e);if(!r)continue;let n=Number.parseInt(r[1]??"",10);if(Number.isInteger(n))return n}return null}function a0(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 a1(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function a2(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 a3(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 a5(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return a4(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(n?.[1])return n[1].trim()}}function a4(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function a8(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function a6(e,t,r,n){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(n,e)):t}let a9={start:async e=>await is(e)},a7=rr(a9,function(e={}){return{...a9,...e}});async function ie(e,t){return await a7.run(e,t)}function it(e,t){let r=process.env[e];if(!r)return t;let n=Number.parseInt(r,10);return Number.isInteger(n)&&n>0?n:t}function ir(e){let t=p.dirname(e);s.existsSync(t)||s.mkdirSync(t,{recursive:!0}),function(e,t){if(s.existsSync(e)&&!(s.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,n=`${e}.${r}`;s.existsSync(t)&&(s.existsSync(n)&&s.unlinkSync(n),s.renameSync(t,n))}}(e,{maxBytes:it("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:it("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function ia(e){var t,r,n,a;let i,o,l,u,{device:d,appBundleId:c,appLogState:p,appLogStartedAt:f,appLogPath:m,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y}=e,v="macos"===d.platform?"macos":"ios"===d.platform?"device"===d.kind?"ios-device":"ios-simulator":"android",I=(t={backend:v,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y},i=a6(t?.maxEntries,25,1,200),o=t?.include??"summary",l=a6(t?.maxPayloadChars,2048,64,16384),u=a6(t?.maxScanLines,4e3,100,2e4),s.existsSync(m)?aX(s.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:o,limits:{maxEntries:i,maxPayloadChars:l,maxScanLines:u}}),A=[],S=await ii({device:d,appBundleId:c,appLogPath:m,appLogState:p});if(S){let e=await aF(d.id,c);if(e){let t=aX(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y});t.entries.length>0&&(I=aJ(t,I,h),A.push((r=S,n=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 ${n.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${n.join(", ")}.`)))}}if("ios"===d.platform&&"simulator"===d.kind&&c&&0===I.entries.length){let e=await il({deviceId:d.id,appBundleId:c,startedAt:f,simulatorSetPath:d.simulatorSetPath,appLogPath:m,maxEntries:h,include:w,maxPayloadChars:g,maxScanLines:y});e&&(e.dump.entries.length>0?(I=aJ(e.dump,I,h),A.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&&A.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===p?A.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==p&&0===A.length&&("ios"===d.platform&&"simulator"===d.kind?A.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."):A.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&A.push("ios"===(a=d).platform&&"simulator"===a.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"===a.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:A}}async function ii(e){let{device:t,appBundleId:r,appLogPath:n,appLogState:a}=e;if("android"!==t.platform||!r)return null;if(void 0!==a&&"active"!==a)return{reason:"inactive"};if("active"!==a)return null;let i=function(e){let t=function(e){if(!e||!s.existsSync(e))return null;try{return aE(s.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(p.join(p.dirname(n),ak));if(!i)return null;let o=await a$(t.id,r);return o&&o!==i?{reason:"stale-active",trackedPid:i}:null}async function io(e,t,r,n){return await a7.resolve(void 0).start({device:e,appBundleId:t,outPath:r,pidPath:n})}async function is({device:e,appBundleId:t,outPath:r,pidPath:n}){ir(r);let a=s.createWriteStream(r,{flags:"a"}),i=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await aq(e.id,a,i,n):await aj(e.id,t,a,i,e.simulatorSetPath,n);if("android"===e.platform)return aT(t),await aU(e.id,t,a,i,n);if("macos"===e.platform)return await aB(t,a,i,n);throw a.end(),new k("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function il(e){let t=await aV({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:aX(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 iu(e){await e.stop(),await aC(e.wait)}async function id(e,t){let r={},n=[];if(t||n.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let t=await R(e,["shell","echo","ok"],{allowFailure:!0,timeoutMs:1e3});r.adbAvailable=0===t.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await R(e,["shell","pidof",t],{allowFailure:!0,timeoutMs:1e3})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await rm(["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await rm(["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await P("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:n}}function ic(e){let t=p.dirname(e),r=p.basename(e);s.existsSync(t)||s.mkdirSync(t,{recursive:!0}),s.existsSync(e)?s.truncateSync(e,0):s.writeFileSync(e,"","utf8");let n=0;for(let e of s.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let a=e.slice(r.length+1);if(/^\d+$/.test(a))try{s.unlinkSync(p.join(t,e)),n+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:n}}let ip=new Map;function im(e){let t=i.randomUUID(),r=setTimeout(()=>{ih(t)},9e5);return r.unref(),ip.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}function ih(e){let t=ip.get(e);if(t&&(clearTimeout(t.timer),ip.delete(e),t.deleteAfterDownload))try{s.rmSync(t.artifactPath,{force:!0})}catch{}}let iw=new Map;function ig(e,t){let r=iw.get(e);if(!r)throw new k("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new k("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function iy(e){let t=iw.get(e);t&&(clearTimeout(t.timer),iw.delete(e),s.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function iv(e){let t=await iI(e);await P("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=p.join(e.tempDir,t);if(!s.existsSync(r))throw new k("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function iI(e){let t=await P("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new k("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 k("INVALID_ARGS","Uploaded app bundle archive is empty");let n=r.map(iA),a=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let n=[...r];if("ios"===t){let e=n.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new k("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new k("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===n.length)return n[0];throw new k("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${n.join(", ")}`)}(n,e.platform);if(!n.some(e=>e===a||e.startsWith(`${a}/`)))throw new k("INVALID_ARGS",`Uploaded archive must contain a top-level "${a}" bundle`);for(let e of n){var i=e,o=a;if(i!==o&&!i.startsWith(`${o}/`))throw new k("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${i}`)}for(let t of(await P("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new k("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return a}function iA(e){if(e.includes("\0"))throw new k("INVALID_ARGS",`Invalid archive entry: ${e}`);if(p.posix.isAbsolute(e))throw new k("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=p.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new k("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let iS=em(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function ib(e,t){return new Promise((r,n)=>{let a,i=!1,o=0,l=s.createWriteStream(t),u=e=>{if(!i){if(i=!0,a&&clearTimeout(a),e)return void i_(l,t).finally(()=>n(e));r()}},d=()=>{a&&clearTimeout(a),a=setTimeout(()=>{let t=new k("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:iS});"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t),c.destroy(t),u(t)},iS)},c=new I({transform(e,t,r){d();let n=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e,t);(o+=n)>0x80000000?r(new k("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")):r(null,e)}});e.on("aborted",()=>{u(new k("COMMAND_FAILED","Artifact transfer was interrupted"))}),d(),A(e,c,l).then(()=>u(),e=>u(e))})}async function i_(e,t){if(e.destroy(),!e.closed)try{await v(e,"close")}catch{}await s.promises.rm(t,{force:!0}).catch(()=>{})}async function iN(e){let t,r=e.headers["x-artifact-type"],n=e.headers["x-artifact-filename"];if(!r||!n)throw new k("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new k("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 k("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let a=function(e){let t=e.trim(),r=p.basename(t);if(!r||"."===r||".."===r)throw new k("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(n),i=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),s.mkdtempSync(p.join(d.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=p.join(i,a);return await ib(e,t),{artifactPath:t,tempDir:i}}let t=p.join(i,"artifact.tar");await ib(e,t);let n=await iv({archivePath:t,tempDir:i,platform:"ios",expectedRootName:a});return s.rmSync(t,{force:!0}),{artifactPath:n,tempDir:i}}catch(e){throw s.rmSync(i,{recursive:!0,force:!0}),e}}let ix=new Set(["agent_device.command","agent-device.command"]),iM=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),iD=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),ik={"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"},iE=new Set([...ix,...iM,...iD,...Object.keys(ik)]);function iO(e,t,r,n){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:n}}}function iP(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function iC(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function iL(e,t){let r="string"==typeof t.authorization?t.authorization:"",n=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,a="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??a??n??""}function iR(e,t){let r=e[t];return"string"==typeof r?r:void 0}function iT(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}function i$(e,t){let r="string"==typeof e[t]?e[t].trim():"";if(!r)throw new k("INVALID_ARGS",`Invalid params: source.${t} is required for github-actions-artifact sources`);return r}function iF(e,t){let r=e[t],n="number"==typeof r?r:"string"==typeof r?Number(r):NaN;if(!Number.isInteger(n))throw new k("INVALID_ARGS",`Invalid params: source.${t} must be an integer`);return n}async function iU(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=D(new k("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:iO(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=D(new k(x(r.code,"UNAUTHORIZED"),r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:iO(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=eR(r.tenantId);if(!e){let e=D(new k("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:iO(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function iG(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",n=p.isAbsolute(t)?t:p.resolve(t);try{e=await import(y(n).href)}catch(e){throw new k("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:n,error:e instanceof Error?e.message:String(e)})}let a=e[r];if("function"!=typeof a)throw new k("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:n,exportName:r});return a}async function iV(e){let t=await iG(),{handleRequest:r,token:n}=e;return w.createServer((e,a)=>{if("GET"===e.method&&"/health"===e.url){a.statusCode=200,a.setHeader("content-type","application/json"),a.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void ij(e,a,t,n);if("GET"===e.method&&e.url?.startsWith("/artifacts/"))return void iB(e,a,t,n);if("POST"!==e.method||"/rpc"!==e.url){a.statusCode=404,a.end("Not found");return}let i="";e.setEncoding("utf8"),e.on("data",t=>{(i+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{a.headersSent||iP(a,iO(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let n,o;try{n=JSON.parse(i)}catch{iP(a,iO(null,-32700,"Parse error"),400);return}if("2.0"!==n.jsonrpc||"string"!=typeof n.method)return void iP(a,iO(n.id??null,-32600,"Invalid Request"),400);if(!iE.has(n.method))return void iP(a,iO(n.id??null,-32601,`Method not found: ${n.method}`),404);if(!n.params||"object"!=typeof n.params)return void iP(a,iO(n.id??null,-32602,"Invalid params"),400);try{var s;let i=n.params,l=function(e,t,r){if(ix.has(e))return{token:iL(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(iM.has(e)){let e,n=iR(t,"platform");if("ios"!==n&&"android"!==n)throw new k("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:iL(t,r),session:iR(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:n},meta:{requestId:iR(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new k("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new k("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,n={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new k("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 k("INVALID_ARGS","Invalid params: source.headers values must be strings");n[e]=t}}return Object.keys(n).length>0?{kind:"url",url:e,headers:n}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new k("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}if("github-actions-artifact"===t.kind)return function(e){let t,r=i$(e,"owner"),n=i$(e,"repo"),a=void 0!==e.artifactId,i=void 0!==e.runId,o=void 0!==e.artifactName;if(a&&(i||o))throw new k("INVALID_ARGS","Invalid params: source must specify either artifactId or artifactName, not both");if(!a&&i&&!o)throw new k("INVALID_ARGS","Invalid params: source.artifactName is required when source.runId is specified");if(!a&&!o)throw new k("INVALID_ARGS","Invalid params: source must specify artifactId or artifactName");return a?{kind:"github-actions-artifact",owner:r,repo:n,artifactId:iF(e,"artifactId")}:(i&&(t=iF(e,"runId")),{kind:"github-actions-artifact",owner:r,repo:n,...i?{runId:t}:{},artifactName:i$(e,"artifactName")})}(t);throw new k("INVALID_ARGS",'Invalid params: source.kind must be "url", "path", or "github-actions-artifact"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:iT(t,"retentionMs")}}}if(iD.has(e)){let e=iR(t,"materializationId")?.trim();if(!e)throw new k("INVALID_ARGS","Invalid params: materializationId is required");return{token:iL(t,r),session:iR(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:iR(t,"requestId"),materializationId:e}}}let n=ik[e];if(n)return{token:iL(t,r),session:iR(t,"session")??"default",command:n,positionals:[],meta:{tenantId:iR(t,"tenantId")??iR(t,"tenant"),runId:iR(t,"runId"),leaseId:iR(t,"leaseId"),leaseTtlMs:iT(t,"ttlMs"),leaseBackend:iR(t,"backend")}};throw new k("INVALID_ARGS",`Method not found: ${e}`)}(n.method,i,e.headers);if(s=n.method,ix.has(s)&&("string"!=typeof l.command||0===l.command.length))return void iP(a,iO(n.id??null,-32602,"Invalid params: command is required"),400);o=t3(l.meta?.requestId,n.id),l.meta={...l.meta,requestId:o},t5(o);let u=()=>{a.writableFinished||t4(o)};e.on("aborted",u),a.on("close",u);let d=await iU(t,{headers:e.headers,rpcRequest:n,daemonRequest:l});if(!d.ok)return void iP(a,d.response,d.statusCode);d.tenantId&&(l.meta={...l.meta,tenantId:d.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void iP(a,{jsonrpc:"2.0",id:n.id??null,result:c});iP(a,iO(n.id??null,-32e3,c.error.message,c.error),iC(c.error.code))}catch(t){let e=D(t);iP(a,iO(n.id??null,-32e3,e.message,e),iC(e.code))}finally{t8(o)}})})}async function ij(e,t,r,n){try{var a;let o,s,l=iL({},e.headers),u=iq(l,n);if(u){t.statusCode=iC(u.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.message,code:u.code}));return}let d=await iU(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!d.ok){t.statusCode=d.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.response.error?.data?.message??d.response.error?.message??"Unauthorized"}));return}let c=await iN(e),p=(a={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:d.tenantId},o=i.randomUUID(),(s=setTimeout(()=>{iy(o)},3e5)).unref(),iw.set(o,{artifactPath:a.artifactPath,tempDir:a.tempDir,tenantId:a.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:p}))}catch(r){let e=D(r);t.statusCode=iC(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function iB(e,t,r,n){let a=e.url?.slice("/artifacts/".length)??"";if(!a){t.statusCode=400,t.end("Missing artifact id");return}try{let i=iL({},e.headers),o=iq(i,n);if(o){t.statusCode=iC(o.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:o.message,code:o.code}));return}let l=await iU(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:i,session:"default",command:"download_artifact",positionals:[a]}});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 u=function(e,t){let r=ip.get(e);if(!r)throw new k("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new k("UNAUTHORIZED","Artifact belongs to a different tenant");if(!s.existsSync(r.artifactPath))throw ih(e),new k("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(a,l.tenantId),d=s.createReadStream(u.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),u.fileName&&t.setHeader("content-disposition",`attachment; filename="${u.fileName.replace(/"/g,"")}"`),d.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=D(e);t.statusCode=iC(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&ih(a)}),d.pipe(t)}catch(r){let e=D(r);t.statusCode=iC(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function iq(e,t){return t&&e!==t?D(new k("UNAUTHORIZED","Invalid token")):null}function iH(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function iW(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function iz(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 k("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class iK{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=iz(e.backend),r=eR(e.tenantId);if(!r)throw new k("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let n=iH(e.runId);if(!n)throw new k("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let a=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,n,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,a);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),u={leaseId:i.randomBytes(16).toString("hex"),tenantId:r,runId:n,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+a};return this.leases.set(u.leaseId,u),this.runBindings.set(o,u.leaseId),{...u}}heartbeatLease(e){let t=iW(e.leaseId);if(!t)throw new k("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new k("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let n=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,n)}releaseLease(e){let t=iW(e.leaseId);if(!t)throw new k("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=iz(e.backend),r=eR(e.tenantId);if(!r)throw new k("INVALID_ARGS","tenant isolation requires tenant id.");let n=iH(e.runId);if(!n)throw new k("INVALID_ARGS","tenant isolation requires run id.");let a=iW(e.leaseId);if(!a)throw new k("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let i=this.leases.get(a);if(!i)throw new k("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(i.backend!==t||i.tenantId!==r||i.runId!==n)throw new k("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 k("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 k("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),n={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(n.leaseId,n),this.runBindings.set(this.bindingKey(n.tenantId,n.runId,n.backend),n.leaseId),{...n}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let n=eR(t),a=iH(r);if(t&&!n)throw new k("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!a)throw new k("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(n&&e.tenantId!==n||a&&e.runId!==a)throw new k("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}function iJ(){return{platform:"macos",id:"host-macos-local",name:d.hostname(),kind:"device",target:"desktop",booted:!0}}async function iX(){return[iJ()]}let iY=em(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),iZ=/^(iphone|ipad|ipod|appletv)/i,iQ=/\b(iphone|ipad|ipod)\b/i,i0=/^appletv/i,i1=["apple tv","appletv","tvos"],i2=/^==\s*(.+?)\s*==$/,i3=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function i5(e){return(e??"").trim().toLowerCase()}function i4(e){return i5(e.hardwareProperties?.platform)}function i8(e){return e.includes("tvos")}function i6(e){let t=i5(e);return i1.some(e=>t.includes(e))}function i9(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function i7(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function oe(e={}){let t,r,n=T(e.simulatorSetPath),a=e.target;try{t=await rm(rg(["list","devices","-j"],{simulatorSetPath:n}))}catch{return null}try{r=JSON.parse(t.stdout)}catch{return null}let i=ot(r,n),o=null,s=null,l=null;for(let e of i)a&&e.target!==a||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function ot(e,t){let r=[];for(let[n,a]of Object.entries(e.devices))if(function(e){let t=i5(e);return t.includes("ios")||t.includes("tvos")}(n))for(let e of a)e.isAvailable&&r.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:i8(i5(n))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return r}function or(e,t){let r=new Set(e.map(e=>e.id)),n=[...e];for(let e of t)r.has(e.id)||(r.add(e.id),n.push(e));return n}async function on(){let e=null;try{e=p.join(d.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await rm(["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:iY});if(0!==t.exitCode)return[];let r=await u.readFile(e,"utf8");return function(e){let t=[];for(let r of e.result?.devices??[]){if(!function(e){var t;let r=i4(e);return!!(r.includes("ios")||r.includes("tvos"))||(t=i7(e),!!iZ.test(t.trim())||i9(e).some(i6))}(r))continue;let e=r.hardwareProperties?.udid??r.identifier??"",n=r.name??r.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:n,kind:"device",target:function(e){var t;return i8(i4(e))?"tv":(t=i7(e),i0.test(t.trim())||i9(e).some(i6))?"tv":"mobile"}(r),booted:!0})}return t}(JSON.parse(r))}catch{return[]}finally{e&&await u.rm(e,{force:!0}).catch(()=>{})}}async function oa(){try{let e=await rm(["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],r=null;for(let n of e.split(/\r?\n/)){let e=n.trim();if(!e)continue;let a=i2.exec(e);if(a){r=a[1]?.trim()??null;continue}if("Devices"!==r)continue;let i=i3.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return i6(e)?"tv":iQ.test(e.trim())?"mobile":null}(s);l&&t.push({platform:"ios",id:o,name:s,kind:"device",target:l,booted:!0})}return t}(e.stdout)}catch{return[]}}async function oi(e={}){if("darwin"!==process.platform)throw new k("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await rc().whichCommand("xcrun"))throw new k("TOOL_MISSING","xcrun not found in PATH");let t=T(e.simulatorSetPath),r=await rm(rg(["list","devices","-j"],{simulatorSetPath:t})),n=[];try{let e=JSON.parse(r.stdout);n=ot(e,t)}catch(e){throw new k("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(n.push(iJ()),e.udid&&n.some(t=>"ios"===t.platform&&t.id===e.udid)||t)return n;let[a,i]=await Promise.all([on(),oa()]);return n=or(n,a),or(n,i)}async function oo(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:c(),kind:"device",target:"desktop",booted:!0}]}let os=new m,ol=new m;async function ou(e,t,r){var n,a;let i=await od(e,t,r);if(n=t,a=i,!oc(n)&&(!n.platform||"apple"===n.platform||"ios"===n.platform)&&"desktop"!==n.target&&(!a||"device"===a.kind)){let e=await oe({simulatorSetPath:r.simulatorSetPath,target:t.target});if(e)return e}if(i)return i;throw new k("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function od(e,t,r){try{return await rQ(e,t,r)}catch(e){var n;if(n=e,!oc(t)&&n instanceof k&&"DEVICE_NOT_FOUND"===n.code)return;throw e}}function oc(e){return!!(e.udid||e.serial||e.deviceName)}async function op(e){let t=e.platform,r=rZ({simulatorSetPath:T(e.iosSimulatorDeviceSet),platform:t,target:e.target}),n=er(e.androidDeviceAllowlist),a=function(e){let{flags:t,normalizedPlatform:r,iosSimulatorSetPath:n,androidSerialAllowlist:a}=e;return JSON.stringify({platform:r,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorSetPath:n,androidSerialAllowlist:a?Array.from(a).sort():void 0})}({flags:e,normalizedPlatform:t,iosSimulatorSetPath:r,androidSerialAllowlist:n}),i={platform:t,target:e.target,cacheHit:!1};return await ex("resolve_target_device",async()=>{let o=function(e){let t=os.getStore(),r=t?.get(e);if(r)return{...r}}(a);if(o)return i.cacheHit=!0,o;let s={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(s.target&&!s.platform)throw new k("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");let l=await og({...s,iosSimulatorSetPath:r,androidSerialAllowlist:n?Array.from(n).sort():void 0});if(l)return ov(s)?oI(a,await ou(l,s,{simulatorSetPath:r})):oI(a,await rQ(l,s,{simulatorSetPath:r}));"android"===s.platform&&await V();let u=await oy({...s,iosSimulatorSetPath:r,androidSerialAllowlist:n?Array.from(n).sort():void 0});return ov(s)?oI(a,await ou(u,s,{simulatorSetPath:r})):oI(a,await rQ(u,s,{simulatorSetPath:r}))},i)}async function of(e){return os.getStore()?await e():await os.run(new Map,e)}async function om(e,t){return e?await ol.run(e,t):await t()}async function oh(e,t){return await om(e,async()=>await of(t))}async function ow(e){return await og(e)??await oy(e)}async function og(e){let t=ol.getStore();if(!t)return null;let r=await t(e);return null==r?null:r.map(e=>({...e}))}async function oy(e){if("macos"===e.platform||"apple"===e.platform&&"desktop"===e.target)return await iX();if("linux"===e.platform)return await oo();if("android"===e.platform)return await U({serialAllowlist:e.androidSerialAllowlist?new Set(e.androidSerialAllowlist):void 0});if(e.platform)return await oi({simulatorSetPath:e.iosSimulatorSetPath,udid:e.udid});let t=[];try{t.push(...await U({serialAllowlist:e.androidSerialAllowlist?new Set(e.androidSerialAllowlist):void 0}))}catch{}try{t.push(...await oi({simulatorSetPath:e.iosSimulatorSetPath,udid:e.udid}))}catch{}try{t.push(...await oo())}catch{}return t}function ov(e){return!!e.platform&&"android"!==e.platform&&"linux"!==e.platform}function oI(e,t){return os.getStore()?.set(e,{...t}),t}let oA={runCommand:P,whichCommand:C,desktop:ox(P,C),clipboard:oM(P,C),screenshot:oD(P,C)},oS=rr(oA,function(e={}){let t={...oA,...e};return{...t,desktop:e.desktop??ox(t.runCommand,t.whichCommand),clipboard:e.clipboard??oM(t.runCommand,t.whichCommand),screenshot:e.screenshot??oD(t.runCommand,t.whichCommand)}});function ob(e){return oS.resolve(e)}async function o_(e,t){return await oS.run(e,t)}async function oN(e,t,r){return await ob().runCommand(e,t,r)}function ox(e,t){return{async openTarget(r){if(r.includes("://")||r.startsWith("/"))return void await e("xdg-open",[r]);if(await t(r)){e(r,[],{allowFailure:!0}).catch(e=>{eM({level:"warn",phase:"linux_app_launch",data:{app:r,error:String(e)}})}),await ef(500);return}await e("xdg-open",[r],{allowFailure:!0})},async closeApp(r){await t("wmctrl")?await e("wmctrl",["-c",r],{allowFailure:!0}):await e("pkill",["-x",r],{allowFailure:!0})}}}function oM(e,t){return{async readText(){let r=oO[await oL(t,ok)];return(await e(r.cmd,r.args,r.options)).stdout},async writeText(r){let n=oP[await oL(t,ok)](r);await e(n.cmd,n.args,n.options)}}}function oD(e,t){return{async capture(r){let n=oC[await oL(t,oE)](r);await e(n.cmd,n.args,n.options)}}}let ok={wayland:[{tool:"wl-clipboard",command:"wl-paste"}],x11:[{tool:"xclip",command:"xclip"},{tool:"xsel",command:"xsel"}],waylandError:"wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.",x11Error:"xclip or xsel is required for clipboard access on X11. Install via your package manager."},oE={wayland:[{tool:"grim",command:"grim"},{tool:"gnome-screenshot",command:"gnome-screenshot"}],x11:[{tool:"scrot",command:"scrot"},{tool:"import",command:"import"},{tool:"gnome-screenshot",command:"gnome-screenshot"}],waylandError:"grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.",x11Error:"scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager."},oO={"wl-clipboard":{cmd:"wl-paste",args:["--no-newline"],options:{allowFailure:!0,timeoutMs:5e3}},xclip:{cmd:"xclip",args:["-selection","clipboard","-o"],options:{allowFailure:!0,timeoutMs:5e3}},xsel:{cmd:"xsel",args:["--clipboard","--output"],options:{allowFailure:!0,timeoutMs:5e3}}},oP={"wl-clipboard":e=>({cmd:"wl-copy",args:["--",e],options:{allowFailure:!1,timeoutMs:5e3}}),xclip:e=>({cmd:"xclip",args:["-selection","clipboard"],options:{allowFailure:!1,timeoutMs:5e3,stdin:e}}),xsel:e=>({cmd:"xsel",args:["--clipboard","--input"],options:{allowFailure:!1,timeoutMs:5e3,stdin:e}})},oC={grim:e=>({cmd:"grim",args:[e]}),scrot:e=>({cmd:"scrot",args:[e]}),import:e=>({cmd:"import",args:["-window","root",e]}),"gnome-screenshot":e=>({cmd:"gnome-screenshot",args:["-f",e]})};async function oL(e,t){let r=process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11";for(let n of t[r])if(await e(n.command))return n.tool;throw new k("TOOL_MISSING","wayland"===r?t.waylandError:t.x11Error)}let oR=em(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,ec.ios_boot.totalMs,5e3),oT=em(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,ec.ios_boot.operationMs,1e3),o$=em(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),oF=em(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),oU=em(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),oG=em(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),oV=em(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),oj=es(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function oB(e,t){let r=["devicectl",...e],n=await rm(r,{allowFailure:!0,timeoutMs:oF});if(0===n.exitCode)return;let a=String(n.stdout??""),i=String(n.stderr??"");throw new k("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:r,exitCode:n.exitCode,stdout:a,stderr:i,deviceId:t.deviceId,hint:oK(a,i)??oz})}async function oq(e,t){var r;return r=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let n="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,a="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;r.push({bundleId:t,name:n,url:a})}return r}(await oW(e,{jsonPrefix:"agent-device-ios-apps",args:["devicectl","device","info","apps","--device",e.id,"--include-all-apps"],failureMessage:"Failed to list iOS apps",parseFailureMessage:"Failed to parse iOS apps list"})),"user-installed"===t?r.filter(e=>!e.bundleId.startsWith("com.apple.")):r}async function oH(e){return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",n="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(n)&&r.push({executable:t,pid:n})}return r}(await oW(e,{jsonPrefix:"agent-device-ios-processes",args:["devicectl","device","info","processes","--device",e.id],failureMessage:"Failed to list iOS processes",parseFailureMessage:"Failed to parse iOS process list"}))}async function oW(e,t){let r=p.join(d.tmpdir(),`${t.jsonPrefix}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=[...t.args,"--json-output",r],a=await rm(n,{allowFailure:!0,timeoutMs:oF});try{if(0!==a.exitCode){let r=String(a.stdout??""),i=String(a.stderr??"");throw new k("COMMAND_FAILED",t.failureMessage,{cmd:"xcrun",args:n,exitCode:a.exitCode,stdout:r,stderr:i,deviceId:e.id,hint:oK(r,i)??oz})}return JSON.parse(await u.readFile(r,"utf8"))}catch(r){if(r instanceof k)throw r;throw new k("COMMAND_FAILED",t.parseFailureMessage,{deviceId:e.id,cause:String(r)})}finally{await u.unlink(r).catch(()=>{})}}let oz="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function oK(e,t){let r=`${e}
12
+ ${t}`.toLowerCase();return r.includes("device is busy")&&r.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":r.includes("coredeviceservice")&&r.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}let oJ=em(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3),oX=new Map;async function oY(e){var t;let r,n=(r="simulator"===(t=e).kind?t.simulatorSetPath??"":"",JSON.stringify([t.platform,t.kind,t.id,t.target??"",r])),a=oX.get(n);if(void 0!==a){if(a>Date.now())return;oX.delete(n)}if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(tZ);await t(e),oZ(n);return}if("device"===e.kind){await oQ(e.id),oZ(n);return}}if("android"===e.platform){let{waitForAndroidBoot:t}=await import("../1769.js");await t(e.id),oZ(n)}}function oZ(e){oX.set(e,Date.now()+5e3)}async function oQ(e){let t=p.join(d.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=Math.max(1,Math.ceil(oJ/1e3));try{let n=await rm(["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(r)],{allowFailure:!0,timeoutMs:oJ+3e3}),a=String(n.stdout??""),i=String(n.stderr??""),o=await o0(t);if(0===n.exitCode){if(!o.parsed)throw new k("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:a,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new k("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new k("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:a,stderr:i,exitCode:n.exitCode,tunnelState:o?.tunnelState,hint:o1(a,i)})}catch(t){if(t instanceof k&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let r=t.details??{},n=String(r.stdout??""),a=String(r.stderr??""),i=Number(r.timeoutMs??oJ),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new k("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:n,stderr:a,hint:n||a?o1(n,a):o},t)}throw new k("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await u.rm(t,{force:!0}).catch(()=>{})}}async function o0(e){try{let t=await u.readFile(e,"utf8"),r=JSON.parse(t),n=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let r=t.connectionProperties?.tunnelState,n=t.device?.connectionProperties?.tunnelState,a="string"==typeof r?r:"string"==typeof n?n:void 0;return a?{tunnelState:a}:{}}(r);return{parsed:!0,tunnelState:n.tunnelState}}catch{return{parsed:!1}}}function o1(e,t){let r=oK(e,t);return r||(`${e}
13
+ ${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":oz)}async function o2(e,t,r){let n="string"==typeof r.action&&r.action.trim()?r.action.trim():`${t}.TEST_PUSH`,a=["shell","am","broadcast","-a",n,"-p",t],i="string"==typeof r.receiver?r.receiver.trim():"";i&&a.push("-n",i);let o=r.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new k("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,r){if("string"==typeof r)return e.push("--es",t,r);if("boolean"==typeof r)return e.push("--ez",t,r?"true":"false");if("number"==typeof r&&Number.isFinite(r))return Number.isInteger(r)?e.push("--ei",t,String(r)):e.push("--ef",t,String(r));throw new k("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(a,e,t),s+=1);return await R(e,a),{action:n,extrasCount:s}}function o3(e){let t=e.direction,r="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,n=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new k("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),a=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new k("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(r*n),i=Math.max(1,Math.round(.05*r)),o=Math.max(1,Math.min(a,Math.max(1,r-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),u=Math.round(e.referenceHeight/2),d=(r,n,a,i)=>({direction:t,x1:r,y1:n,x2:a,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return d(l,u-s,l,u+s);case"down":return d(l,u+s,l,u-s);case"left":return d(l-s,u,l+s,u);case"right":return d(l+s,u,l-s,u)}}function o5(e){var t;return!!e&&(!!e.password||!!(t=e.text)&&Array.from(t).every(o8))}function o4(e){if(!e)return null;let t=o5(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function o8(e){return"•"===e||"*"===e||"●"===e}function o6(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function o9(e,t){let r=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),n=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=r&&Math.abs(e.crossSize-t.crossSize)<=n}function o7(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function se(e,t={}){let r=e6(e,t.helperAdb),n=await st(e,t,r),a=n.xml;if(!t.interactiveOnly){let i=e7(a,800,t);return function(e,t){for(let[r,n]of e){let e=t[r];e&&(n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0))}}(await so(e,i.nodes,r),i.nodes),{...i,androidSnapshot:n.metadata}}let i=tt(a),o=to(i,800,{...t,interactiveOnly:!1}),s=to(i,800,t),l=await so(e,o.nodes,r);sp(l,o,s),0===l.size&&sp(tm(tO(o.nodes)),o,s);let{sourceNodes:u,...d}=s;return{...d,androidSnapshot:n.metadata}}async function st(e,t,r){let n=await ex("android_snapshot_helper_artifact_resolution",async()=>await sa(t.helperArtifact));if(n.artifact){var a;let i=(a=e,`${a.platform}:${a.id}`);try{let a=e8(e,t.helperAdb),o=await ex("android_snapshot_helper_install",async()=>await te({adb:r,adbProvider:a,artifact:n.artifact,deviceKey:i,installPolicy:t.helperInstallPolicy,timeoutMs:3e4}),{packageName:n.artifact.manifest.packageName,versionCode:n.artifact.manifest.versionCode,installPolicy:t.helperInstallPolicy??"missing-or-outdated"});eM({phase:"android_snapshot_helper_install_decision",data:{packageName:o.packageName,versionCode:o.versionCode,installedVersionCode:o.installedVersionCode,installed:o.installed,reason:o.reason}});let s=await ex("android_snapshot_helper_capture",async()=>await tr({adb:r,packageName:n.artifact.manifest.packageName,instrumentationRunner:n.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:5e3,commandTimeoutMs:8e3}),{packageName:n.artifact.manifest.packageName,version:n.artifact.manifest.version,timeoutMs:5e3,commandTimeoutMs:8e3});return{xml:s.xml,metadata:{backend:"android-helper",helperVersion:n.artifact.manifest.version,helperApiVersion:s.metadata.helperApiVersion,installReason:o.reason,waitForIdleTimeoutMs:s.metadata.waitForIdleTimeoutMs,timeoutMs:s.metadata.timeoutMs,maxDepth:s.metadata.maxDepth,maxNodes:s.metadata.maxNodes,rootPresent:s.metadata.rootPresent,captureMode:s.metadata.captureMode,windowCount:s.metadata.windowCount,nodeCount:s.metadata.nodeCount,helperTruncated:s.metadata.truncated,elapsedMs:s.metadata.elapsedMs}}}catch(o){let t=function(e){let t=D(e);if(!function(e,t){if(!e||"object"!=typeof e)return!1;let r="errorType"in e?String(e.errorType):"",n=sn(e)??t;return/TimeoutException/.test(r)||/timed out/i.test(n)}(t.details?.helper,t.message))return;let r=sr(e);return new k(x(t.code),`${r}. Stock UIAutomator fallback was skipped because this usually means the Android accessibility tree is busy or stalled.`,{...t.details,hint:"Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists."},e)}(o);if(t)throw t;let a=sr(o);return eM({level:"warn",phase:"android_snapshot_helper_fallback",data:{reason:a}}),ti({deviceKey:i,packageName:n.artifact.manifest.packageName,versionCode:n.artifact.manifest.versionCode}),await si(e,a,r)}}return eM({level:n.fallbackReason?"warn":"info",phase:"android_snapshot_helper_unavailable",data:{reason:n.fallbackReason??"artifact_not_found"}}),await si(e,n.fallbackReason,r)}function sr(e){let t=D(e),r=sn(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let n=("string"==typeof t.details?.stderr?t.details.stderr.trim():"").split(/\r?\n/).find(e=>e.trim());return n?`${t.message}: ${n}`:t.message}function sn(e){if(!e||"object"!=typeof e||!("message"in e))return;let t=String(e.message).trim();return t&&"null"!==t?t:void 0}async function sa(e){if(e)return{artifact:e};let t=eD(),r=p.join(ek(),"android-snapshot-helper","dist"),n=p.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await S.access(n)}catch{return{}}try{let e=tn(JSON.parse(await S.readFile(n,"utf8"))),t=p.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await S.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{fallbackReason:D(e).message}}}async function si(e,t,r){let n;try{n=await ex("android_snapshot_stock_capture",async()=>await ss(e,r),{fallbackReason:t,timeoutMs:8e3})}catch(e){if(t){var a,i;let r;throw a=e,i=t,new k(x((r=D(a)).code),`${r.message} Android snapshot helper failed before stock fallback: ${i}`,{...r.details,androidSnapshotHelperFallbackReason:i,...r.hint?{hint:r.hint}:{}},a)}throw e}return{xml:n,metadata:{backend:"uiautomator-dump",...t?{fallbackReason:t}:{}}}}async function so(e,t,r){if(!t.some(e=>e9(e.type)))return new Map;let n=await sc(e,r);return n?function(e,t){let r=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},r=[{indent:-1,node:t}],n=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=n.exec(t);if(!e)continue;let a=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),u={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;r.length>1&&a<=r[r.length-1].indent;)r.pop();r[r.length-1].node.children.push(u),r.push({indent:a,node:u})}return t.children.length>0?t:null}(t);if(!r)return new Map;let n=function(e){let t=[],r=[e];for(;r.length>0;){let e=r.pop();if(e9(e.className)){let r=function(e){let t=e.children[0];if(!t)return null;let r=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),n=t.children.filter(e=>e.rect.height>0).map(t=>o7(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===n.length?null:{rect:e.rect,contentExtent:r,contentBlocks:n}}(e);r&&t.push(r)}r.push(...e.children)}return t}(r);if(0===n.length)return new Map;let a=new Map;for(let t of e){if(!t.rect||!e9(t.type))continue;let r=function(e,t){let r=null,n=1/0;for(let a of t){let t=Math.abs(a.rect.width-e.width)+Math.abs(a.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(a.rect.x-e.x)+Math.abs(a.rect.y-e.y));i<n&&(r=a,n=i)}return r}(t.rect,n);if(!r)continue;let i=function(e,t){let r=function(e,t){let r=t,n=new Set;for(;!n.has(r.index);){var a,i;n.add(r.index);let o=e.filter(e=>e.parentIndex===r.index&&e.rect);if(1!==o.length)return r;let s=o[0];if(a=s.rect,i=t.rect,a.x!==i.x||a.y!==i.y||a.width!==i.width||a.height!==i.height)return r;r=s}return t}(e,t);return e.filter(e=>e.parentIndex===r.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>o7(e,t.rect))}(e,t),o=function(e){let{viewportRect:t,visibleBlocks:r,nativeScrollView:n}=e;if(0===r.length||0===n.contentBlocks.length)return null;let a=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],r=e.contentBlocks[e.contentBlocks.length-1];if(!t||!r)return null;let n=o6(e.contentBlocks.map(e=>e.size))??e.rect.height,a=Math.max(48,Math.round(.5*n)),i=Math.max(24,Math.round(.25*n)),o=t.start>=a,s=e.contentExtent-(r.start+r.size)>=i;return o||s?{above:o,below:s}:null}(n),i=function(e,t){let r=new Map;for(let n of e)for(let e of t){if(!o9(n,e))continue;let t=n.start-e.start,a=8*Math.round(t/8),i=r.get(a)??[];i.push(t),r.set(a,i)}let n=null;for(let e of r.values())(!n||e.length>n.length)&&(n=e);if(!n||n.length<2)return null;let a=[...n].sort((e,t)=>e-t);return a[Math.floor(a.length/2)]??null}(n.contentBlocks,r)??function(e){let{nativeBlocks:t,visibleBlocks:r,viewportExtent:n,contentExtent:a}=e,i=[],o=[];for(let e of t)for(let t of r){if(!o9(e,t))continue;let r=e.start-t.start;16>=Math.abs(r)&&i.push(r),16>=Math.abs(r+n-a)&&o.push(r)}return o.length>0?o6(o):i.length>0?o6(i):null}({nativeBlocks:n.contentBlocks,visibleBlocks:r,viewportExtent:t.height,contentExtent:n.contentExtent});if(null===i)return a;let o=t.height;return{above:(a?.above??!1)||i>16,below:(a?.below??!1)||i+o<n.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:i,nativeScrollView:r});if(!o)continue;let s={};o.above&&(s.hiddenContentAbove=!0),o.below&&(s.hiddenContentBelow=!0),(s.hiddenContentAbove||s.hiddenContentBelow)&&a.set(t.index,s)}return a}(t,n):new Map}async function ss(e,t=e6(e)){try{return await ed(()=>sl(t),{shouldRetry:sd})}catch(e){if(function(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code||"number"!=typeof e.details?.timeoutMs)return!1;let t=e.details?.cmd,r=e.details?.args,n=Array.isArray(r)?r.map(String):"string"==typeof r?r.split(/\s+/):[];return"adb"===t&&n.includes("uiautomator")&&n.includes("dump")}(e)){let t="Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout. Stock Android UIAutomator may still time out on app-owned infinite animations.";throw new k("COMMAND_FAILED",`Android UI hierarchy dump timed out while waiting for the UI to become idle. ${t}`,{...e.details??{},hint:t},e)}throw e}}async function sl(e){var t,r,n;let a,i,o=await e(["exec-out","uiautomator","dump","/dev/tty"],{allowFailure:!0,timeoutMs:8e3}),s=su(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",u=await e(["shell","uiautomator","dump",l],{allowFailure:!0,timeoutMs:8e3}),d=(t=l,r=u.stdout,n=u.stderr,a=`${r}
14
+ ${n}`,i=/dumped to:\s*(\S+)/i.exec(a),i?.[1]??t),c=await e(["shell","cat",d]),p=su(c.stdout,c.stderr);if(!p)throw new k("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function su(e,t){let r=`${e}
15
+ ${t}`,n=r.indexOf("<?xml"),a=n>=0?n:r.indexOf("<hierarchy");if(a<0)return null;let i=r.lastIndexOf("</hierarchy>");if(i<0||i<a)return null;let o=r.slice(a,i+12).trim();return o.length>0?o:null}function sd(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,r=("string"==typeof t?t:"").toLowerCase();return!!(r.includes("device offline")||r.includes("device not found")||r.includes("transport error")||r.includes("connection reset")||r.includes("broken pipe")||r.includes("timed out")||r.includes("no such file or directory"))}async function sc(e,t=e6(e)){try{let e=await t(["shell","dumpsys","activity","top"],{allowFailure:!0,timeoutMs:8e3}),r=`${e.stdout}
16
+ ${e.stderr}`.trim();return r.length>0?r:null}catch{return null}}function sp(e,t,r){if(0===e.size)return;let n=new Map;for(let[e,t]of r.sourceNodes.entries()){let a=r.nodes[e];a&&n.set(t,a)}for(let[r,a]of e){let e=t.sourceNodes[r];if(!e)continue;let i=n.get(e);i&&(a.hiddenContentAbove&&(i.hiddenContentAbove=!0),a.hiddenContentBelow&&(i.hiddenContentBelow=!0))}}async function sf(e,t,r,n){let a=null,i=null,o=await sy(e);for(let s of[0,150,350]){s>0&&await ef(s);let l=await sh(e,t,r,n,o);if(a=l,"ime_capture"===l.reason)return l;i=l.ok?l:null}return i??a??{ok:!1,actual:null,reason:"text_mismatch",targetInput:null,actualInput:null}}async function sm(e,t,r){var n,a,i;return n=await ss(e),a=t,i=r,sw(n,a,i).actualInput?.text??null}async function sh(e,t,r,n,a){return function(e,t,r,n,a={}){var i,o;let s,l=sw(e,t,r,a);return!function(e){let{targetInput:t,actualInput:r}=e;return!!t&&!!r&&r!==t&&r.inputMethodOwned&&!t.inputMethodOwned}(l)?function(e,t){let r=e.actualInput;if(!r||!o5(r))return null;let n=r.text??null,a=Array.from(n??"").length,i=Array.from(t).length,o=null!==n&&a>0&&i>0&&a===i;return{ok:o,actual:n,reason:o?void 0:"masked_unverified",masked:!0,targetInput:e.targetInput,actualInput:r}}(l,n)??(i=l,o=n,{ok:function(e,t){if(e===t)return!0;let r=sg(e),n=sg(t);return!!r&&!!n&&!!(r===n||function(e,t){if(e.length!==t.length||0===e.length||e.slice(1)!==t.slice(1))return!1;let r=e[0],n=t[0];return!!r&&!!n&&n.toLowerCase()===n&&r===n.toUpperCase()}(r,n))}(s=i.actualInput?.text??null,o),actual:s,reason:"text_mismatch",targetInput:i.targetInput,actualInput:i.actualInput}):{ok:!1,actual:l.actualInput?.text??null,reason:"ime_capture",targetInput:l.targetInput,actualInput:l.actualInput}}(await ss(e),t,r,n,a)}function sw(e,t,r,n={}){var a;let i,o={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of ta(e)){let e=function(e,t){if(!e.rect)return null;let r=e.text??"",n=Math.max(1,e.rect.width*e.rect.height);return{text:r||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:!0===e.password,inputMethodOwned:et({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:n,editText:function(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}(e.className??"")}}(a,n);e&&function(e,t,r,n){var a,i,o;let s=(a=t.rect,i=r,o=n,i>=a.x&&i<=a.x+a.width&&o>=a.y&&o<=a.y+a.height);if(s&&t.editText&&(e.editAtPoint=sv(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=sv(e.focusedEdit,t);return}s&&t.text&&(e.anyAtPoint=sv(e.anyAtPoint,t))}(o,e,t,r)}return{targetInput:i=(a=o).editAtPoint??a.anyAtPoint,actualInput:(a.focusedEdit?.text?a.focusedEdit:null)??i}}function sg(e){return(e??"").replace(/\s+/g," ").trim()}async function sy(e){try{return{activeInputMethodPackage:(await z(e)).inputMethodPackage}}catch(e){return eM({level:"warn",phase:"android_fill_verification_input_method_probe_failed",data:{error:e instanceof Error?e.message:String(e)}}),{}}}function sv(e,t){return e&&e.area<t.area?e:t}async function sI(e,t,r){await R(e,["shell","input","tap",String(t),String(r)])}async function sA(e,t,r,n,a,i=250){await R(e,["shell","input","swipe",String(t),String(r),String(n),String(a),String(i)])}async function sS(e){await R(e,["shell","input","keyevent","4"])}async function sb(e){await R(e,["shell","input","keyevent","3"])}async function s_(e,t){let r=function(e){switch(e){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new k("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await R(e,["shell","settings","put","system","accelerometer_rotation","0"]),await R(e,["shell","settings","put","system","user_rotation",r])}async function sN(e){await R(e,["shell","input","keyevent","187"])}async function sx(e,t,r,n=800){await R(e,["shell","input","swipe",String(t),String(r),String(t),String(r),String(n)])}async function sM(e,t,r=0){let n=e4(e);if(n){await n({action:"type",text:t,delayMs:r}),sU("type","provider-native",t);return}(s$(t),await sP(e,"type"),r>0&&Array.from(t).length>1)?await sR(e,{action:"type",text:t,chunkSize:1,delayMs:r}):await sR(e,{action:"type",text:t,chunkSize:sL,delayMs:0})}async function sD(e,t,r){await sI(e,t,r)}async function sk(e,t,r,n,a=0){let i=e4(e);if(i){await i({action:"fill",target:{x:t,y:r},text:n,delayMs:a}),sU("fill","provider-native",n);let o=await sf(e,t,r,n);if(o.ok)return;sE(n,o)}s$(n);let o=Array.from(n).length,s=null;for(let i of[{clearPadding:12,minClear:8,maxClear:48,chunkSize:a>0?1:sL,inputDelayMs:a},{clearPadding:24,minClear:16,maxClear:96,chunkSize:a>0?1:4,inputDelayMs:a>0?a:15}]){var l,u;await sD(e,t,r),await sP(e,"fill");let a=(l=o+i.clearPadding,u=i.minClear,Math.max(u,Math.min(i.maxClear,l)));await sG(e,a),await sR(e,{action:"fill",text:n,chunkSize:i.chunkSize,delayMs:i.inputDelayMs});let d=await sf(e,t,r,n);if(s=d,d.ok)return;"ime_capture"===d.reason&&sE(n,d)}sE(n,s)}function sE(e,t){let r;throw new k("COMMAND_FAILED",t?.reason==="ime_capture"?"Android fill input was captured by the active keyboard instead of the app field":t?.reason==="masked_unverified"?"Android fill verification could not confirm masked text value":"Android fill verification failed",(r=function(e,t){var r;if(!t)return{expected:e,actual:null,failureReason:"text_mismatch",targetInput:null,actualInput:null};let n=!0===(r=t).masked||o5(r.targetInput)||o5(r.actualInput),a={failureReason:t.reason??"text_mismatch",targetInput:o4(t.targetInput),actualInput:o4(t.actualInput)};return n?{...a,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??"").length}:{...a,expected:e,actual:t.actual}}(e,t),t?.reason==="ime_capture"&&(r.hint="The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill."),r))}async function sO(e,t,r){let n=await sC(e),a=o3({direction:t,amount:r?.amount,pixels:r?.pixels,referenceWidth:n.width,referenceHeight:n.height});return await R(e,["shell","input","swipe",String(a.x1),String(a.y1),String(a.x2),String(a.y2),"300"]),a}async function sP(e,t){let r;try{r=await z(e)}catch(e){eM({level:"warn",phase:"android_input_ownership_probe_failed",data:{action:t,error:e instanceof Error?e.message:String(e)}});return}if("ime"===r.inputOwner)throw new k("COMMAND_FAILED","KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.",{failureReason:"ime_capture",action:t,inputOwner:r.inputOwner,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,nextAction:"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry."})}async function sC(e){let t=(await R(e,["shell","wm","size"])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new k("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}let sL=8;async function sR(e,t){let r=t.text.split("\n");for(let[n,a]of r.entries()){let i=function(e,t){let r=Math.max(1,Math.floor(t)),n=[],a=Array.from(e);for(let e=0;e<a.length;e+=r)n.push(a.slice(e,e+r).join(""));return n.length>0?n:[""]}(a,t.chunkSize);for(let[a,o]of i.entries())await sT(e,o),t.delayMs>0&&(a+1<i.length||n+1<r.length)&&await ef(t.delayMs);n+1<r.length&&await R(e,["shell","input","keyevent","ENTER"])}sU(t.action,"adb-shell",t.text)}async function sT(e,t){if(t)try{await R(e,["shell","input","text",t.replace(/ /g,"%s")])}catch(e){if(function(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,r=("string"==typeof t?t:"").toLowerCase();return!!(r.includes("exception occurred while executing 'text'")||r.includes("nullpointerexception")&&r.includes("inputshellcommand.sendtext"))}(e))throw sF(t,e);throw e}}function s$(e){if(!function(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&"\n"!==t&&(e<32||e>126))return!1}return!0}(e))throw sF(e)}function sF(e,t){return new k("COMMAND_FAILED","Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.",{backend:"adb-shell",textLength:Array.from(e).length,textPreview:e.slice(0,32)},t instanceof Error?t:void 0)}function sU(e,t,r){eM({phase:"android_text_injection",data:{action:e,backend:t,textLength:Array.from(r).length}})}async function sG(e,t){let r=Math.max(0,t);await R(e,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let t=0;t<r;t+=24){let n=Math.min(24,r-t);await R(e,["shell","input","keyevent",...Array(n).fill("KEYCODE_DEL")],{allowFailure:!0})}}function sV(e){return e.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}let sj=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function sB(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new k("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function sq(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new k("INVALID_ARGS",`permission setting requires a target: ${sj.join("|")}`)}function sH(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new k("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function sW(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new k("INVALID_ARGS",`Invalid setting state: ${e}`)}let sz=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function sK(e,t,r,n,a){switch(t.toLowerCase()){case"wifi":{let t=sW(r);await R(e,["shell","svc","wifi",t?"enable":"disable"]);return}case"airplane":{let t=sW(r);await R(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"]),await R(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]);return}case"location":{if("set"===r.toLowerCase()){if("emulator"!==e.kind)throw new k("UNSUPPORTED_OPERATION","Android precise location coordinates are supported only on emulators.",{deviceId:e.id,hint:"Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling."});let{latitude:t,longitude:r}=eB(a);return await R(e,["emu","geo","fix",String(r),String(t)]),{latitude:t,longitude:r}}let t=sW(r);await R(e,["shell","settings","put","secure","location_mode",t?"3":"0"]);return}case"animations":{let t=sW(r)?"1":"0";for(let r of sz)await R(e,["shell","settings","put","global",r,t]);return{scale:t,keys:[...sz]}}case"appearance":{let t=await sX(e,r);await R(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]);return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new k("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await sJ(e,t);return}case"permission":{if(!n)throw new k("INVALID_ARGS","permission setting requires an active app in session");let t=sB(r),i=function(e,t){let r=sq(e);if(t?.trim())throw new k("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===r)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===r)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===r)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===r)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new k("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(a?.permissionTarget,a?.permissionMode);if("notifications"===i.kind)return void await sZ(e,n,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await sY(e,n,o);await R(e,["shell","pm",o,n,i.value]);return}default:throw new k("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function sJ(e,t){var r;let n,a,i=(r=e,a=[["shell","cmd","fingerprint","touch",n="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",n]],"emulator"===r.kind&&a.push(["emu","finger","touch",n]),a),o=[];for(let t of i){let r=await R(e,t,{allowFailure:!0});if(0===r.exitCode)return;o.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let s=sV(o);if(o.length>0&&o.every(e=>{var t,r;let n;return t=e.stdout,r=e.stderr,(n=`${t}
17
+ ${r}`.toLowerCase()).includes("unknown command")||n.includes("can't find service: fingerprint")||n.includes("service fingerprint was not found")||n.includes("fingerprint cmd unavailable")||n.includes("emu command is not supported")||n.includes("emulator console is not running")||n.includes("fingerprint")&&n.includes("not found")}))throw new k("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new k("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}async function sX(e,t){let r=sH(t);if("toggle"!==r)return r;let n=await R(e,["shell","cmd","uimode","night"],{allowFailure:!0});if(0!==n.exitCode)throw new k("COMMAND_FAILED","Failed to read current Android appearance",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let a=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
18
+ ${t}`);if(!r)return null;let n=r[1].toLowerCase();return"yes"===n?"dark":"no"===n?"light":"auto"===n?"auto":null}(n.stdout,n.stderr);if(!a)throw new k("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:n.stdout,stderr:n.stderr});return"auto"===a?"dark":"dark"===a?"light":"dark"}async function sY(e,t,r){let n=await sQ(e),a=[];for(let i of null!==n&&n>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let n=await R(e,["shell","pm",r,t,i],{allowFailure:!0});if(0===n.exitCode)return;a.push({permission:i,stderr:n.stderr,exitCode:n.exitCode})}throw new k("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:n,attempts:a})}async function sZ(e,t,r,n){"grant"===r?await R(e,["shell","pm","grant",t,n.permission],{allowFailure:!0}):(await R(e,["shell","pm","revoke",t,n.permission],{allowFailure:!0}),"reset"===r&&(await R(e,["shell","pm","clear-permission-flags",t,n.permission,"user-set"],{allowFailure:!0}),await R(e,["shell","pm","clear-permission-flags",t,n.permission,"user-fixed"],{allowFailure:!0}))),await R(e,["shell","appops","set",t,n.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"])}async function sQ(e){let t=await R(e,["shell","getprop","ro.build.version.sdk"],{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}let s0=Buffer.from([137,80,78,71,13,10,26,10]);async function s1(e,t,r={}){if(!1===r.stabilize)return void await s5(e,t);await s2(e);try{await ef(1e3),await s5(e,t)}finally{await s3(e).catch(()=>{})}}async function s2(e){let t=t=>R(e,["shell",t],{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let r=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await r("clock -e hhmm 0941"),await r("notifications -e visible false")}async function s3(e){await R(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"],{allowFailure:!0})}async function s5(e,t){let r=await R(e,["exec-out","screencap","-p"],{binaryStdout:!0});if(!r.stdoutBuffer)throw new k("COMMAND_FAILED","Failed to capture screenshot");let n=r.stdoutBuffer.indexOf(s0);if(n<0)throw new k("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let a=function(e,t){let r=t+s0.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),n=r+4,a=e.toString("ascii",n,n+4),i=r+12+t;if(i>e.length)break;if("IEND"===a)return i;r=i}return null}(r.stdoutBuffer,n);if(!a)throw new k("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await u.writeFile(t,r.stdoutBuffer.subarray(n,a))}function s4(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let r=String(t.stderr??"").toLowerCase();return r.includes("fbsopenapplicationserviceerrordomain")&&r.includes("the request to open")}async function s8(e,t){let r=await rm(ry(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==r.exitCode)return{installed:!1};let n=r.stdout.trim();if(!n)return{installed:!1};let a=await rf("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${n}/Info.plist`],{allowFailure:!0});if(0!==a.exitCode||!a.stdout.trim())return{installed:!0};let i=a.stdout.trim(),o=`${n}/${i}`,s=await rf("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function s6(e,t){if("simulator"!==e.kind)throw new k("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function s9(){await rf("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:oU})}async function s7(e){let t,r;if("simulator"!==e.kind||"Booted"===await lt(e))return;let n=ep.fromTimeoutMs(oR);try{await eu(async({deadline:n})=>{if(n?.isExpired())throw new k("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:oR});let a=Math.max(1e3,n?.remainingMs()??oR),i=await rm(ry(e,["boot",e.id]),{allowFailure:!0,timeoutMs:a});t={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let o=`${t.stdout}
19
+ ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new k("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await rm(ry(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:a});if(r={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==r.exitCode)throw new k("COMMAND_FAILED","simctl bootstatus failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let u=await lt(e);if("Booted"!==u)throw new k("COMMAND_FAILED","Simulator is still booting",{state:u})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let n=G({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==n&&"CI_RESOURCE_STARVATION_SUSPECTED"!==n}},{deadline:n,phase:"boot",classifyReason:e=>G({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let a=G({error:i,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new k("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:oR,elapsedMs:n.elapsedMs(),reason:a,hint:W(a),boot:t,bootstatus:r})}await s9()}async function le(e){let t=ry(e,["shutdown",e.id]),r=await rm(t,{allowFailure:!0,timeoutMs:15e3});return{success:0===r.exitCode,exitCode:r.exitCode,stdout:String(r.stdout??""),stderr:String(r.stderr??"")}}async function lt(e){let t="string"==typeof e?e:e.id,r="string"==typeof e?rg(["list","devices","-j"]):ry(e,["list","devices","-j"]),n=await rm(r,{allowFailure:!0,timeoutMs:oT});if(0!==n.exitCode)return null;try{let e=JSON.parse(String(n.stdout??""));for(let r of Object.values(e.devices??{})){let e=r.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function lr(e,t){try{let r=await rh(e),n=r?.[t];if("string"==typeof n&&n.length>0)return n}catch{}try{let r=await rf("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===r.exitCode){let e=String(r.stdout??"").trim();if(e.length>0)return e}}catch{}try{var r,n;let a;return r=await u.readFile(e,"utf8"),n=t,r4(r5(r),(e,t)=>{void 0===a&&e===n&&"string"===t.name&&(a=t.text??void 0)}),a}catch{return}}async function ln(e,t){let r;if("url"===e.kind&&!tC(e.url))throw new k("INVALID_ARGS","iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.");let n=await tP({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||tC(e.url),signal:t?.signal});try{let e=r=await li(n.installablePath,t),a=await la(e.installPath);return{archivePath:n.archivePath??(n.installablePath.toLowerCase().endsWith(".ipa")?n.installablePath:void 0),installablePath:e.installPath,bundleId:a.bundleId,appName:a.appName,cleanup:async()=>{await e.cleanup(),await n.cleanup()}}}catch(e){try{await r?.cleanup()}finally{await n.cleanup()}throw e}}async function la(e){let t=p.join(e,"Info.plist"),[r,n,a]=await Promise.all([lr(t,"CFBundleIdentifier"),lr(t,"CFBundleDisplayName"),lr(t,"CFBundleName")]);return{bundleId:r,appName:n??a}}async function li(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let r=await u.mkdtemp(p.join(d.tmpdir(),"agent-device-ios-ipa-")),n=async()=>{await u.rm(r,{recursive:!0,force:!0})};try{await P("unzip",["-q",e,"-d",r]);let a=p.join(r,"Payload"),i=(await u.readdir(a,{withFileTypes:!0}).catch(()=>{throw new k("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:p.join(a,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===i.length)return{installPath:i[0].installPath,cleanup:n};if(0===i.length)throw new k("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await lo(i);let o=t?.appIdentifierHint?.trim();if(o){let e=function(e,t){let r=t.toLowerCase(),n=e.filter(e=>e.bundleName.toLowerCase()===r);if(1===n.length)return n[0];if(n.length>1)throw new k("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===r);if(1===t.length)return t[0]}}(i,o);if(e)return{installPath:e.installPath,cleanup:n};throw new k("INVALID_ARGS",`Invalid IPA: found ${i.length} .app bundles under Payload and none matched "${o}". Available bundles: ${i.map(ls).join(", ")}`)}throw new k("INVALID_ARGS",`Invalid IPA: found ${i.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${i.map(ls).join(", ")}`)}catch(e){throw await n(),e}}async function lo(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await la(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function ls(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}let ll="agent-device-macos-helper",lu="AGENT_DEVICE_MACOS_HELPER_BIN",ld=p.join(d.homedir(),".agent-device","macos-helper","current"),lc=p.join(ld,"manifest.json"),lp=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function lf(e){let t=e.trim();if(!lp.test(t))throw new k("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function lm(e,t){t.bundleId&&e.push("--bundle-id",lf(t.bundleId)),t.surface&&e.push("--surface",t.surface)}function lh(){return function(e){let t=p.dirname(e);for(;;){let e=p.join(t,"macos-helper");if(l(p.join(e,"Package.swift")))return e;let r=p.dirname(t);if(r===t)break;t=r}throw new k("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(g(import.meta.url))}async function lw(e){let t=await u.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let r=p.join(e,t.name);return t.isDirectory()?".build"===t.name?[]:await lw(r):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[r]:[]}))).flat().sort()}async function lg(e){let t=await lw(e),r=o("sha256");for(let n of t)r.update(p.relative(e,n)),r.update("\0"),r.update(await u.readFile(n)),r.update("\0");let n=await rf("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return r.update("swift-version"),r.update("\0"),r.update(n.stdout||n.stderr||`exit:${n.exitCode}`),r.update("\0"),r.digest("hex")}async function ly(){try{let e=JSON.parse(await u.readFile(lc,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function lv(){let e=await L(process.env[lu],lu);if(e)return e;let t=lh(),r=await lg(t),n=p.join(ld,ll);try{if(await ly()===r)return await u.access(n),n}catch{}let a=p.join(lh(),".build","release",ll);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await rf("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await u.mkdir(ld,{recursive:!0});let i=`${n}.tmp`;return await u.copyFile(a,i),await u.rename(i,n),await u.chmod(n,493),await u.writeFile(lc,`${JSON.stringify({fingerprint:r},null,2)}
20
+ `,"utf8"),n}async function lI(){let e=process.env[lu]?.trim();if(e){let t=await L(e,lu);if(t)return t}if(ru.hasScope())return ll;if("darwin"!==process.platform)throw new k("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");return await lv()}async function lA(e){let t={allowFailure:!0,timeoutMs:3e4},r=rc().macosHelper,n=r?ll:await lI(),a=r?await r.run(e,t):await rf(n,e,t),i=a.stdout.trim(),o=null;if(i)try{o=JSON.parse(i)}catch{o=null}if(0===a.exitCode&&o?.ok)return o.data;throw new k("COMMAND_FAILED",o&&!o.ok?o.error?.message??`macOS helper exited with code ${a.exitCode}`:i||a.stderr.trim()||`macOS helper exited with code ${a.exitCode}`,{helperPath:n,args:e,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,...o&&!o.ok?o.error?.details:{}})}async function lS(){return await lA(["app","frontmost"])}async function lb(e){return await lA(["app","quit","--bundle-id",lf(e)])}async function l_(e,t){return await lA(["permission",e,t])}async function lN(e,t={}){let r=["alert",e];return lm(r,t),await lA(r)}async function lx(e,t={}){let r=["snapshot","--surface",e];return lm(r,t),await lA(r)}async function lM(e,t,r={}){let n=["read","--x",String(e),"--y",String(t)];return lm(n,r),await lA(n)}async function lD(e,t,r={}){let n=["press","--x",String(e),"--y",String(t)];return lm(n,r),await lA(n)}async function lk(e,t={}){let r=["screenshot","--out",e];return lm(r,t),t.fullscreen&&r.push("--fullscreen"),await lA(r)}let lE={settings:"com.apple.systempreferences"},lO=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,lP={platform:"macos",deviceId:"host",variant:"all"},lC=en();async function lL(e){let t=e.trim(),r=lE[t.toLowerCase()];if(r)return r;if(lO.test(t))return t;let n=lC.get(lP,t);if(n)return n;let a=(await lV("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===a.length)return lC.set(lP,t,a[0].bundleId);if(a.length>1)throw new k("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:a});throw new k("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function lR(e,t,r){let n=r?.url?.trim();if(n){if(!ea(n))throw new k("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=r?.appBundleId??await lL(t);await lj().openBundle(e,n);return}let a=t.trim();if(ea(a))return void await lj().openTarget(a);let i=r?.appBundleId??await lL(a);await lj().openBundle(i)}async function lT(e,t){let r=await lL(t),n=await lb(r);if(n.running&&!n.terminated&&!n.forceTerminated)throw new k("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:r,running:n.running,terminated:n.terminated,forceTerminated:n.forceTerminated})}async function l$(){return await lj().readClipboard()}async function lF(e){await lj().writeClipboard(e)}async function lU(){return await lj().readDarkMode()}async function lG(e){let t=sH(e),r="toggle"===t?!await lU():"dark"===t;await lj().setDarkMode(r)}async function lV(e){return await lj().listApps(e)}function lj(){let e=rc().macosHost;if(!e)throw new k("UNSUPPORTED_OPERATION","macOS host provider is not available");return e}function lB(e){if(!(e instanceof k))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:r}}let lq=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],lH={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},lW={1:"searching",2:"failed",3:"active"},lz={0:"notSupported",1:"searching",2:"failed",3:"active"};function lK(e,t,r){return rm(ry(e,t),r)}async function lJ(e,t){var r,n;let a;await lY(e),t&&await lZ(e,(a=[],(r=t).dataNetwork&&a.push("--dataNetwork",r.dataNetwork),r.wifiMode&&a.push("--wifiMode",r.wifiMode),void 0!==r.wifiBars&&("wifi"===r.dataNetwork||r.wifiMode)&&a.push("--wifiBars",r.wifiBars),r.cellularMode&&a.push("--cellularMode",r.cellularMode),void 0!==r.cellularBars&&(r.cellularMode||(n=r.dataNetwork)&&"hide"!==n&&"wifi"!==n||void 0!==r.operatorName)&&a.push("--cellularBars",r.cellularBars),void 0!==r.operatorName&&a.push("--operatorName",r.operatorName),a))}async function lX(e){let t=await lK(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new k("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let r of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(r);if(e){let r=Number(e[1]),n=lH[r];if(!n)throw new k("COMMAND_FAILED",`Unsupported simulator data network type: ${r}`);t.dataNetwork=n;continue}let n=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(r);if(n){let e=lW[Number(n[1])];e&&(t.wifiMode=e),t.wifiBars=n[2];continue}let a=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(r);if(a){let e=Number(a[1]),r=lz[e];if(!r)throw new k("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=r,t.cellularBars=a[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(r);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function lY(e){await lK(e,["status_bar",e.id,"clear"])}async function lZ(e,t){0!==t.length&&await lK(e,["status_bar",e.id,"override",...t])}function lQ(e,t,r){eM({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...lB(r)}})}function l0(e,t,r){return rm(ry(e,t),r)}let l1={ensureBooted:s7,prepareStatusBarForScreenshot:async function e(e){let t=null,r=!1;try{t=await lX(e),r=!0}catch(t){lQ(e,"snapshot_failed",t)}try{await lY(e),await lZ(e,lq)}catch(t){lQ(e,"prepare_failed",t)}return async()=>{await lJ(e,r?t:null)}},captureWithRetry:l5,runnerFallbackEnabled:oj,captureWithRunner:l4,shouldFallbackToRunner:ut};async function l2(e,t,r,n,a){if("macos"===e.platform)return void await l4(e,t,r,n,a);if("simulator"===e.kind)return void await l3(e,t,r,n,void 0,a);try{await oB(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",n="string"==typeof t.stderr?t.stderr:"",a=`${e.message}
21
+ ${r}
22
+ ${n}`.toLowerCase();return a.includes("unknown option '--device'")||a.includes("unknown subcommand")&&a.includes("screenshot")||a.includes("unrecognized subcommand")&&a.includes("screenshot")}(t))throw t;l7(e,"devicectl_screenshot",t)}await l4(e,t,r,n,a)}async function l3(e,t,r,n,a=l1,i){if("simulator"!==e.kind)throw new k("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let o="object"==typeof n&&null!==n?n:a;await o.ensureBooted(e);let s=async()=>{};try{s=await o.prepareStatusBarForScreenshot(e)}catch(t){ue(e,"prepare_failed",t)}try{try{await o.captureWithRetry(e,t);return}catch(t){if(!o.shouldFallbackToRunner(t))throw t;if(!o.runnerFallbackEnabled){var l,u,d;let r,n;throw l=e,u=t,r=lB(u),eM({level:"warn",phase:"ios_screenshot_fallback_skipped",data:{platform:l.platform,deviceKind:l.kind,deviceId:l.id,from:"simctl_screenshot",to:"runner",reason:"Simulator runner fallback is disabled to avoid XCTest automation instability during screenshot capture.",...r}}),n=(d=t)instanceof k?d:new k("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,d),new k(n.code,n.message,{...n.details??{},hint:"Restart the simulator and retry. If simctl screenshots keep timing out and you accept the stability tradeoff, set AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK=1 to allow XCTest runner fallback."},n)}l7(e,"simctl_screenshot",t)}await o.captureWithRunner(e,t,r,"boolean"==typeof n?n:void 0,i)}finally{await s().catch(t=>ue(e,"restore_failed",t))}}async function l5(e,t){let r=ep.fromTimeoutMs(oG);await eu(async({deadline:r})=>{await l0(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,r?.remainingMs()??oG)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>ut(e)},{deadline:r,phase:"ios_simulator_screenshot"})}async function l4(e,t,r,n,a){let i=(await at(e,{command:"screenshot",appBundleId:r,fullscreen:n},a)).message;if(!i)throw new k("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await u.copyFile(i,t):"simulator"===e.kind?await l6(e,i,t):await l8(e,i,t)}async function l8(e,t,r){let n=ep.fromTimeoutMs(oV),a={exitCode:1,stdout:"",stderr:""};for(let i of np)if(0===(a=await rm(["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",r,"--domain-type","appDataContainer","--domain-identifier",i],{allowFailure:!0,timeoutMs:l9(n,oV,"runner screenshot copy")})).exitCode)return;let i=a.stderr.trim()||a.stdout.trim()||`devicectl exited with code ${a.exitCode}`;throw new k("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}async function l6(e,t,r){let n=ep.fromTimeoutMs(oV),a="Unable to locate runner container for simulator screenshot";for(let i of np){let o=await l0(e,["get_app_container",e.id,i,"data"],{allowFailure:!0,timeoutMs:l9(n,oV,"runner screenshot container lookup")});if(0!==o.exitCode){let e=o.stderr.trim();e&&(a=e);continue}let s=o.stdout.trim();if(!s){a="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let r=p.resolve(e),n=t.trim();if(!n)return[];let a=[],i=new Set,o=e=>{let t=p.normalize(e);i.has(t)||(i.add(t),a.push(t))},s=n.replace(/^\/+/,""),l=s.replace(/\\/g,"/");if(s&&o(p.join(r,s)),p.isAbsolute(n)&&o(p.normalize(n)),l.startsWith("tmp/"))o(p.join(r,l));else{let e=l.lastIndexOf("/tmp/");if(e>=0){let t=l.slice(e+1);o(p.join(r,t))}}let u=p.basename(n);return u&&o(p.join(r,"tmp",u)),a}(s,t))try{await u.copyFile(e,r);return}catch(e){a=e instanceof Error?e.message:String(e)}}throw new k("COMMAND_FAILED",`Failed to capture iOS screenshot: ${a}`)}function l9(e,t,r){let n=e.remainingMs();if(n>0)return n;throw new k("COMMAND_FAILED",`iOS ${r} timed out after ${t}ms`,{timeoutMs:t,step:r})}function l7(e,t,r){let n=lB(r);eM({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...n}})}function ue(e,t,r){eM({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...lB(r)}})}function ut(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",n="string"==typeof t.stderr?t.stderr:"",a=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",i=`${e.message}
23
+ ${r}
24
+ ${n}
25
+ ${a}`.toLowerCase();return i.includes("timeout waiting for screen surfaces")||i.includes("nsposixerrordomain")&&i.includes("code=60")&&i.includes("screenshot")||i.includes("timed out")&&i.includes("screenshot")}let ur={settings:"com.apple.Preferences"},un=en(),ua=null;function ui(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function uo(e,t,r){return rm(ry(e,t),r)}function us(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function ul(e,t){if("macos"===e.platform)return await lL(t);let r=t.trim();if(r.includes("."))return r;let n=ur[r.toLowerCase()];if(n)return n;let a=ui(e),i=un.get(a,r);if(i)return i;let o=("simulator"===e.kind?await uA(e):await oq(e,"all")).filter(e=>e.name.toLowerCase()===r.toLowerCase());if(1===o.length)return un.set(a,r,o[0].bundleId);if(o.length>1)throw new k("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:o});throw new k("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function uu(e,t,r){if("macos"===e.platform)return void await lR(e,t,r);let n=r?.url?.trim();if(n){if(!ea(n))throw new k("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await s7(e),await uo(e,["openurl",e.id,n]);return}let a=F(r?.appBundleId??await ul(e,t),n);if(!a)throw new k("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await uk(e,a,{payloadUrl:n});return}let a=t.trim();if(ea(a)){if("simulator"===e.kind){await s7(e),await uo(e,["openurl",e.id,a]);return}let t=F(r?.appBundleId,a);if(!t)throw new k("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await uk(e,t,{payloadUrl:a});return}let i=r?.appBundleId??await ul(e,t);"simulator"===e.kind?await uD(e,i):await uk(e,i)}async function ud(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await lt(e)&&await s7(e)}async function uc(e,t){if("macos"===e.platform)return void await lT(e,t);let r=await ul(e,t);if("simulator"===e.kind){await s7(e);let t=ry(e,["terminate",e.id,r]),n=await rm(t,{allowFailure:!0});if(0!==n.exitCode){if(n.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new k("COMMAND_FAILED",`xcrun exited with code ${n.exitCode}`,{cmd:"xcrun",args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}return}await oB(["device","process","terminate","--device",e.id,r],{action:"terminate iOS app",deviceId:e.id})}async function up(e,t){return await un.invalidateWhile(ui(e),async()=>{let r=await ul(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,r],n=await rm(t,{allowFailure:!0,timeoutMs:oF});if(0!==n.exitCode){let a=String(n.stdout??""),i=String(n.stderr??"");if(!us(`${a}
26
+ ${i}`.toLowerCase()))throw new k("COMMAND_FAILED",`Failed to uninstall iOS app ${r}`,{cmd:"xcrun",args:t,exitCode:n.exitCode,stdout:a,stderr:i,deviceId:e.id,hint:oK(a,i)??oz})}return{bundleId:r}}await s7(e);let n=await uo(e,["uninstall",e.id,r],{allowFailure:!0});if(0!==n.exitCode&&!us(`${n.stdout}
27
+ ${n.stderr}`.toLowerCase()))throw new k("COMMAND_FAILED",`simctl uninstall failed for ${r}`,{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});return{bundleId:r}})}async function uf(e,t,r){let n=await ln({kind:"path",path:t},r);try{return await uh(e,n.installablePath),{archivePath:n.archivePath,installablePath:n.installablePath,bundleId:n.bundleId,appName:n.appName,launchTarget:n.bundleId}}finally{await n.cleanup()}}async function um(e,t,r){return await un.invalidateWhile(ui(e),async()=>{let{bundleId:n}=await up(e,t);return await uf(e,r,{appIdentifierHint:t}),{bundleId:n}})}async function uh(e,t){await un.invalidateWhile(ui(e),async()=>{"simulator"!==e.kind?await oB(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await s7(e),await uo(e,["install",e.id,t]))})}async function uw(e){if("macos"===e.platform)return await l$();s6(e,"clipboard"),await s7(e);let t=await uo(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new k("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function ug(e,t){if("macos"===e.platform)return void await lF(t);s6(e,"clipboard"),await s7(e);let r=await uo(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==r.exitCode)throw new k("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function uy(e,t,r){s6(e,"push"),await s7(e);let n=await u.mkdtemp(p.join(d.tmpdir(),"agent-device-ios-push-")),a=p.join(n,"payload.apns");try{await u.writeFile(a,`${JSON.stringify(r)}
28
+ `,"utf8"),await uo(e,["push",e.id,t,a])}finally{await u.rm(n,{recursive:!0,force:!0})}}async function uv(e,t,r,n,a){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await lG(r);if("permission"===e){let e=sB(r);if("deny"===e)throw new k("INVALID_ARGS",tv("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new k("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(a?.permissionTarget);return await l_(e,t)}throw new k("INVALID_ARGS",tv(t))}s6(e,"settings"),await s7(e);let i=t.toLowerCase();switch(i){case"wifi":{let t=sW(r);await uo(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(sW(r)?await uo(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await uo(e,["status_bar",e.id,"clear"]));case"location":{if("set"===r.toLowerCase()){let{latitude:t,longitude:r}=eB(a);return await uo(e,["location",e.id,"set",`${t},${r}`]),{latitude:t,longitude:r}}let t=sW(r);if(!n)throw new k("INVALID_ARGS","location setting requires an active app in session");await uo(e,["privacy",e.id,t?"grant":"revoke","location",n]);return}case"faceid":case"touchid":{let t=ub[i],n=function(e,t){let r=e.trim().toLowerCase();if("match"===r)return"match";if("nonmatch"===r)return"nonmatch";if("enroll"===r)return"enroll";if("unenroll"===r)return"unenroll";throw new k("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(r,i);await uM(e,n,{settingName:i,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await uS(e,r);await uo(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!n)throw new k("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=sB(r))?"revoke":o,i=function(e,t){let r=sq(e);if("photos"!==r&&t?.trim())throw new k("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return"camera";if("microphone"===r)return"microphone";if("contacts"===r)return"contacts";if("contacts-limited"===r)return"contacts-limited";if("notifications"===r)return"notifications";if("calendar"===r)return"calendar";if("location"===r)return"location";if("location-always"===r)return"location-always";if("media-library"===r)return"media-library";if("motion"===r)return"motion";if("reminders"===r)return"reminders";if("siri"===r)return"siri";if("photos"===r){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new k("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new k("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(a?.permissionTarget,a?.permissionMode);await u_(e,t,i,n);return}default:throw new k("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function uI(e,t){return"macos"===e.platform?await lV(t):"simulator"===e.kind?rn(await uA(e),t):await oq(e,t)}async function uA(e){let t=(await uo(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let r=null;if(t.startsWith("{"))try{r=JSON.parse(t)}catch{r=null}if(!r&&t.startsWith("{"))try{let e=await rf("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>({bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e})):[]}async function uS(e,t){let r=sH(t);if("toggle"!==r)return r;let n=await uo(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==n.exitCode)throw new k("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let a=function(e,t){let r=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
29
+ ${t}`);if(!r)return null;let n=r[1].toLowerCase();return"dark"===n?"dark":"light"===n?"light":null}(n.stdout,n.stderr);if(!a)throw new k("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:n.stdout,stderr:n.stderr});return"dark"===a?"light":"dark"}let ub={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function u_(e,t,r,n){let a=await ux(e);if(!a.has(r))throw new k("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:n,hint:`Supported services: ${Array.from(a).sort().join(", ")}`});let i=["privacy",e.id,t,r,n],o="notifications"===r;if(!("reset"===t&&o))try{await uo(e,i);return}catch(t){if(!(o&&uN(t)))throw t;throw new k("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:n,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await uo(e,i);return}catch(e){if(!uN(e))throw e}try{await uo(e,["privacy",e.id,"reset","all",n])}catch(t){throw new k("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:n,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function uN(e){if(!(e instanceof k)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function ux(t){let r=T(t.simulatorSetPath),n=`${process.env.PATH??""}::${r??""}`;if(ua&&e===n)return ua;let a=await uo(t,["privacy","help"],{allowFailure:!0}),i=function(e){let t=new Set,r=!1;for(let n of e.split("\n")){let e=n.trim();if(!e)continue;if("service"===e){r=!0;continue}if(!r)continue;if(e.startsWith("bundle identifier"))break;let a=/^([a-z-]+)\s+-\s+/.exec(e);a&&t.add(a[1])}return t}(`${a.stdout}
30
+ ${a.stderr}`);if(0===i.size)throw new k("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return ua=i,e=n,i}async function uM(e,t,r){let n=function(e,t,r){let n=r.length>0?r:["face"];switch(t){case"match":return n.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return n.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,r.modalityAliases),a=[];for(let t of n){let r=ry(e,t),n=await rm(r,{allowFailure:!0});if(0===n.exitCode)return;a.push({args:r,stderr:n.stderr,stdout:n.stdout,exitCode:n.exitCode})}let i=sV(a);if(a.length>0&&a.every(e=>{var t,r;let n;return t=e.stdout,r=e.stderr,(n=`${t}
31
+ ${r}`.toLowerCase()).includes("unrecognized subcommand")||n.includes("unknown subcommand")||n.includes("not supported")||n.includes("unavailable")||n.includes("biometric")&&n.includes("invalid")}))throw new k("UNSUPPORTED_OPERATION",`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:i});throw new k("COMMAND_FAILED",`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:i})}async function uD(e,t){await s7(e);let r=0,n=ep.fromTimeoutMs(o$);try{await eu(async({deadline:r})=>{var n;if(r?.isExpired())throw new k("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:o$});let a=(n=["launch",e.id,t],ry(e,n)),i=await rm(a,{allowFailure:!0});if(0!==i.exitCode)throw new k("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:a,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!s4(e)&&(r+=1)<3},{deadline:n})}catch(r){if(s4(r)){var a;let n=(a=await s8(e,t)).installed?!1===a.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";r.details={...r.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(n)}}throw r}}async function uk(e,t,r){let n=["device","process","launch","--device",e.id,t];r?.payloadUrl&&n.push("--payload-url",r.payloadUrl),await oB(n,{action:"launch iOS app",deviceId:e.id})}function uE(e,t,r){return{command:"remotePress",remoteButton:e,...void 0!==r?{durationMs:r}:{},...void 0!==t?{appBundleId:t}:{}}}async function uO(e,t,r,n,a,i,o){if("tv"===t.target)return uL(await e(t,uE(a,r.appBundleId),n),i);let s=o??await uP(e,t,r,n),l=o3({direction:a,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return uL(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:r.appBundleId},n),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function uP(e,t,r,n){let a=await e(t,{command:"interactionFrame",appBundleId:r.appBundleId},n),i=uC(a.x),o=uC(a.y),s=uC(a.referenceWidth),l=uC(a.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new k("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function uC(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function uL(e,t){var r;let{x1:n,y1:a,x2:i,y2:o}={x1:uC((r=e).x),y1:uC(r.y),x2:uC(r.x2),y2:uC(r.y2)},s=uC(e.referenceWidth),l=uC(e.referenceHeight),u=void 0!==n&&void 0!==i?Math.round(Math.abs(i-n)):void 0,d=void 0!==a&&void 0!==o?Math.round(Math.abs(o-a)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:u&&u>0?u:d&&d>0?d:void 0;return{...void 0!==n?{x1:n}:{},...void 0!==a?{y1:a}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}let uR=null;async function uT(){let e=ob();if(uR?.provider===e)return uR;let t=process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11";if("wayland"===t){if(await e.whichCommand("ydotool"))return uR={tool:"ydotool",display:t,provider:e};throw new k("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await e.whichCommand("xdotool"))return uR={tool:"xdotool",display:t,provider:e};throw new k("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function u$(...e){await ob().runCommand("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function uF(...e){await ob().runCommand("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}function uU(){return ob().input}async function uG(e,t){let{tool:r}=await uT();"xdotool"===r?await u$("mousemove","--sync",String(e),String(t)):await uF("mousemove","--absolute","-x",String(e),"-y",String(t))}async function uV(e,t){let r=uU();if(r)return void await r.key(e,t);let{tool:n}=await uT();"xdotool"===n?await u$("key","--clearmodifiers",e):await uF("key",...t)}async function uj(e,t,r,n){await uG(e,t);let{tool:a}=await uT();"xdotool"===a?await u$("click",r):await uF("click",n)}async function uB(e,t,r,n,a){let i=uU();i?await i.click(e,t,r):await uj(e,t,n,a)}async function uq(e,t){await uB(e,t,"primary","1","0xC0")}async function uH(e,t){await uB(e,t,"secondary","3","0xC1")}async function uW(e,t){await uB(e,t,"middle","2","0xC2")}async function uz(e,t){let r=uU();if(r)return void await r.doubleClick(e,t);let{tool:n}=await uT();await uG(e,t),"xdotool"===n?await u$("click","--repeat","2","1"):(await uF("click","0xC0"),await uF("click","0xC0"))}async function uK(e,t,r=800){let n=uU();if(n)return void await n.longPress(e,t,r);let{tool:a}=await uT();await uG(e,t),"xdotool"===a?(await u$("mousedown","1"),await ef(r),await u$("mouseup","1")):(await uF("click","--down","0xC0"),await ef(r),await uF("click","--up","0xC0"))}async function uJ(e,t){await uq(e,t)}async function uX(e,t,r,n,a=300){let i=uU();if(i)return void await i.drag(e,t,r,n,a);let{tool:o}=await uT();await uG(e,t),"xdotool"===o?(await u$("mousedown","1"),await u$("mousemove","--sync",String(r),String(n)),await ef(a),await u$("mouseup","1")):(await uF("click","--down","0xC0"),await uF("mousemove","--absolute","-x",String(r),"-y",String(n)),await ef(a),await uF("click","--up","0xC0"))}async function uY(e,t){let r=uU();if(r)return void await r.scroll(e,t);let{tool:n}=await uT(),a=5;if(t?.pixels!=null?a="xdotool"===n?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===n)await u$("click","--repeat",String(a),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-a):String(a);await uF("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await uF("mousemove","--wheel","-x",t)}}async function uZ(e,t=0){let r=uU();if(r)return void await r.typeText(e,{delayMs:t});let{tool:n}=await uT();if("xdotool"===n){let r=["type"];t>0&&r.push("--delay",String(t)),r.push("--clearmodifiers","--",e),await u$(...r)}else await uF("type","--",e)}async function uQ(e,t,r,n=0){await uq(e,t),await ef(100),await uV("ctrl+a",["29:1","30:1","30:0","29:0"]),await ef(50),await uZ(r,n)}async function u0(e){await ob().desktop.openTarget(e)}async function u1(e){await ob().desktop.closeApp(e)}async function u2(){await uV("alt+Left",["56:1","105:1","105:0","56:0"])}async function u3(){await uV("super+d",["125:1","32:1","32:0","125:0"])}async function u5(){return await ob().clipboard.readText()}async function u4(e){await ob().clipboard.writeText(e)}async function u8(e,t){await ob().screenshot.capture(e,t)}let u6={"push button":"Button","toggle button":"Button","push button menu":"Button",label:"StaticText",static:"StaticText",caption:"StaticText",text:"TextField",entry:"TextField","password text":"TextField","spin button":"TextField",terminal:"TextArea","document text":"TextArea",paragraph:"TextArea",frame:"Window",window:"Window",dialog:"Dialog",alert:"Alert","file chooser":"Dialog","color chooser":"Dialog","font chooser":"Dialog",panel:"Group",filler:"Group",section:"Group",form:"Group",grouping:"Group","layered pane":"Group","glass pane":"Group","root pane":"Group","option pane":"Group","internal frame":"Group","desktop frame":"Group","block quote":"Group",article:"Group",comment:"Group",landmark:"Group",log:"Group",marquee:"Group",math:"Group",notification:"Group","content deletion":"Group","content insertion":"Group",mark:"Group",suggestion:"Group","scroll pane":"ScrollArea","scroll bar":"ScrollBar","menu bar":"MenuBar",menu:"Menu","popup menu":"Menu","menu item":"MenuItem","check menu item":"MenuItem","radio menu item":"MenuItem","tearoff menu item":"MenuItem","check box":"CheckBox","radio button":"RadioButton",switch:"Switch","combo box":"ComboBox","page tab":"Tab","page tab list":"TabList",table:"Table","tree table":"Table","table cell":"Cell","table row":"Row","table column header":"Cell","table row header":"Cell","column header":"Cell","row header":"Cell",list:"List","list item":"ListItem","list box":"List",tree:"Tree","tree item":"TreeItem","description list":"List","description term":"ListItem","description value":"ListItem","tool bar":"Toolbar","status bar":"StatusBar","info bar":"StatusBar",slider:"Slider","progress bar":"ProgressBar","level bar":"ProgressBar",image:"Image",icon:"Image",animation:"Image",canvas:"Image","drawing area":"Image",video:"Video",audio:"Audio",link:"Link",hyperlink:"Link",separator:"Separator",application:"Application","tool tip":"Tooltip",timer:"Timer",heading:"Heading",footnote:"Footnote","title bar":"TitleBar","date editor":"DateEditor",rating:"Slider"},u9="atspi-dump.py",u7=null;async function de(e,t={}){let r,n=ob().accessibility;if(n)return await n.captureTree(e,t);if("linux"!==process.platform)throw new k("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await ob().whichCommand("python3"))throw new k("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let a=t.maxNodes??1500,i=t.maxDepth??12,o=t.maxApps??24,l=[function(){if(u7)return u7;let e=p.dirname(g(import.meta.url));for(let t=0;t<5;t++){let r=p.join(e,"src","platforms","linux",u9);if(s.existsSync(r))return u7=r,r;if(0===t){let t=p.join(e,u9);if(s.existsSync(t))return u7=t,t}e=p.dirname(e)}throw new k("TOOL_MISSING",`Cannot find ${u9}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(a),"--max-depth",String(i),"--max-apps",String(o)],u=await oN("python3",l,{allowFailure:!0,timeoutMs:3e4});if(0!==u.exitCode){let e=u.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new k("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new k("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${u.exitCode}): ${e||u.stdout}`)}try{r=JSON.parse(u.stdout)}catch{throw new k("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${u.stdout.slice(0,200)}`)}if(r.error)throw new k("COMMAND_FAILED",`AT-SPI2: ${r.error}`);return{nodes:(r.nodes??[]).map(e=>{let t,r;return{index:e.index,type:(r=u6[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:r.truncated,surface:e}}async function dt(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&eM({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),r=await de(t);return{nodes:r.nodes,truncated:r.truncated}}async function dr(e,t,r){let{nodes:n}=await dt(r);for(let r of n.filter(r=>{let n=r.rect;return!!n&&e>=n.x&&t>=n.y&&e<=n.x+n.width&&t<=n.y+n.height}).sort((e,t)=>{let r=e.depth??0,n=t.depth??0;return r!==n?n-r:dn(e.rect)-dn(t.rect)})){let e=function(e){for(let t of[e.value,e.label,e.identifier])if("string"==typeof t&&t.length>0)return t;return""}(r);if(e.trim())return e}return""}function dn(e){return(e?.width??0)*(e?.height??0)}let da=/^[A-Za-z0-9_.:-]{1,64}$/;function di(e){return e?.clickButton??"primary"}function ds(e){return"primary"===e.button?null:"click"!==e.commandLabel?new k("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new k("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new k("UNSUPPORTED_OPERATION","click --button middle is not supported by the macOS runner yet"):"number"==typeof e.count||"number"==typeof e.intervalMs||"number"==typeof e.holdMs||"number"==typeof e.jitterPx||!0===e.doubleTap?new k("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}let dl=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];async function du(e,t,r){for(let n=0;n<e;n+=1)await r(n),n<e-1&&t>0&&await ef(t)}async function dd(e,t){let r=Number(t[0]),n=Number(t[1]),a=t[2]?Number(t[2]):void 0;if(Number.isNaN(r)||Number.isNaN(n))throw new k("INVALID_ARGS","longpress requires x y [durationMs]");return await e.longPress(r,n,a),{x:r,y:n,durationMs:a,...eG(`Long pressed (${r}, ${n})`)}}async function dc(e,t){let[r,n]=t.map(Number);if(Number.isNaN(r)||Number.isNaN(n))throw new k("INVALID_ARGS","focus requires x y");return await e.focus(r,n),{x:r,y:n,...eG(`Focused (${r}, ${n})`)}}async function dp(e,t,r){let n=ts(t[0]);if(n)throw new k("INVALID_ARGS",`type does not accept a target ref like "${n}"`,{hint:`Use fill ${n} "text" to target that field, or press ${n} then type "text" to append.`});let a=t.join(" ");if(!a)throw new k("INVALID_ARGS","type requires text");let i=tA(r?.delayMs??0,"delay-ms",0,1e4);return await e.type(a,i),{text:a,delayMs:i,...eG(dk("Typed",a))}}async function df(e,t,r){let n=Number(t[0]),a=Number(t[1]),i=t.slice(2).join(" ");if(Number.isNaN(n)||Number.isNaN(a)||!i)throw new k("INVALID_ARGS","fill requires x y text");let o=tA(r?.delayMs??0,"delay-ms",0,1e4);return await e.fill(n,a,i,o),{x:n,y:a,text:i,delayMs:o,...eG(dk("Filled",i))}}async function dm(e,t,r,n){var a,i,o,s;if(n?.directElementSelector&&"ios"===e.platform)return await dh(t,n.directElementSelector);let{x:l,y:u}=function(e,t){let[r,n]=e.map(Number);if(Number.isNaN(r)||Number.isNaN(n))throw new k("INVALID_ARGS",t);return{x:r,y:n}}(r,"press requires x y");if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return await dw(l,u,n);let d=di(n);if("primary"!==d)return await dg(e,l,u,d,n);let c=(s=n,{count:dv(s?.count,1,"count",1,200),intervalMs:dv(s?.intervalMs,0,"interval-ms",0,1e4),holdMs:dv(s?.holdMs,0,"hold-ms",0,1e4),jitterPx:dv(s?.jitterPx,0,"jitter-px",0,100),doubleTap:!!s?.doubleTap});return(function({doubleTap:e,holdMs:t,jitterPx:r}){if(e&&t>0)throw new k("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(e&&r>0)throw new k("INVALID_ARGS","double-tap cannot be combined with jitter-px")}(c),a=c.count,i=c.holdMs,o=c.jitterPx,rX(e.platform)&&a>1&&0===i&&0===o)?await dI(e,l,u,c,n):await dA(t,l,u,c)}async function dh(e,t){if(!e.tapElementSelector)throw new k("UNSUPPORTED_OPERATION","direct element selector tap is not supported");let r=await e.tapElementSelector(t);return{selector:t.raw,...r??{},...eG(`Tapped ${t.raw}`)}}async function dw(e,t,r){let n=di(r);if("primary"!==n)throw new k("UNSUPPORTED_OPERATION",`${n} click is not supported on macOS ${r.surface} sessions.`);return await lD(e,t,{bundleId:r.appBundleId,surface:r.surface}),{x:e,y:t,...eG(dM({x:e,y:t}))}}async function dg(e,t,r,n,a){return(function(e,t,r){let n=ds({commandLabel:"click",platform:e.platform,button:t,count:r?.count,intervalMs:r?.intervalMs,holdMs:r?.holdMs,jitterPx:r?.jitterPx,doubleTap:r?.doubleTap});if(n)throw n}(e,n,a),"linux"===e.platform)?await dy(t,r,n):(await at(e,{command:"mouseClick",x:t,y:r,button:n,appBundleId:a?.appBundleId},dS(a)),{x:t,y:r,button:n,...eG(dM({x:t,y:r,button:n}))})}async function dy(e,t,r){return"secondary"===r?await uH(e,t):await uW(e,t),{x:e,y:t,button:r,...eG(dM({x:e,y:t,button:r}))}}function dv(e,t,r,n,a){return tA(void 0===e?t:e,r,n,a)}async function dI(e,t,r,n,a){let i=await at(e,{command:"tapSeries",x:t,y:r,count:n.count,intervalMs:n.intervalMs,doubleTap:n.doubleTap,appBundleId:a?.appBundleId},dS(a));return{x:t,y:r,count:n.count,intervalMs:n.intervalMs,holdMs:n.holdMs,jitterPx:n.jitterPx,doubleTap:n.doubleTap,timingMode:"runner-series",...i,...eG(dM({x:t,y:r}))}}async function dA(e,t,r,n){let a;return await du(n.count,n.intervalMs,async i=>{let[o,s]=function(e,t){if(t<=0)return[0,0];let[r,n]=dl[e%dl.length];return[r*t,n*t]}(i,n.jitterPx),l=t+o,u=r+s;if(n.doubleTap){a??=await e.doubleTap(l,u)??void 0;return}n.holdMs>0?a??=await e.longPress(l,u,n.holdMs)??void 0:a??=await e.tap(l,u)??void 0}),ez({x:t,y:r,count:n.count,intervalMs:n.intervalMs,holdMs:n.holdMs,jitterPx:n.jitterPx,doubleTap:n.doubleTap,...a},dM({x:t,y:r}))}function dS(e){return{verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,requestId:e?.requestId}}async function db(e,t,r,n){let a=Number(r[0]),i=Number(r[1]),o=Number(r[2]),s=Number(r[3]);if([a,i,o,s].some(Number.isNaN))throw new k("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let l=tA(r[4]?Number(r[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(l))):l,d=tA(n?.count??1,"count",1,200),c=tA(n?.pauseMs??0,"pause-ms",0,1e4),p=n?.pattern??"one-way";if("one-way"!==p&&"ping-pong"!==p)throw new k("INVALID_ARGS",`Invalid pattern: ${p}`);if(rX(e.platform)&&d>1){let t=await at(e,{command:"dragSeries",x:a,y:i,x2:o,y2:s,durationMs:u,count:d,pauseMs:c,pattern:p,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId});return{x1:a,y1:i,x2:o,y2:s,durationMs:l,effectiveDurationMs:u,timingMode:"runner-series",count:d,pauseMs:c,pattern:p,...t,...eG(dD(d,p))}}return await du(d,c,async e=>{"ping-pong"===p&&e%2==1?await t.swipe(o,s,a,i,u):await t.swipe(a,i,o,s,u)}),ez({x1:a,y1:i,x2:o,y2:s,durationMs:l,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:d,pauseMs:c,pattern:p},dD(d,p))}async function d_(e,t,r){let n=t[0],a=t[1]?Number(t[1]):void 0,i=r?.pixels;if(!n)throw new k("INVALID_ARGS","scroll requires direction");if(void 0!==a&&!Number.isFinite(a))throw new k("INVALID_ARGS","scroll amount must be a number");if(void 0!==a&&void 0!==i)throw new k("INVALID_ARGS","scroll accepts either a relative amount or --pixels, not both");let o=function(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new k("INVALID_ARGS",`Unknown direction: ${e}`)}}(n),s=await e.scroll(o,{amount:a,pixels:i});return ez({direction:o,...void 0!==a?{amount:a}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==a?`Scrolled ${o} by ${a}`:`Scrolled ${o}`)}async function dN(e,t,r){if("android"===e.platform)throw new k("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");if("tv"===e.target)throw new k("UNSUPPORTED_OPERATION","pinch is not supported on tvOS");if("macos"===e.platform&&r?.surface&&"app"!==r.surface)throw new k("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let n=Number(t[0]),a=t[1]?Number(t[1]):void 0,i=t[2]?Number(t[2]):void 0;if(Number.isNaN(n)||n<=0)throw new k("INVALID_ARGS","pinch requires scale > 0");return await at(e,{command:"pinch",scale:n,x:a,y:i,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{scale:n,x:a,y:i,...eG(`Pinched to scale ${n}`)}}async function dx(e,t,r){let[n,a]=t.map(Number);if(Number.isNaN(n)||Number.isNaN(a))throw new k("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await sm(e,n,a)??""};if("linux"===e.platform)return{action:"read",text:await dr(n,a,r?.surface)};if("macos"===e.platform&&r?.surface&&"app"!==r.surface)return{action:"read",text:(await lM(n,a,{bundleId:r.appBundleId,surface:r.surface})).text};let i=await at(e,{command:"readText",x:n,y:a,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{action:"read",text:"string"==typeof i.text?i.text:"string"==typeof i.message?i.message:""}}function dM(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function dD(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function dk(e,t){return`${e} ${Array.from(t).length} chars`}function dE(e,t){let r,n=t?.subject??"Payload",a=e.trim();if(!a)throw new k("INVALID_ARGS",`${n} cannot be empty`);let i=t?.expandPath?t.expandPath(a,t.cwd):a;try{if(!s.statSync(i).isFile())throw new k("INVALID_ARGS",`${n} path is not a file: ${i}`);return{kind:"file",path:i}}catch(t){if(t instanceof k)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new k("INVALID_ARGS",`${n} file is not readable: ${i}`);if(e&&"ENOENT"!==e)throw new k("COMMAND_FAILED",`Unable to read ${n} file: ${i}`,{cause:String(t)})}if((r=a.trim()).startsWith("{")&&r.endsWith("}")||r.startsWith("[")&&r.endsWith("]"))return{kind:"inline",text:a};throw new k("INVALID_ARGS",`${n} file not found: ${i}`)}async function dO(e){let t=dE(e,{subject:"Push payload"}),r="inline"===t.kind?t.text:await dP(t.path);try{let e=JSON.parse(r);if(!e||"object"!=typeof e||Array.isArray(e))throw new k("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof k)throw t;throw new k("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function dP(e){try{return await u.readFile(e,"utf8")}catch(r){let t=r.code;if("ENOENT"===t)throw new k("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new k("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new k("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new k("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(r)})}}async function dC(e,t,r,n,a){let i={requestId:a?.requestId,appBundleId:a?.appBundleId,verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath},o=function(e,t){switch(e.platform){case"android":return{open:(t,r)=>q(e,t,r?.activity),openDevice:()=>J(e),close:t=>H(e,t),tap:(t,r)=>sI(e,t,r),doubleTap:async(t,r)=>{await sI(e,t,r),await sI(e,t,r)},swipe:(t,r,n,a,i)=>sA(e,t,r,n,a,i),longPress:(t,r,n)=>sx(e,t,r,n),focus:(t,r)=>sD(e,t,r),type:(t,r)=>sM(e,t,r),fill:(t,r,n,a)=>sk(e,t,r,n,a),scroll:(t,r)=>sO(e,t,r),screenshot:(t,r)=>s1(e,t,r),snapshot:async t=>{let r=await ex("snapshot_capture",async()=>await se(e,{interactiveOnly:t?.interactiveOnly,compact:t?.compact,depth:t?.depth,scope:t?.scope,raw:t?.raw}),{backend:"android"});return{nodes:r.nodes??[],truncated:r.truncated??!1,backend:"android",analysis:r.analysis,androidSnapshot:r.androidSnapshot}},back:t=>sS(e),home:()=>sb(e),rotate:t=>s_(e,t),appSwitcher:()=>sN(e),readClipboard:()=>ei(e),writeClipboard:t=>B(e,t),setSetting:(t,r,n,a)=>sK(e,t,r,n,a)};case"linux":return{open:e=>u0(e),openDevice:()=>Promise.resolve(),close:e=>u1(e),tap:(e,t)=>uq(e,t),doubleTap:(e,t)=>uz(e,t),swipe:(e,t,r,n,a)=>uX(e,t,r,n,a),longPress:(e,t,r)=>uK(e,t,r),focus:(e,t)=>uJ(e,t),type:(e,t)=>uZ(e,t),fill:(e,t,r,n)=>uQ(e,t,r,n),scroll:(e,t)=>uY(e,t),screenshot:(e,t)=>u8(e,t),snapshot:async e=>{let t=await ex("snapshot_capture",async()=>await dt(e?.surface),{backend:"linux-atspi"});return{nodes:t.nodes??[],truncated:t.truncated??!1,backend:"linux-atspi"}},back:()=>u2(),home:()=>u3(),rotate:()=>{throw new k("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new k("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>u5(),writeClipboard:e=>u4(e),setSetting:()=>{throw new k("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":return function(e,t){let r,{overrides:n,runnerOpts:a}={runnerOpts:r={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(n,a)=>await at(e,{command:"tap",x:n,y:a,appBundleId:t.appBundleId},r),tapElementSelector:async n=>await at(e,{command:"tap",selectorKey:n.key,selectorValue:n.value,appBundleId:t.appBundleId},r),doubleTap:async(n,a)=>await at(e,{command:"tapSeries",x:n,y:a,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},r),swipe:async(n,a,i,o,s)=>await at(e,{command:"drag",x:n,y:a,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},r),longPress:async(n,a,i)=>await at(e,{command:"longPress",x:n,y:a,durationMs:i,appBundleId:t.appBundleId},r),focus:async(n,a)=>await at(e,{command:"tap",x:n,y:a,appBundleId:t.appBundleId},r),type:async(n,a)=>{await at(e,{command:"type",text:n,delayMs:a,textEntryMode:"append",appBundleId:t.appBundleId},r)},fill:async(n,a,i,o)=>await at(e,{command:"type",x:n,y:a,text:i,delayMs:o,textEntryMode:"replace",appBundleId:t.appBundleId},r),scroll:async(n,a)=>await uO(at,e,t,r,n,a)}};return{open:(t,r)=>uu(e,t,{appBundleId:r?.appBundleId,url:r?.url}),openDevice:()=>ud(e),close:t=>uc(e,t),screenshot:async(t,r)=>{"macos"===e.platform&&r?.surface&&"app"!==r.surface?await lk(t,{surface:r.surface,fullscreen:r.fullscreen}):await l2(e,t,r?.appBundleId,r?.fullscreen,a)},snapshot:async t=>{var r;let n={nodes:Array.isArray((r=await ex("snapshot_capture",async()=>await at(e,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,compact:t?.compact,depth:t?.depth,scope:t?.scope,raw:t?.raw},a),{backend:"xctest"})).nodes)?r.nodes:void 0,truncated:"boolean"==typeof r.truncated?r.truncated:void 0},i=n.nodes??[];if(0===i.length&&"simulator"===e.kind)throw new k("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:i,truncated:n.truncated??!1,backend:"xctest"}},back:async r=>{"tv"===e.target?await at(e,uE("menu",t.appBundleId),a):await at(e,{command:"system"===r?"backSystem":"backInApp",appBundleId:t.appBundleId},a)},home:async()=>{"tv"===e.target?await at(e,uE("home",t.appBundleId),a):await at(e,{command:"home",appBundleId:t.appBundleId},a)},rotate:async r=>{await at(e,{command:"rotate",orientation:r,appBundleId:t.appBundleId},a)},appSwitcher:async()=>{await at(e,{command:"appSwitcher",appBundleId:t.appBundleId},a)},readClipboard:()=>uw(e),writeClipboard:t=>ug(e,t),setSetting:(t,r,n,a)=>uv(e,t,r,n,a),...n}}(e,t);default:throw new k("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,i);return eM({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await ex("platform_command",async()=>{switch(t){case"open":return dL(e,o,r,a);case"close":{let e=r[0];if(!e)return{closed:"session",...eG("Closed session")};return await o.close(e),{app:e,...eG(`Closed: ${e}`)}}case"press":return dm(e,o,r,a);case"swipe":return db(e,o,r,a);case"longpress":return dd(o,r);case"focus":return dc(o,r);case"type":return dp(o,r,a);case"fill":return df(o,r,a);case"scroll":return d_(o,r,a);case"pinch":return dN(e,r,a);case"trigger-app-event":{let{eventName:t,payload:n}=function(e){let t=e[0]?.trim(),r=e[1]?.trim();if(!t)throw new k("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!da.test(t))throw new k("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new k("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let n=function(e,t){if(e)try{let r=JSON.parse(e);if(!r||"object"!=typeof r||Array.isArray(r))throw new k("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let n=JSON.stringify(r);if(Buffer.byteLength(n,"utf8")>8192)throw new k("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return r}catch(t){if(t instanceof k)throw t;throw new k("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(r,t);return{eventName:t,payload:n}}(r),i=function(e,t,r){var n;let a,i=(a=("ios"===(n=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===n?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,a?.trim()||void 0);if(!i)throw new k("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new k("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,n);return await o.open(i,{appBundleId:a?.appBundleId}),{event:t,eventUrl:i,transport:"deep-link",...eG(`Triggered app event: ${t}`)}}case"screenshot":{let e=r[0]??n??`./screenshot-${Date.now()}.png`;await u.mkdir(p.dirname(e),{recursive:!0});let t=ej(a);return await o.screenshot(e,{appBundleId:a?.appBundleId,fullscreen:t.fullscreen,stabilize:t.stabilize,surface:a?.surface}),{path:e,...eG(`Saved screenshot: ${e}`)}}case"back":return await o.back(a?.backMode),{action:"back",mode:a?.backMode??"in-app",...eG("Back")};case"home":return await o.home(),{action:"home",...eG("Home")};case"rotate":{let e=tS(r[0]);return await o.rotate(e),{action:"rotate",orientation:e,...eG(`Rotated to ${e}`)}}case"app-switcher":return await o.appSwitcher(),{action:"app-switcher",...eG("Opened app switcher")};case"clipboard":return dR(o,r);case"keyboard":return dT(e,r,a,i);case"settings":return d$(e,o,r,a);case"push":return dF(e,r,a);case"snapshot":return await dU(o,a);case"read":return dx(e,r,a);default:throw new k("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function dL(e,t,r,n){let a=r[0],i=r[1];if(r.length>2)throw new k("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!a)return await t.openDevice(),{app:null,...eG("Opened device")};if(void 0!==i){if("android"===e.platform)throw new k("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(ea(a))throw new k("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!ea(i))throw new k("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(a,{activity:n?.activity,appBundleId:n?.appBundleId,url:i}),{app:a,url:i,...eG(`Opened: ${a}`)}}return await t.open(a,{activity:n?.activity,appBundleId:n?.appBundleId}),{app:a,...eG(`Opened: ${a}`)}}async function dR(e,t){let r=(t[0]??"").toLowerCase();if("read"!==r&&"write"!==r)throw new k("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===r){if(1!==t.length)throw new k("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:r,text:await e.readClipboard()}}if(t.length<2)throw new k("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let n=t.slice(1).join(" ");return await e.writeClipboard(n),{action:r,textLength:Array.from(n).length,...eG("Clipboard updated")}}async function dT(e,t,r,n){let a=(t[0]??"status").toLowerCase();if("status"!==a&&"get"!==a&&"dismiss"!==a)throw new k("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(t.length>1)throw new k("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===a){let t=await $(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type,inputMethodPackage:t.inputMethodPackage,focusedPackage:t.focusedPackage,focusedResourceId:t.focusedResourceId,inputOwner:t.inputOwner}}let t=await z(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type,inputMethodPackage:t.inputMethodPackage,focusedPackage:t.focusedPackage,focusedResourceId:t.focusedResourceId,inputOwner:t.inputOwner}}if("ios"===e.platform){if("dismiss"!==a)throw new k("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await at(e,{command:"keyboardDismiss",appBundleId:r?.appBundleId},n);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...eG(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new k("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function d$(e,t,r,n){var a;let[i,o,s,l]=r,u="location"===i&&"set"===o,d=("permission"===i||u?r[4]:r[2])??n?.appBundleId,c="permission"===i?{permissionTarget:s,permissionMode:l}:u?{latitude:eC(s,"latitude"),longitude:eC(l,"longitude")}:void 0;eM({level:"debug",phase:"settings_apply",data:u?{setting:i,state:o,latitude:s,longitude:l,platform:e.platform}:"permission"===i?{setting:i,state:o,permissionTarget:s,permissionMode:l,platform:e.platform}:{setting:i,state:o,appBundleId:d,platform:e.platform}});let p=await t.setSetting(i,o,d,c);return p&&"object"==typeof p?ez({setting:i,state:o,...p},("string"==typeof(a=p).message&&a.message.length>0?a.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...eG(`Updated setting: ${i}`)}}async function dF(e,t,r){let n=t[0]?.trim(),a=t[1]?.trim();if(!n||!a)throw new k("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await dO(a);if("ios"===e.platform)return await uy(e,n,i),{platform:"ios",bundleId:n,...eG(`Pushed notification to ${n}`)};let o=await o2(e,n,i);return{platform:"android",package:n,action:o.action,extrasCount:o.extrasCount,...eG(`Pushed notification to ${n}`)}}async function dU(e,t){return await e.snapshot({appBundleId:t?.appBundleId,interactiveOnly:t?.snapshotInteractiveOnly,compact:t?.snapshotCompact,depth:t?.snapshotDepth,scope:t?.snapshotScope,raw:t?.snapshotRaw,surface:t?.surface})}function dG(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}let dV=em(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),dj=em(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function dB(e,t,r){return t||dq(r)?null:dG("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function dq(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function dH(e){return"ios"===e.platform&&"simulator"===e.kind}async function dW(e,t){dH(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function dz(e){let t=dq(e.flags)||!e.session?await op(e.flags??{}):await dK(e.session.device);return!1!==e.ensureReady&&await oY(t),t}async function dK(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 op(t)}catch(e){if(!(e instanceof k)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await op({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function dJ(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 dX={startIosSimulatorRecording:({device:e,outPath:t})=>E("xcrun",ry(e,["io",e.id,"recordVideo",t]),{allowFailure:!0})},dY=rr(dX,function(e={}){return{...dX,...e}});async function dZ(e,t){return await dY.run(e,t)}let dQ=[{resolverKey:"androidAdbProvider",resolve(e,t){let r=e.androidAdbProvider;if(!r||"android"!==t.device.platform)return{};let n=r(t),a="function"==typeof n?n:n?.exec;return{androidAdb:{provider:n,executor:a,serial:t.device.id}}},appendWrapper(e,t){d3(t,e.androidAdb,(t,r)=>e3(t,{serial:e.androidAdb?.serial??""},r))}},{resolverKey:"appleRunnerProvider",resolve(e,t){let r=e.appleRunnerProvider;return r&&rX(t.device.platform)?{appleRunner:{provider:r(t),deviceId:t.device.id,requestId:t.req.meta?.requestId}}:{}},appendWrapper(e,t){d3(t,e.appleRunner,(t,r)=>n7(t,{deviceId:e.appleRunner?.deviceId??"",requestId:e.appleRunner?.requestId},r))}},{resolverKey:"appleToolProvider",resolve(e,t){let r=e.appleToolProvider;return r&&rX(t.device.platform)?{appleTool:{provider:r(t)}}:{}},appendWrapper(e,t){d3(t,e.appleTool,rp)}},{resolverKey:"linuxToolProvider",resolve(e,t){let r=e.linuxToolProvider;return r&&"linux"===t.device.platform?{linuxTool:{provider:r(t)}}:{}},appendWrapper(e,t){d3(t,e.linuxTool,o_)}},{resolverKey:"appLogProvider",resolve(e,t){let r=e.appLogProvider;return r?{appLog:{provider:r(t)}}:{}},appendWrapper(e,t){d3(t,e.appLog,ie)}},{resolverKey:"recordingProvider",resolve(e,t){let r=e.recordingProvider;return r?{recording:{provider:r(t)}}:{}},appendWrapper(e,t){d3(t,e.recording,dZ)}}];async function d0(e,t){let r=await d1(e),n={androidAdbExecutor:r.androidAdb?.executor},a=function(e){let t=[];for(let r of dQ)r.appendWrapper(e,t);return t}(r);return await d5(a,async()=>await t(n))}async function d1(e){var t,r,n;if(t=e.providers,!dQ.some(e=>!!t[e.resolverKey]))return{};let a=await d2(e.req,e.existingSession);if(!a)return{};let i=(r=e,n=a,{req:r.req,device:n,session:r.existingSession});return dQ.reduce((t,r)=>({...t,...r.resolve(e.providers,i)}),{})}async function d2(e,t){var r;return t?t.device:e.command===eL.open||dq(e.flags)||(r=e).command===eL.record&&"start"===(r.positionals?.[0]??"").toLowerCase()?await op(e.flags??{}):void 0}function d3(e,t,r){let n=t?.provider;n&&e.push(async e=>await r(n,e))}async function d5(e,t){let r=t;for(let t of[...e].reverse()){let e=r;r=async()=>await t(e)}return await r()}let d4=e=>"macos"!==e.platform,d8={device:!0},d6={},d9={alert:{apple:{simulator:!0,device:!0},android:{},linux:d6,supports:e=>"macos"===e.platform||"simulator"===e.kind},pinch:{apple:{simulator:!0,device:!0},android:{},linux:d6,supports:e=>"macos"===e.platform||"simulator"===e.kind&&"tv"!==e.target},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6,supports:d4},...tN,back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6,supports:d4},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8,supports:e=>"android"===e.platform||"linux"===e.platform||"macos"===e.platform||"simulator"===e.kind},keyboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},...td,...t_,focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8,supports:d4},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6,supports:d4},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d8},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6,supports:e=>"android"===e.platform||"macos"===e.platform||"simulator"===e.kind},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:d6},...eT};function d7(e,t){let r=d9[e];if(!r)return!0;let n=rX(t.platform)?r.apple:"linux"===t.platform?r.linux:r.android;return!!n&&(!r.supports||!!r.supports(t))&&!0===n[t.kind??"unknown"]}let ce=[250,400,600];function ct(e,t,r=e.snapshot){if("android"!==e.device.platform)return;let n=r?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:r?.nodes.length??0,baselineSignatures:n?ci(r?.nodes??[]):void 0,routeComparable:n}}function cr(e){if(!e||"android"!==e.device.platform)return;let t=e.androidSnapshotFreshness;if(t)return Date.now()-t.markedAt>2500?void delete e.androidSnapshotFreshness:t}function cn(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function ca(e){return"press"===e||"click"===e||"back"===e||"open"===e}function ci(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}function co(e,t,r,n,a){return{requestId:a??e_().requestId,appBundleId:r,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:n,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,...eW(t),count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:di(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}function cs(e){e?.postGestureStabilization&&(e.postGestureStabilization=void 0)}async function cl(e){let{session:t,capture:r}=e,n=t?.postGestureStabilization;if(!t||"ios"!==t.device.platform||!n)return await r();let a=Date.now(),i=1,o=await r(),s=cu(o.nodes);for(;Date.now()-a<1500;){await ef(200),i+=1;let e=await r(),l=cu(e.nodes);if(function(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1){let n=e[r],a=t[r];if(!n||!a||n.key!==a.key||Math.abs(n.x-a.x)>1||Math.abs(n.y-a.y)>1||Math.abs(n.width-a.width)>1||Math.abs(n.height-a.height)>1)return!1}return!0}(s,l))return cs(t),eM({level:i>2?"info":"debug",phase:"post_gesture_snapshot_stabilized",data:{action:n.action,attempts:i,durationMs:Date.now()-a}}),e;o=e,s=l}return cs(t),eM({level:"warn",phase:"post_gesture_snapshot_stabilization_timeout",data:{action:n.action,attempts:i,durationMs:Date.now()-a}}),o}function cu(e){let t=new Map,r=[];for(let i of e){var n,a;if(!i.rect||!([(n=i.rect).x,n.y,n.width,n.height].every(e=>Number.isFinite(e))&&n.width>0&&n.height>0)||(a=i,`${a.label??""} ${a.identifier??""}`.toLowerCase().includes("scroll bar")))continue;let e=[i.identifier,i.label,i.value,i.type].map(e=>"string"==typeof e?e.trim():"").join("|");if(!e.replaceAll("|",""))continue;let o=t.get(e)??0;t.set(e,o+1),r.push({key:`${e}|#${o}`,x:i.rect.x,y:i.rect.y,width:i.rect.width,height:i.rect.height})}return r}async function cd(e){if("ios"===e.device.platform&&e.session?.postGestureStabilization)return{snapshot:await cl({session:e.session,capture:async()=>(await cf(e)).snapshot})};let t=cr(e.session);if(t&&"android"===e.device.platform)return await cp(e,t);let r=await cc(e);return cn(e.session),{snapshot:cw(r,cm(e)),analysis:r.analysis,androidSnapshot:r.androidSnapshot}}async function cc(e){let{device:t,session:r,flags:n,outPath:a,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await dt(r?.surface);return cg({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:n?.snapshotDepth,snapshotInteractiveOnly:n?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&r?.surface&&"app"!==r.surface?cg(await lx(r.surface,{bundleId:"menubar"===r.surface?r.appBundleId:void 0}),{snapshotDepth:n?.snapshotDepth,snapshotInteractiveOnly:n?.snapshotInteractiveOnly,snapshotScope:o}):await dC(t,"snapshot",[],a,{...co(i,{...n,snapshotScope:o},r?.appBundleId,r?.trace?.outPath)})}async function cp(e,t){let r=await cf(e),n=ch(r,t,e),a=0,i=t.markedAt+1500;for(let o of ce){if(!n)break;let s=i-Date.now();if(s<=0)break;await ef(Math.min(o,s)),r=await cf(e),a+=1,n=ch(r,t,e)}return n||cn(e.session),{snapshot:r.snapshot,analysis:r.data.analysis,androidSnapshot:r.data.androidSnapshot,freshness:a>0||n?{action:t.action,retryCount:a,staleAfterRetries:!!n,reason:n??void 0}:void 0}}async function cf(e){let t=await cc(e);return{data:t,snapshot:cw(t,cm(e))}}function cm(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function ch(e,t,r){var n,a;let i=r.flags?.snapshotInteractiveOnly===!0,o=e.data.analysis;if(i&&0===e.snapshot.nodes.length&&o&&o.rawNodeCount>=12)return"empty-interactive";if("ref-refresh"===r.androidFreshnessMode)return null;return(n=t.baselineCount,a=e.snapshot.nodes.length,!(n<12)&&a<=Math.floor(.2*n))?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&ca(t.action)&&function(e,t){if(!e||0===e.length)return!1;let r=Math.max(e.length,t.length);if(r<12)return!1;let n=ci(t),a=Math.min(e.length,n.length),i=0;for(let t=0;t<a;t+=1)e[t]===n[t]&&(i+=1);let o=Math.max(0,n.length-e.length),s=Math.max(0,e.length-n.length),l=Math.max(3,Math.floor(.15*r));return i>=Math.floor(.9*r)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function cw(e,t){let r=e?.nodes??[],n=tw(t?.snapshotRaw?r:tH(r));return{nodes:tO(t?.snapshotScope&&e?.backend!=="macos-helper"?cy(n,t.snapshotScope):n),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,presentationKey:tk(tx(t)),comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function cg(e,t){var r,n;let a=e.nodes??[];return t.snapshotScope&&(a=cy(a,t.snapshotScope)),t.snapshotInteractiveOnly&&(a=function(e){if(0===e.length)return e;let t=new Map;for(let r of e)t.set(r.index,r);let r=new Set;for(let n of e){if(!function(e){if(e.focused||e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(n))continue;let e=n;for(;e&&!r.has(e.index);)r.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===r.size?e:cv(e.filter(e=>r.has(e.index)))}(a)),"number"==typeof t.snapshotDepth&&(r=a,n=t.snapshotDepth,a=cv(r.filter(e=>(e.depth??0)<=n))),{...e,nodes:a}}function cy(e,t){let r=tU(tO(e),t);if(!r)return[];let n=e.findIndex(e=>e.index===r.index);if(-1===n)return[];let a=e[n]?.depth??0,i=[];for(let t=n;t<e.length;t+=1){let r=e[t];if(!r)continue;let o=r.depth??0;if(t>n&&o<=a)break;i.push(r)}return cv(i,a)}function cv(e,t=0){let r=new Map;for(let[t,n]of e.entries())r.set(n.index,t);return e.map((e,n)=>({...e,index:n,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?r.get(e.parentIndex):void 0}))}function cI(e,t){e.snapshot=t,e.snapshotScopeSource=void 0}function cA(e){return{get:t=>t===e.sessionName?function(e,t,r={}){if(e)return{name:t,appBundleId:e.appBundleId,appName:e.appName,...!0===r.includeSnapshot?{snapshot:e.snapshot}:{},metadata:{surface:e.surface,...r.metadata??{}}}}(e.getSession(),e.sessionName,e.recordOptions):void 0,set:t=>{t.name!==e.sessionName?eM({level:"warn",phase:"runtime_session_write_skipped",data:{expected:e.sessionName,received:t.name}}):e.setRecord(t)}}}async function cS(e){let{session:t,sessionName:r,outPath:n,outputPlacement:a,dispatchContext:i}=e,o=tg({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:n}=e;return{platform:t.device.platform,captureScreenshot:async(e,a,i)=>{let o={...n,...eW(i),surface:i?.surface};return"out"===r?cb(await dC(t.device,"screenshot",[],a,o)):cb(await dC(t.device,"screenshot",[a],void 0,o))}}}({session:t,outputPlacement:a,dispatchContext:i}),artifacts:{resolveInput:async()=>{throw new k("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await u.mkdtemp(p.join(d.tmpdir(),"agent-device-screenshot-")),r=p.join(t,"screenshot.png")),await u.mkdir(p.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await u.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await u.mkdtemp(p.join(d.tmpdir(),`${e.prefix}-`));return{path:p.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await u.rm(t,{recursive:!0,force:!0})}}}},sessions:cA({sessionName:r,getSession:()=>t,recordOptions:{includeSnapshot:!1},setRecord:()=>{}}),policy:tI()});return await o.capture.screenshot({session:r,requestId:i.requestId,appBundleId:t.appBundleId,...ej(i),surface:t.surface,...n?{out:{kind:"path",path:n}}:{}})}function cb(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let c_=/\bis(?:n't| not)\s+responding\b/i,cN=/^close app$/i;async function cx(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await cM(t),r=function(e){if(cO(e))return e.find(e=>{let t=cE(e);return t.length>0&&cN.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:n,y:a}=tE(r.rect),i=await R(t.device,["shell","input","tap",String(Math.round(n)),String(Math.round(a))],{allowFailure:!0});if(0!==i.exitCode)return eM({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:i.exitCode,stdout:i.stdout.trim(),stderr:i.stderr.trim()}}),"failed";if(!await cD(t))return eM({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await q(t.device,t.appBundleId),!await ck(t,t.appBundleId)))return eM({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return eM({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:n,y:a}}),"recovered"}catch(e){return eM({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 cM(e){return tO(tH((await se(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function cD(e){for(let t=0;t<12;t+=1){if(!cO(await cM(e)))return!0;await ef(500)}return!cO(await cM(e))}async function ck(e,t){for(let r=0;r<12;r+=1){if((await Z(e.device)).package===t)return!0;await ef(500)}return(await Z(e.device)).package===t}function cE(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 cO(e){return e.some(e=>{let t=cE(e);return t.length>0&&c_.test(t)})}let cP=[255,59,48,255],cC=[255,214,10,255],cL=[0,0,0,255],cR={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 cT(e){let t=tb(await u.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,n={}){let a=function(e){let t=null;for(let r of e)cF(r)&&cB(r.rect)&&(!t||cq(r.rect)>cq(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,n=-1/0,a=-1/0;for(let i of e)i.rect&&cB(i.rect)&&(t=Math.min(t,i.rect.x),r=Math.min(r,i.rect.y),n=Math.max(n,i.rect.x+i.rect.width),a=Math.max(a,i.rect.y+i.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||n<=t||a<=r?null:{x:t,y:r,width:n-t,height:a-r}}(e.filter(e=>{var t;return cB(e.rect)&&!("image"===tq((t=e).type??"")&&!cU(t.label))}))}(e.nodes),i=new Map;for(let n of e.nodes){if(!function(e){let t=[e.label,e.value].some(cG)||cV(e.identifier);return c$(e)?t:t&&function(e){let t=tq(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(n))continue;let o=function(e,t){if(function(e){return c$(e)&&!cF(e)}(t)&&cB(t.rect))return t;let r=function(e,t){let r=t,n=new Set;for(;void 0!==r.parentIndex&&!n.has(r.ref);){;n.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(c$(t)&&!cF(t)&&cB(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&cB(r.rect))return r;if(t.hittable&&cB(t.rect)&&!cF(t))return t;let n=tR(e,t);return n?.rect&&cB(n.rect)&&!cF(n)?n:null}(e.nodes,n);if(!o?.rect||!cB(o.rect))continue;let s=function(e,t,r){let n=cj(e);if(e.ref!==t.ref&&n)return n;let a=function(e,t){let r=null;for(let n of t){if(n.ref===e.ref||!function(e,t,r){let n=e;for(;void 0!==n.parentIndex;){let e=r[n.parentIndex];if(!e)break;if(e.ref===t.ref)return!0;n=e}return!1}(n,e,t))continue;let a=cj(n);if(!a)continue;let i=function(e){let t=0;return tq(e.type??"").includes("text")&&(t+=2),cG(e.label)&&(t+=2),cG(e.value)&&(t+=1),t}(n);(!r||i>r.score)&&(r={label:a,score:i})}return r?.label}(t,r);return a||(cj(t)??tG(t,r))}(n,o,e.nodes),l=function(e,t,r){let n=0;return e.ref===t.ref&&(n+=4),t.hittable&&(n+=3),c$(t)&&(n+=3),c$(e)&&(n+=2),r&&(n+=2),cV(t.identifier)&&(n+=1),cU(t.value)&&(n+=1),n}(n,o,s),u=function(e,t,r,n){if(!e)return cz({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,n);let a=r/e.width,i=n/e.height;return cz({x:Math.round((t.x-e.x)*a),y:Math.round((t.y-e.y)*i),width:Math.max(1,Math.round(t.width*a)),height:Math.max(1,Math.round(t.height*i))},r,n)}(a,o.rect,t,r);if(!cB(u))continue;let d=i.get(o.ref);(!d||l>d.score)&&i.set(o.ref,{ref:o.ref,label:s,rect:o.rect,overlayRect:u,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>cq(e.overlayRect)-cq(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(cH(e.overlayRect,r.overlayRect)||cH(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}cq(r.overlayRect)<cq(t[e].overlayRect)&&(t[e]=r)}return t})([...i.values()]).sort((e,t)=>{if(t.score!==e.score)return t.score-e.score;let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let n=e.overlayRect.x-t.overlayRect.x;return 0!==n?n:cW(e.ref,t.ref)}).slice(0,n.maxRefs??24).sort((e,t)=>{let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let n=e.overlayRect.x-t.overlayRect.x;return 0!==n?n:cW(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:tE(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var n,a;(function(e,t,r){for(let n=0;n<2;n+=1)cJ(e,t.x,t.x+t.width-1,t.y+n,r),cJ(e,t.x,t.x+t.width-1,t.y+t.height-1-n,r),cX(e,t.x+n,t.y,t.y+t.height-1,r),cX(e,t.x+t.width-1-n,t.y,t.y+t.height-1,r)})(n=t,(a=e).overlayRect,cP),function(e,t,r){let n=6+5*r.length+ +Math.max(0,r.length-1),a=cK(t.x,0,Math.max(0,e.width-n)),i=t.y-11-2,o=i>=0?i:cK(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,n,a){for(let i=0;i<11;i+=1)for(let o=0;o<n;o+=1)cY(e,t+o,r+i,a)})(e,a,o,n,cC),function(e,t,r,n,a){let i=t;for(let t of n.toLowerCase()){let n=cR[t];if(n)for(let t=0;t<n.length;t+=1)for(let o=0;o<n[t].length;o+=1)"1"===n[t][o]&&cY(e,i+o,r+t,a);i+=6}}(e,a+3,o+2,r,cL)}(n,a.overlayRect,a.ref)}return await u.writeFile(e.screenshotPath,b.sync.write(t)),r}function c$(e){let t=[e.type,e.role,e.subrole].map(e=>tq(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 cF(e){let t=[e.type,e.role,e.subrole].map(e=>tq(e??"")).join(" ");return t.includes("application")||t.includes("window")}function cU(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function cG(e){var t;let r;return!!cU(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function cV(e){var t;return"string"==typeof e&&!!cG(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function cj(e){let t=[e.label,e.value].find(cG);return t?t.trim():cV(e.identifier)?e.identifier.trim():void 0}function cB(e){return!!(e&&e.width>0&&e.height>0)}function cq(e){return e.width*e.height}function cH(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 cW(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function cz(e,t,r){let n=cK(e.x,0,Math.max(0,t-1)),a=cK(e.y,0,Math.max(0,r-1)),i=Math.max(1,t-n),o=Math.max(1,r-a);return{x:n,y:a,width:cK(e.width,1,i),height:cK(e.height,1,o)}}function cK(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function cJ(e,t,r,n,a){for(let i=t;i<=r;i+=1)cY(e,i,n,a)}function cX(e,t,r,n,a){for(let i=r;i<=n;i+=1)cY(e,t,i,a)}function cY(e,t,r,n){if(t<0||r<0||t>=e.width||r>=e.height)return;let a=(e.width*r+t)*4;e.data[a]=n[0],e.data[a+1]=n[1],e.data[a+2]=n[2],e.data[a+3]=n[3]}function cZ(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 cQ=new WeakMap;function c0(e){if(!e)return;let t=cQ.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)&&c1(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(c1);if(0===r.length)return;let n=Math.max(...r.map(e=>e.x+e.width)),a=Math.max(...r.map(e=>e.y+e.height));if(!(n<=0)&&!(a<=0))return{x:0,y:0,width:n,height:a}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return cQ.set(e,r),r}function c1(e){return!!e&&e.width>0&&e.height>0}let c2={referenceWidth:1e3,referenceHeight:1e3};function c3(e,t,r,n,a={},i=Date.now(),o=Date.now()){var s,l,u;let d,c,p=e.recording;if(!p)return;let f={...a,...n??{}},m=c6(f.effectiveDurationMs)??c6(f.durationMs),h={recordingStartedAt:p.startedAt,gestureClockOriginAtMs:p.gestureClockOriginAtMs,gestureClockOriginUptimeMs:p.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===p.platform?p.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:c6(f.gestureStartUptimeMs),gestureEndUptimeMs:c6(f.gestureEndUptimeMs),fallbackStartedAtMs:i,fallbackFinishedAtMs:o},w="number"==typeof(s={gestureStartUptimeMs:c6(f.gestureStartUptimeMs),gestureEndUptimeMs:c6(f.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:i,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),g="ios"===e.device.platform&&void 0===c6(f.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=c9(c6(t.count),1)??1,r=!0===t.doubleTap,n=c9(c6(t.holdMs),1);return 1===e&&!r&&void 0===n}default:return!1}}(t,f)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return cZ(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:w}):cZ(h),y=(l=e.snapshot,d=c6((u=f).referenceWidth),c=c6(u.referenceHeight),void 0!==d&&d>0&&void 0!==c&&c>0?{referenceWidth:d,referenceHeight:c}:c0(l)),v=function(e,t,r,n,a,i){switch(e){case"click":case"press":return function(e,t,r,n){let a=c7(t,e);if(!a)return[];let{x:i,y:o}=a,s=c9(c6(t.count),1)??1,l=c9(c6(t.intervalMs),0)??0,u=!0===t.doubleTap,d=c9(c6(t.holdMs),1),c=[];for(let e=0;e<s;e+=1){let t=r+e*l;if(void 0!==d&&d>0){c.push(c4(t,i,o,d,n));continue}c.push(c5(t,i,o,n)),u&&c.push(c5(t+90,i,o,n))}return c}(t,r,n,i);case"fill":case"focus":return function(e,t,r,n){let a=c7(t,e);if(!a)return[];let{x:i,y:o}=a;return[c5(r,i,o,n)]}(t,r,n,i);case"longpress":return function(e,t,r,n,a){let i=c7(t,e);if(!i)return[];let{x:o,y:s}=i;return[c4(r,o,s,pt(n,[c6(t.durationMs),c6(e[2])],800),a)]}(t,r,n,a,i);case"scroll":return function(e,t,r,n,a){let i=pe(t,e),o=c8(t.contentDirection)??c8(t.direction);if(!i||!o)return[];let{x1:s,y1:l,x2:u,y2:d}=i,c=pt(n,[],250),p=c6(t.amount)??c6(e[1]),f=c6(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:u,y2:d,...a,durationMs:c,contentDirection:o,...void 0!==p?{amount:p}:{},...void 0!==f?{pixels:f}:{}}]}(t,r,n,a,i);case"swipe":return function(e,t,r,n,a){let i=pe(t,e);if(!i)return[];let{x1:o,y1:s,x2:l,y2:u}=i,d=pt(n,[c6(t.effectiveDurationMs),c6(t.durationMs),c6(e[4])],250),c=c9(c6(t.count),1)??1,p=c9(c6(t.pauseMs),0)??0,f="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===f&&e%2==1,n=t?l:o,i=t?u:s,c=t?o:l,h=t?s:u,w=r+e*(d+p);if("back-swipe"===function(e,t,r,n,a){if(!a||Math.abs(r-e)<=1.25*Math.abs(n-t))return"swipe";let i=.08*a.referenceWidth;return e<=i&&r>e||e>=a.referenceWidth-i&&r<e?"back-swipe":"swipe"}(n,i,c,h,a)){m.push({kind:"back-swipe",tMs:w,x:n,y:i,x2:c,y2:h,...a,durationMs:d,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"}(n,c,a)});continue}m.push({kind:"swipe",tMs:w,x:n,y:i,x2:c,y2:h,...a,durationMs:d})}return m}(t,r,n,a,i);case"pinch":return function(e,t,r,n,a){let i=c7(t,e,1),o=c6(t.scale)??c6(e[0]);if(!i||void 0===o||o<=0)return[];let{x:s,y:l}=i;return[{kind:"pinch",tMs:r,x:s,y:l,...a,scale:o,durationMs:pt(n,[],280)}]}(t,r,n,a,i);default:return[]}}(t,r,f,g,w,y);0!==v.length&&(p.gestureEvents.push(...v),eM({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:g,gestureDurationMs:w,kinds:v.map(e=>e.kind)}}))}function c5(e,t,r,n){return{kind:"tap",tMs:e,x:t,y:r,...n}}function c4(e,t,r,n,a){return{kind:"longpress",tMs:e,x:t,y:r,...a,durationMs:n}}function c8(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 c6(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 c9(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function c7(e,t,r=0){let n=c6(e.x)??c6(t[r]),a=c6(e.y)??c6(t[r+1]);if(void 0!==n&&void 0!==a)return{x:n,y:a}}function pe(e,t){let r=c6(e.x1)??c6(t[0]),n=c6(e.y1)??c6(t[1]),a=c6(e.x2)??c6(t[2]),i=c6(e.y2)??c6(t[3]);if(void 0!==r&&void 0!==n&&void 0!==a&&void 0!==i)return{x1:r,y1:n,x2:a,y2:i}}function pt(e,t,r){return c9(e,1)??t.map(e=>c9(e,1)).find(e=>void 0!==e)??r}async function pr(e){var t,r,n,a,i,o,s,l,u;let d,c,p,f,m,{req:h,session:w,logPath:g,sessionStore:y,contextFromFlags:v}=e,I=h.command;if(!d7(I,w.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${I} is not supported on this device`}};if("android"===w.device.platform&&w.recording&&"record"!==I&&"failed"===await cx({session:w}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:A,resolvedOut:S,recordedPositionals:b,recordedFlags:_}="screenshot"===(t=h).command?(c=(n=(r=t).positionals??[],a=r.meta?.cwd,(d=n[0])?[aD.expandHome(d,a),...n.slice(1)]:n),f=(p=(i=r.flags?.out,o=r.meta?.cwd,i?aD.expandHome(i,o):i))?{...r.flags??{},out:p}:r.flags??{},{resolvedPositionals:c,resolvedOut:p,recordedPositionals:c,recordedFlags:f}):{resolvedPositionals:m=(s=t).positionals??[],resolvedOut:s.flags?.out,recordedPositionals:m,recordedFlags:s.flags??{}},N=Date.now(),x={...v(h.flags,w.appBundleId,w.trace?.outPath),surface:w.surface},M="screenshot"===I?await cS({session:w,sessionName:e.sessionName,outPath:A[0]??S,outputPlacement:"screenshot"!==(l=h).command?"default":(l.positionals??[])[0]?"positional":l.flags?.out?"out":"default",dispatchContext:x}):await dC(w.device,I,A,S,{...x});return"screenshot"===I&&h.flags?.overlayRefs&&"string"==typeof M?.path&&await pn(w,M,g),function(e){let{session:t,sessionStore:r,command:n,resolvedPositionals:a,recordedPositionals:i,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:u,flags:d}=e,c=function(e,t,r,n){if("scroll"!==t)return n;let a=c0(e.snapshot),i={...n??{}},o=c8(i.direction)??c8(r[0]);if(!o)return n;let s=c6(i.amount)??c6(r[1]),l=c6(i.pixels),u=pe(i,[]),d=c6(i.referenceWidth),c=c6(i.referenceHeight),p=void 0!==d&&d>0&&void 0!==c&&c>0?{referenceWidth:d,referenceHeight:c}:a??c2;if(u&&(u.x1!==u.x2||u.y1!==u.y2))return{...i,x1:u.x1,y1:u.y1,x2:u.x2,y2:u.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==l?{pixels:l}:{},referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight,durationMs:250};let f=o3({direction:o,amount:s,pixels:l,referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight});return{...i,x1:f.x1,y1:f.y1,x2:f.x2,y2:f.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==f.pixels?{pixels:f.pixels}:{},referenceWidth:p.referenceWidth,referenceHeight:p.referenceHeight,durationMs:250}}(t,n,a,s);c3(t,n,a,c,d,l,u),r.recordAction(t,{command:n,positionals:i,flags:o,result:s??{}})}({session:w,sessionStore:y,command:I,resolvedPositionals:A,recordedPositionals:b,recordedFlags:_,data:M,actionStartedAt:N,actionFinishedAt:Date.now(),flags:h.flags??{}}),ca(I)&&ct(w,I),"ios"!==w.device.platform||("swipe"===(u=I)||"scroll"===u)&&(w.postGestureStabilization={action:I,markedAt:Date.now()}),{ok:!0,data:M??{}}}async function pn(e,t,r){let n=cw(await cc({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);cI(e,n);let a=await cT({screenshotPath:t.path,snapshot:n});t.overlayRefs=a}async function pa(e){let{device:t,node:r,flags:n,appBundleId:a,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=t$(r),u=tp(r.rect);if(!u)return l;try{let e=await dC(t,"read",[String(u.x),String(u.y)],void 0,{...s(n,a,i),surface:o}),d=e&&"object"==typeof e?e:void 0,c="string"==typeof d?.text?d.text:"";if(c.trim())return c;return eM({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:r.ref,surface:o,platform:t.platform}}),l}catch(e){return eM({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:r.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}async function pi(e,t,r){let n=e.get(t),a=n?.device??await op(r??{});return n||await oY(a),{session:n,device:a}}async function po(e,t,r){let n=!e&&"ios"===t.platform;try{return await r()}finally{n&&await nY(t.id)}}function ps(e,t,r,n){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}let pl=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function pu(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,n]of pl)void 0!==e[r]&&t.push(n);return t}(t);return 0===r.length?null:dG("INVALID_ARGS",`${e} @ref does not support ${r.join(", ")}.`)}async function pd(e,t){let r=await pc(e);if(r)throw new k("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}async function pc(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let r=await Z(e.device),n=r.package?.trim();return n&&n!==e.appBundleId&&("com.android.settings"===(t=n)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:n,activity:r.activity,hint:"com.google.android.permissioncontroller"===n?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function pp(e,t){let r=Array.isArray(e.selectorChain)?e.selectorChain:void 0,n=pw(e),a=n?.kind==="ref"?pg(n.ref):void 0,i=n?.kind==="selector"?n.selector:void 0,o={...a?{ref:a}:{},...i?{selector:i}:{},...r?{selectorChain:r}:{}};if("attrs"===t)return o;let s="string"==typeof e.text?e.text:"";return{...o,text:s,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(s)}}function pf(e){let t=pw(e);return{...t?.kind==="ref"?{ref:pg(t.ref)}:{},...t?.kind==="selector"?{selector:t.selector}:{},..."string"==typeof e.text?{text:e.text}:{},...e.node&&"object"==typeof e.node?{node:e.node}:{}}}function pm(e){let{selectorChain:t,...r}=e;return r}function ph(e,t,r,n){let a=e.get(t);a&&e.recordAction(a,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:n})}function pw(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function pg(e){return e.startsWith("@")?e.slice(1):e}function py(e,t={}){return{artifacts:function(e,t={}){let r=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new k("UNSUPPORTED_OPERATION",`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new k("UNSUPPORTED_OPERATION",`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new k("UNSUPPORTED_OPERATION",`${e} ${r} not create temporary files`)}}}(e,t),policy:tI()}}let pv=["application","window","tabbar","scrollbar","image"],pI=new Set(["tab bar"]);async function pA(e,t){var r;if(t.ok||(r=t.error.message,!/^wait timed out for (?:selector|text): /i.test(r)))return t;let n=await pS(e).catch(()=>null);return n?dG(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}async function pS(e){let t=[...(await cd({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0,snapshotCompact:!0},logPath:e.logPath??""})).snapshot.nodes].sort(p_),r=pb(t,6,{includeIdentifiers:!0});if(0===r.length)return null;let n=pb(t.filter(e=>!pM(e)),4,{includeIdentifiers:!1}),a=pb(t.filter(pD),4,{includeIdentifiers:!0});return{summary:(n.length>0?n:r.slice(0,4)).join(", "),details:{labels:r,...a.length>0?{buttons:a}:{}}}}function pb(e,t,r){let n=new Set,a=[];for(let i of e){let e=px(i,r);if(!(!e||n.has(e))&&(n.add(e),a.push(e),a.length>=t))break}return a}function p_(e,t){var r,n;return pN(e)-pN(t)||(r=e,n=t,r.rect&&n.rect?r.rect.y-n.rect.y||r.rect.x-n.rect.x:r.rect?-1:n.rect?1:(r.depth??0)-(n.depth??0)||r.index-n.index)}function pN(e){let t=!!px(e,{includeIdentifiers:!1});return 2*!!pM(e)+ +!t}function px(e,t){let r=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>"string"==typeof e?e.trim():"").find(e=>e.length>0);return r?r.replace(/\s+/g," ").slice(0,80):""}function pM(e){let t=tq(`${e.type??""} ${e.role??""} ${e.subrole??""}`),r=`${e.label??""} ${e.value??""}`.trim().toLowerCase();return pv.some(e=>t.includes(e))||pI.has(r)||r.endsWith(".fill")}function pD(e){return tq(`${e.type??""} ${e.role??""} ${e.subrole??""}`).includes("button")}function pk(e){var t;let{session:r,selectorExpression:n}=e;if(!r||"ios"!==r.device.platform||r.postGestureStabilization)return null;let a=tF(n);if(!a||1!==a.selectors.length)return null;let i=a.selectors[0];if(!i||1!==i.terms.length)return null;let o=i.terms[0];return o&&"string"==typeof o.value&&("id"===(t=o.key)||"label"===t||"text"===t||"value"===t)?{key:o.key,value:o.value,raw:i.raw}:null}function pE(e){let t=M(e);if("COMMAND_FAILED"!==t.code)return!1;let r=t.message.toLowerCase();return r.includes("fetch failed")||r.includes("timed out")||r.includes("timeout")||r.includes("runner did not accept connection")||r.includes("invalid runner response")}async function pO(e){var t;let{req:r}=e;if("find"!==r.command)return null;let n=r.positionals??[];if(0===n.length)return dG("INVALID_ARGS","find requires a locator or text");let a=tz(n);if(!a.query)return dG("INVALID_ARGS","find requires a value");if(r.flags?.findFirst&&r.flags?.findLast)return dG("INVALID_ARGS","find accepts only one of --first or --last");let i=a.action;if("exists"!==(t=i)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let o=await pB(e,{requireSession:!1,capability:"find"});return o.ok?await pW(async()=>{let t=await o.runtime.selectors.find({session:e.sessionName,requestId:r.meta?.requestId,locator:a.locator,query:a.query,action:i,timeoutMs:a.timeoutMs});return ph(e.sessionStore,e.sessionName,r,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let r="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:r,action:"get attrs"}:{ref:r,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,i)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):o.response}async function pP(e){let{req:t}=e;if("get"!==t.command)return null;let r=t.positionals?.[0];if("text"!==r&&"attrs"!==r)return dG("INVALID_ARGS","get only supports text or attrs");let n=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let r=e.positionals?.slice(1).join(" ").trim()??"";return r?{ok:!0,target:{kind:"selector",selector:r}}:{ok:!1,response:dG("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!n.ok)return n.response;if("ref"===n.target.kind){let e=pu("get",t.flags);if(e)return e}if("selector"===n.target.kind){let t=await pR(e,r,n.target.selector);if(t)return t}let a=await pB(e,{requireSession:!0,capability:"get"});return a.ok?await pW(async()=>{let i=await a.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:n.target});return ph(e.sessionStore,e.sessionName,t,pp(i,r)),pf(i)}):a.response}async function pC(e){let{req:t}=e;if("is"!==t.command)return null;let r=(t.positionals?.[0]??"").toLowerCase();if(!tl(r))return dG("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:n}=tV(t.positionals??[]);if(!n)return dG("INVALID_ARGS","is requires a selector expression");let a=n.rest.join(" ").trim();if("text"===r&&!a)return dG("INVALID_ARGS","is text requires expected text value");if("text"!==r&&n.rest.length>0)return dG("INVALID_ARGS",`is ${r} does not accept trailing values`);let i=await pT(e,r,n.selectorExpression,a);if(i)return i;let o=await pB(e,{requireSession:!0,capability:"is"});if(!o.ok)return o.response;let s=await pW(async()=>{let i=await o.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:n.selectorExpression,expectedText:a});return ph(e.sessionStore,e.sessionName,t,i),pm(i)});return await pz(e,s,`is ${r}`)}async function pL(e){let{req:t,sessionName:r,sessionStore:n}=e,a=eq(t.positionals??[]);if(!a)return dG("INVALID_ARGS","wait requires a duration or text");let{session:i,device:o}=await pi(n,r,t.flags);if("sleep"!==a.kind&&!d7("wait",o))return dG("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===a.kind){let t=await p$({...e,session:i,device:o,selectorExpression:a.selectorExpression,timeoutMs:a.timeoutMs});if(t)return t}let s=async()=>{let s=pj({...e,session:i,device:o}),l=await pW(async()=>{let e=await s.selectors.wait({session:r,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new k("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new k("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(a,i)});return ph(n,r,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}}),u=await pA({req:t,logPath:e.logPath,session:i,device:o},l);return await pz(e,u,"wait")};return"sleep"===a.kind?await s():await po(i,o,s)}async function pR(e,t,r){let n=await pF(e,r);if(pV(n))return n.response;if(!n)return null;let a=function(e,t,r){if(!r.found||!r.node)return null;let n={target:{kind:"selector",selector:t},node:r.node,selectorChain:[t]};return"attrs"===e?{kind:"attrs",...n}:"string"!=typeof r.text?null:{kind:"text",...n,text:r.text}}(t,n.selector.raw,n.result);return a?(ph(e.sessionStore,e.sessionName,e.req,pp(a,t)),{ok:!0,data:pf(a)}):null}async function pT(e,t,r,n){var a,i,o,s,l;let u;if("hidden"===t)return null;let d=await pF(e,r);if(pV(d))return d.response;if(!d?.result.found||!d.result.node)return null;let c="exists"===t?{predicate:t,pass:!0,selector:d.selector.raw,matches:1,selectorChain:[d.selector.raw]}:(a=t,i=n,o=d.selector.raw,s=d.session,u=ty({predicate:a,node:l=d.result.node,nodes:[l],expectedText:i,platform:s.device.platform}),{predicate:a,pass:u.pass,selector:o,..."text"===a?{text:u.actualText}:{},selectorChain:[o]});return c?(ph(e.sessionStore,e.sessionName,e.req,c),{ok:!0,data:pm(c)}):null}async function p$(e){let t=pk({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let r=Date.now(),n=await pG(e,e.session,t);if(pV(n))return n.response;if(!n?.found)return null;let a={kind:"selector",selector:t.raw,waitedMs:Date.now()-r,selectorChain:[t.raw]};return ph(e.sessionStore,e.sessionName,e.req,a),await pA({req:e.req,logPath:e.logPath,session:e.session,device:e.device},{ok:!0,data:a})}async function pF(e,t){let r=e.sessionStore.get(e.sessionName),n=pk({session:r,selectorExpression:t});if(!r||!n)return null;let a=await pG(e,r,n);return pV(a)?a:a?{session:r,selector:n,result:a}:null}async function pU(e,t,r){let n=await at(t.device,{command:"querySelector",selectorKey:r.key,selectorValue:r.value,appBundleId:t.appBundleId},{verbose:!!e.req.flags?.verbose,logPath:e.logPath,traceLogPath:t.trace?.outPath,requestId:e.req.meta?.requestId}),a=!0===n.found,i=function(e){let t=e.nodes;if(!Array.isArray(t))return;let r=t[0];if(r&&"object"==typeof r)return r}(n);return{found:a,..."string"==typeof n.text?{text:n.text}:{},...i?{node:i}:{}}}async function pG(e,t,r){try{return await pU(e,t,r)}catch(e){if(pE(e))return null;return{kind:"error",response:{ok:!1,error:D(e)}}}}function pV(e){return null!==e&&"kind"in e&&"error"===e.kind}function pj(e){return tg({backend:function(e){let t,{req:r,session:n,device:a,logPath:i,sessionName:o,sessionStore:s}=e,l=0;return{platform:a.platform,captureSnapshot:async(e,u)=>{var d;let c,p={...r.flags,...(d=u,c={},d?.interactiveOnly!==void 0&&(c.snapshotInteractiveOnly=d.interactiveOnly),d?.compact!==void 0&&(c.snapshotCompact=d.compact),d?.scope!==void 0&&(c.snapshotScope=d.scope),d?.depth!==void 0&&(c.snapshotDepth=d.depth),d?.raw!==void 0&&(c.snapshotRaw=d.raw),c)},f=u?.scope??r.flags?.snapshotScope,m=Date.now(),h=tk(tx(p)),w="wait"===r.command||"find"===r.command;if(!w&&t&&m-l<750&&!cr(n)&&!n?.postGestureStabilization)return t;if(!w&&n?.snapshot&&m-n.snapshot.createdAt<750&&n.snapshot.presentationKey===h&&!cr(n)&&!n.postGestureStabilization)return l=n.snapshot.createdAt,t={snapshot:n.snapshot};let g=await cd({device:a,session:n,flags:p,outPath:r.flags?.out,logPath:i??"",snapshotScope:f});return n&&(cI(n,g.snapshot),s.set(o,n)),l=m,t={snapshot:g.snapshot}},readText:async(t,o)=>({text:await pa({device:a,node:o,flags:r.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,r)=>co(i??"",e,t,r))})}),findText:async(t,r)=>({found:await pq(e,r)})}}(e),...py("selector commands",{plural:!0}),sessions:cA({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{e.session&&t.snapshot&&(cI(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}})})}async function pB(e,t){let r=e.sessionStore.get(e.sessionName);if(!r&&t.requireSession)return{ok:!1,response:dG("SESSION_NOT_FOUND","No active session. Run open first.")};let n=r?.device??await op(e.req.flags??{});return(r||await oY(n),d7(t.capability,n))?{ok:!0,runtime:pj({...e,session:r,device:n})}:{ok:!1,response:dG("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function pq(e,t){let{device:r,session:n,req:a,logPath:i}=e;if("macos"===r.platform&&n?.surface&&"app"!==n.surface)return!!tU((await pH(e)).nodes,t);if(rX(r.platform)&&n?.appBundleId){let e=await at(r,{command:"findText",text:t,appBundleId:n?.appBundleId},{verbose:a.flags?.verbose,logPath:i,traceLogPath:n?.trace?.outPath,requestId:a.meta?.requestId});return e?.found===!0}return!!tU((await pH(e)).nodes,t)}async function pH(e){let t=await cd({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:e.req.flags?.out,logPath:e.logPath??""});return e.session&&(cI(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session)),t.snapshot}async function pW(e){try{return{ok:!0,data:await e()}}catch(t){let e=M(t);return dG(e.code,e.message,e.details)}}async function pz(e,t,r){var n;let a;if(t.ok)return t;let i=e.sessionStore.get(e.sessionName);if(!i)return t;try{a=await pc(i)}catch{return t}return a?dG(t.error.code,`${r} failed because ${"com.google.android.permissioncontroller"===(n=a).foregroundPackage?`Android permission dialog is blocking ${n.expectedPackage}`:`${n.foregroundPackage} is foreground instead of ${n.expectedPackage}`}.`,{...t.error.details??{},...a,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}async function pK(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return dG("INVALID_ARGS","find requires a locator or text");let{locator:l,query:u,action:d,value:c,timeoutMs:p}=tz(s);if(!u)return dG("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return dG("INVALID_ARGS","find accepts only one of --first or --last");let f=await pO({req:t,sessionName:r,logPath:n,sessionStore:a});if(f)return f;let m=a.get(r);if(!m&&"exists"!==d&&"wait"!==d&&"get_text"!==d&&"get_attrs"!==d)return dG("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await op(t.flags??{});m||await oY(h);let w="role"!==l?u:void 0,g="click"===d||"focus"===d||"fill"===d||"type"===d,y=0,v=null,I=async()=>{let e=Date.now();if(v&&e-y<750&&!cr(m))return{nodes:v};let{snapshot:i}=await cd({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:g,snapshotCompact:g},outPath:t.flags?.out,logPath:n,snapshotScope:w}),o=i.nodes;return y=e,v=o,m&&(cI(m,i),a.set(r,m)),{nodes:o,truncated:i.truncated,backend:i.backend}},A={req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i,session:m,device:h,command:o,locator:l,query:u};if("wait"===d)return pJ(A,I,l,u,p);let{nodes:S}=await I(),b=tW(S,l,u,{requireRect:g});if(g&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,x;let e;return _=b.matches,N=l,x=u,e=_.slice(0,8).map(e=>{let t=tT(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),dG("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${x}". Use a more specific locator or selector.`,{locator:N,query:x,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let M=b.matches[0]??null;if(!M)return dG("COMMAND_FAILED","find did not match any element");let D="click"===d||"focus"===d||"fill"===d||"type"===d?tR(S,M)??M:M,k=`@${D.ref}`,E={node:M,resolvedNode:D,ref:k,nodes:S,actionFlags:{...t.flags??{},noRecord:!0}},O={exists:()=>pX(A),get_text:()=>pY(A,E),get_attrs:()=>pZ(A,E),click:()=>pQ(A,E),fill:()=>p0(A,E,c),focus:()=>p1(A,E),type:()=>p2(A,E,c)}[d];return O?O():null}async function pJ(e,t,r,n,a){let{req:i,sessionStore:o,session:s,command:l}=e,u=a??1e4,d=Date.now();for(;Date.now()-d<u;){let{nodes:e}=await t();if(tW(e,r,n,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:i.positionals??[],flags:i.flags??{},result:{found:!0,waitedMs:Date.now()-d}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-d}};await ef(300)}return dG("COMMAND_FAILED","find wait timed out")}async function pX(e){let{req:t,sessionStore:r,session:n,command:a}=e;return n&&r.recordAction(n,{command:a,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function pY(e,t){let{req:r,sessionStore:n,session:a,command:i,device:o,logPath:s}=e,l=await pa({device:o,node:t.node,flags:r.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(e,t,r)=>co(s,e,t,r)});return a&&n.recordAction(a,{command:i,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get text",text:l}}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function pZ(e,t){let{req:r,sessionStore:n,session:a,command:i}=e;return a&&n.recordAction(a,{command:i,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function pQ(e,t){let{req:r,sessionName:n,sessionStore:a,session:i,invoke:o,command:s,locator:l,query:u}=e,d=await o({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let c=t.resolvedNode.rect?tE(t.resolvedNode.rect):null,p={ref:t.ref,locator:l,query:u};return c&&(p.x=c.x,p.y=c.y),i&&a.recordAction(i,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:u}}),{ok:!0,data:p}}async function p0(e,t,r){let{req:n,sessionName:a,sessionStore:i,session:o,invoke:s,command:l}=e;if(!r)return dG("INVALID_ARGS","find fill requires text");let u=await s({token:n.token,session:a,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return u.ok&&o&&i.recordAction(o,{command:l,positionals:n.positionals??[],flags:n.flags??{},result:{ref:t.ref,action:"fill"}}),u}async function p1(e,t){let{req:r,sessionStore:n,session:a,device:i,command:o,logPath:s}=e,l=t.node.rect?tE(t.node.rect):null;if(!l)return dG("COMMAND_FAILED","matched element has no bounds");let u=await dC(i,"focus",[String(l.x),String(l.y)],r.flags?.out,{...co(s,r.flags,a?.appBundleId,a?.trace?.outPath)});return a&&n.recordAction(a,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:u??{ref:t.ref}}}async function p2(e,t,r){let{req:n,sessionStore:a,session:i,device:o,command:s,logPath:l}=e;if(!r)return dG("INVALID_ARGS","find type requires text");let u=t.node.rect?tE(t.node.rect):null;if(!u)return dG("COMMAND_FAILED","matched element has no bounds");await dC(o,"focus",[String(u.x),String(u.y)],n.flags?.out,{...co(l,n.flags,i?.appBundleId,i?.trace?.outPath)});let d=await dC(o,"type",[r],n.flags?.out,{...co(l,n.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:s,positionals:n.positionals??[],flags:n.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:d??{ref:t.ref}}}function p3(e){var t,r,n;let a,i,{data:o,fallbackX:s,fallbackY:l,referenceFrame:u,extra:d}=e,c=(t=d,r=s,n=l,a="string"==typeof t?.ref?t.ref:void 0,i="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:a?i&&"primary"!==i?`Clicked ${i} @${a} (${r}, ${n})`:`Tapped @${a} (${r}, ${n})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...u??{},...d??{},...o??{},...eG(c)}}function p5(e){let{session:t,sessionStore:r,command:n,positionals:a,flags:i,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:u,androidFreshnessBaseline:d}=e;return r.recordAction(t,{command:n,positionals:a,flags:i??{},result:o}),ca(n)&&ct(t,n,d??t.snapshot),c3(t,n,a,o,i??{},l,u),{ok:!0,data:s}}async function p4(e){let{session:t,flags:r,sessionStore:n,contextFromFlags:a,captureSnapshotForSession:i}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await sC(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=c0(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=c0(await i(t,r,n,a,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function p8(e){try{return await p4(e)}catch(t){eM({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function p6(e){return c0({nodes:e,createdAt:0})}function p9(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:dG("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 p7(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new k("SESSION_NOT_FOUND","No active session. Run open first.");return tg({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(n,a)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:a?.interactiveOnly===!0})}),tap:async(n,a)=>fe(await dC(r.device,"press",[String(a.x),String(a.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(n,a,i)=>fe(await dC(r.device,"fill",[String(a.x),String(a.y),i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(n,a)=>fe(await dC(r.device,"type",[a],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),...py("interaction commands",{plural:!0}),sessions:cA({sessionName:e.sessionName,getSession:()=>t,recordOptions:{includeSnapshot:!0},setRecord:r=>{r.snapshot&&(cI(t,r.snapshot),e.sessionStore.set(e.sessionName,t))}})})}function fe(e){return e&&"object"==typeof e?e:void 0}function ft(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function fr(e){return"ref"===e.kind?{ref:fn(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 fn(e){return e?.startsWith("@")?e.slice(1):e}async function fa(e){switch(e.req.command){case"press":case"click":return await fi(e);case"fill":return await fs(e);default:return null}}async function fi(e){let t,{req:r,sessionName:n,sessionStore:a}=e,i=a.get(n),o="click"===r.command?"click":"press";if(!i)return dG("SESSION_NOT_FOUND","No active session. Run open first.");let s=p9(i,o);if(s)return s;if(!d7("press",i.device))return dG("UNSUPPORTED_OPERATION","press is not supported on this device");let l=di(r.flags),u="primary"===l?{}:{button:l};if("primary"!==l){let e=ds({commandLabel:o,platform:i.device.platform,button:l,count:r.flags?.count,intervalMs:r.flags?.intervalMs,holdMs:r.flags?.holdMs,jitterPx:r.flags?.jitterPx,doubleTap:r.flags?.doubleTap});if(e)return dG(e.code,e.message,e.details)}let d=function(e,t){let r=ft(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let n=e[0]??"";if(n.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:n,fallbackLabel:e1.decode(e).label??""}};let a=e.join(" ").trim();return a?{ok:!0,target:{kind:"selector",selector:a}}:{ok:!1,response:dG("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(r.positionals??[],o);if(!d.ok)return d.response;if("ref"===d.target.kind){let n=e.refSnapshotFlagGuardResponse("press",r.flags);if(n)return n;t=await fu(e,i)}let c=function(e){var t;let{session:r,commandLabel:n,target:a,flags:i}=e;return"click"!==n||"selector"!==a.kind||(t=i,t?.count!==void 0||t?.intervalMs!==void 0||t?.holdMs!==void 0||t?.jitterPx!==void 0||t?.doubleTap!==void 0||t?.clickButton!==void 0&&"primary"!==t.clickButton)?null:pk({session:r,selectorExpression:a.selector})}({session:i,commandLabel:o,target:d.target,flags:r.flags});if(c){let t=await fo(e,i,c);if(t)return t}return await fl(e,{androidFreshnessBaseline:t,run:async e=>{let t={session:n,requestId:r.meta?.requestId,button:l,count:r.flags?.count,intervalMs:r.flags?.intervalMs,holdMs:r.flags?.holdMs,jitterPx:r.flags?.jitterPx,doubleTap:r.flags?.doubleTap};return"click"===o?await e.interactions.click(d.target,t):await e.interactions.press(d.target,t)},afterRun:async e=>{var t;await pd(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 t=>{let n="point"===t.kind?await p8({session:i,flags:r.flags,sessionStore:a,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):p6(i.snapshot?.nodes??[]),o=p3({data:t.backendResult,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:{...fr(t),...u}});return{result:o,responseData:o}}})}async function fo(e,t,r){let n=Date.now();try{var a,i;let o,s,l=await dC(t.device,"press",[],e.req.flags?.out,{...e.contextFromFlags(e.req.flags,t.appBundleId,t.trace?.outPath),directElementSelector:r,surface:t.surface})??{},u=Date.now(),d=(a=l,o="number"==typeof a.x?a.x:void 0,s="number"==typeof a.y?a.y:void 0,void 0!==o&&void 0!==s?{x:o,y:s}:{x:0,y:0}),c=p3({data:l,fallbackX:d.x,fallbackY:d.y,referenceFrame:(i=l,"number"==typeof i.referenceWidth&&"number"==typeof i.referenceHeight?{referenceWidth:i.referenceWidth,referenceHeight:i.referenceHeight}:void 0),extra:{selector:r.raw}});return p5({session:t,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:c,responseData:c,actionStartedAt:n,actionFinishedAt:u})}catch(e){if(!pE(e))return{ok:!1,error:D(e)};return eM({level:"debug",phase:"ios_direct_selector_tap_fallback",data:{selector:r.raw,error:e instanceof Error?e.message:String(e)}}),null}}async function fs(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(a){let e=p9(a,"fill");if(e)return e}if(a&&!d7("fill",a.device))return dG("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!a)return dG("SESSION_NOT_FOUND","No active session. Run open first.");let i=function(e){let t=e[0]??"";if(t.startsWith("@")){var r;let n=eQ.decode(e).text;return n?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:(r=e).length>=3&&r[1]?.trim()||""},text:n}:{ok:!1,response:dG("INVALID_ARGS","fill requires text after ref")}}let n=ft(e);if(n){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:n.x,y:n.y},text:t}:{ok:!1,response:dG("INVALID_ARGS","fill requires text after coordinates")}}let a=eQ.decode(e);if("selector"!==a.kind)return{ok:!1,response:dG("INVALID_ARGS","fill requires x y text, @ref text, or selector text")};let i=a.text.trim();return i?{ok:!0,target:{kind:"selector",selector:a.target.selector},text:i}:{ok:!1,response:dG("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!i.ok)return i.response;if("ref"===i.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await fu(e,a)}return await fl(e,{run:async e=>await e.interactions.fill(i.target,i.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:p6(a.snapshot?.nodes??[]),r=p3({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...fr(e),text:i.text}});e.warning&&(r.warning=e.warning);let n="ref"===e.kind?{...e.backendResult??{ref:fn(e.target?.kind==="ref"?e.target.ref:void 0),x:e.point.x,y:e.point.y}}:r;return e.warning&&(n.warning=e.warning),{result:r,responseData:n}}})}async function fl(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return dG("SESSION_NOT_FOUND","No active session. Run open first.");let n=p7(e),a=Date.now();try{let i=await t.run(n);await t.afterRun?.(i);let o=Date.now(),{result:s,responseData:l}=await t.buildPayloads(i);return p5({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:a,actionFinishedAt:o,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=M(t);if("COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage)throw e;return{ok:!1,error:D(t)}}}async function fu(e,t){if(!cr(t))return;let r=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:"ref-refresh"})}catch(t){eM({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}async function fd(e,t,r,n,a){let i={...t??{},snapshotInteractiveOnly:a.interactiveOnly,snapshotCompact:a.interactiveOnly},o=n(i,e.appBundleId,e.trace?.outPath),{snapshot:s}=await cd({device:e.device,session:e,flags:i,outPath:i.out,logPath:o.logPath??"",androidFreshnessMode:a.androidFreshnessMode});return cI(e,s),r.set(e.name,e),s}async function fc(e){let t=await fa({...e,captureSnapshotForSession:fd,refSnapshotFlagGuardResponse:pu});if(t)return t;switch(e.req.command){case eJ.name:return await fp({...e,captureSnapshotForSession:fd});case"get":return await pP(e);case"is":return await pC(e);default:return null}}async function fp(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return dG("SESSION_NOT_FOUND","No active session. Run open first.");if(!d7(eJ.name,a.device))return dG("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===a.device.platform&&a.recording&&"failed"===await cx({session:a}))return dG("COMMAND_FAILED","Android system dialog blocked the recording session");let i=(t.positionals??[]).join(" "),o=p7(e),s=Date.now();try{let e=await o.interactions.typeText(i,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),u={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...eG(e.message??`Typed ${Array.from(e.text).length} chars`)};return p5({session:a,sessionStore:n,command:t.command,positionals:t.positionals??[],flags:t.flags,result:u,responseData:u,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:D(e)}}}function ff(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 fm(e){let{req:t,leaseRegistry:r}=e,n=ff(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:n.tenantId??"",runId:n.runId??"",backend:n.leaseBackend,ttlMs:n.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:n.leaseId??"",tenantId:n.tenantId,runId:n.runId,ttlMs:n.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:n.leaseId??"",tenantId:n.tenantId,runId:n.runId})};default:return null}}let fh=`
14
32
  import Foundation
15
33
  import AVFoundation
16
34
 
@@ -34,13 +52,23 @@ Task {
34
52
 
35
53
  semaphore.wait()
36
54
  exit(exitCode)
37
- `.trim();async function su(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,s=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((s+=1)>=2)return}else s=0;r=t,await Z(a)}}async function sc(e){try{var t,r;let a,i=await Q("swift",["-",e],{stdin:sd,allowFailure:!0,timeoutMs:1e4});if(0===i.exitCode)return!0;if(t=i.stderr,r=i.stdout,a=`${t}
38
- ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return sp(e);return!1}catch(t){if(t instanceof J&&"TOOL_MISSING"===t.code)return sp(e);throw t}}async function sf(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await sc(e))return;await Z(r)}}function sp(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),s=e.toString("latin1",4,8);if(a.push(s),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 sm(e){let t=s.parse(e);return s.join(t.dir,`${t.name}.gesture-telemetry.json`)}function sh(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function sg(e){let t=s.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),s.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),s.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),s.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new J("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 sw(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await su(t),await sf(t);let o=i.mkdtempSync(s.join(c.tmpdir(),"agent-device-record-overlay-")),l=s.join(o,`input${s.extname(t)||".mp4"}`),d=s.join(o,s.basename(t)),u=s.join(o,"home"),f=s.join(o,"module-cache");i.copyFileSync(t,l),i.mkdirSync(u,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await Q("xcrun",["swift",r,"--input",l,"--output",d,...a],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await sf(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof J?a:new J("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new J("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(o,{recursive:!0,force:!0})}}async function sy(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await sw({videoPath:r,scriptPath:t??=sg("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function sv(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await sw({videoPath:r,scriptPath:e??=sg("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function sS(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await sw({videoPath:t,scriptPath:r??=sg("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function sI(e){return e instanceof Error?e.message:String(e)}function sA(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function sb(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:n}=e,s=function(e){var t,r,a;let n,s,{recording:o,trimStartMs:l}=e,d=(n=sm((t={videoPath:o.outPath,events:o.gestureEvents,trimStartMs:l}).videoPath),s={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?sh(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)}]})):sh(r))},i.writeFileSync(n,JSON.stringify(s,null,2)),n);return o.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:s,targetLabel:n})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${sI(e)}`}}}async function s_(e,t,r){return await E(O(e),t,r)}async function sN(e,t){let r=await s_(e,["shell","ps","-o","pid=","-p",t],{allowFailure:!0});return 0===r.exitCode&&r.stdout.split(/\s+/).map(e=>e.trim()).includes(t)}async function sM(e,t){for(let r=0;r<40;r+=1){if(!await sN(e,t))return!0;await Z(250)}return!await sN(e,t)}async function sx(e,t){let r,a=0;for(let i=0;i<20;i+=1){let i=await s_(e,["shell","stat","-c","%s",t],{allowFailure:!0}),n=0===i.exitCode?i.stdout.trim():"";if(n.length>0&&n===r){if((a+=1)>=4)return}else a=0;r=n,await Z(250)}}async function sD(e,t,r){for(let a=0;a<8;a+=1){let i=await s_(e,["shell","stat","-c","%s",t],{allowFailure:!0}),n=0===i.exitCode?Number(i.stdout.trim()):NaN;if(Number.isFinite(n)&&n>0)return!0;if(!await sN(e,r))break;if(a+1>=2)return!0;await Z(250)}return!1}async function sk(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:s}=e;for(let e=0;e<2;e+=1){try{i.rmSync(s,{force:!0})}catch{}let o=O(a),l=await P(n,s,{allowFailure:!0,device:o});if(0!==l.exitCode)t=sA(l,"adb pull");else{await r.waitForStableFile(s,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(s);if(b({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:s,attempt:e+1,fileSize:(()=>{try{return i.statSync(s).size}catch{return 0}})(),playable:t}}),t)return;b({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:s,attempt:e+1}})}e<1&&await Z(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 sP(e){let{deviceId:t,quality:r}=e;if(void 0===r||r>=10)return;let a=await s_(t,["shell","wm","size"],{allowFailure:!0}),i=a.stdout.match(/Override size:\s*(\d+)x(\d+)/)??a.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==a.exitCode||!i)throw Error(`failed to resolve Android screen size for recording quality: ${sA(a,"adb shell wm size")}`);return{width:sR(Number(i[1]),r),height:sR(Number(i[2]),r)}}function sR(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function sL(e,t){await s_(e,["shell","rm","-f",t],{allowFailure:!0})}async function sO(e,t){let r=await s_(e,["shell","kill","-9",t],{allowFailure:!0});return b({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:e,remotePid:t,exitCode:r.exitCode,stdout:r.stdout.trim(),stderr:r.stderr.trim()}}),!(0!==r.exitCode&&await sN(e,t))&&await sM(e,t)}async function sE(e){var t;let r,a,{device:i,recordingBase:n}=e,s="failed to start recording: Android screenrecord did not begin producing frames";try{r=await sP({deviceId:i.id,quality:n.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 s_(i.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: ${sA(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 sL(i.id,e);continue}if(b({level:"debug",phase:"record_start_android_started",data:{deviceId:i.id,remotePath:e,remotePid:a}}),await sD(i.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...n,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await sO(i.id,a),await sL(i.id,e)}return eh("COMMAND_FAILED",s)}async function sC(e){let t,r,{deps:a,device:i,recording:n}=e;b({level:"debug",phase:"record_stop_android_enter",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid}});let s=await s_(i.id,["shell","kill","-2",n.remotePid],{allowFailure:!0});if(b({level:"debug",phase:"record_stop_android_signal",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid,exitCode:s.exitCode,stdout:s.stdout.trim(),stderr:s.stderr.trim()}}),0!==s.exitCode?await sN(i.id,n.remotePid)&&!await sO(i.id,n.remotePid)&&(t=`failed to stop recording: ${sA(s,"adb shell kill")}`):await sM(i.id,n.remotePid)||await sO(i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await sx(i.id,n.remotePath);let e=await sk({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await o(),eh("COMMAND_FAILED",e);await sb({recording:n,deps:a,targetLabel:"Android recording"})}if(await o(),t)return eh("COMMAND_FAILED",t);if(r)return eh("COMMAND_FAILED",r);return null;async function o(){let e=await s_(i.id,["shell","rm","-f",n.remotePath],{allowFailure:!0});b({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: ${sA(e,"adb shell rm")}`)}}function s$(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function sT(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function sF(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,s=s$(r);if(s)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:s,interactiveOnly:!0,compact:!0,depth:1},sT(t,i,r))}catch(e){b({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:s,error:sI(e)}})}}async function sU(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:s,logPath:o,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=sT(a,o,i),h=async()=>l.runIosRunnerCommand(s,{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(!sI(a).toLowerCase().includes("recording already in progress"))return eh("COMMAND_FAILED",`failed to start recording: ${sI(a)}`);b({level:"warn",phase:"record_start_runner_desynced",data:{platform:s.platform,kind:s.kind,deviceId:s.id,session:i.name,error:sI(a)}});let e=(g=s.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(s,{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: ${sI(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function sV(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,fpsFlag:s,recordingBase:o,appBundleId:l}=e;try{await n.runIosRunnerCommand(a,{command:"recordStart",outPath:o.outPath,fps:s,quality:o.quality,appBundleId:l},sT(t,i,r))}catch(e){return eh("COMMAND_FAILED",`failed to start recording: ${sI(e)}`)}return{platform:"macos-runner",...o}}async function sG(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:s}=e,o=s$(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:o},sT(t,i,r))}catch(e){b({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:sI(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",s.remotePath,"--destination",s.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 s.runnerStartedAtUptimeMs||"number"!=typeof s.targetAppReadyUptimeMs?0:Math.max(0,s.targetAppReadyUptimeMs-s.runnerStartedAtUptimeMs);return d>0&&await n.trimRecordingStart({videoPath:s.outPath,trimStartMs:d}),await sb({recording:s,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function sj(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:s}=e,o=s$(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:o},sT(t,i,r))}catch(e){b({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:sI(e)}})}return await sb({recording:s,deps:n,targetLabel:"macOS recording"}),null}async function sq(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 Z(250)}return Date.now()}async function sH(e){let t,r,{req:a,activeSession:i,device:n,logPath:s,deps:o,recordingBase:l,resolvedOut:d}=e;await sF({req:a,activeSession:i,device:n,logPath:s,deps:o});let{child:u,wait:c}=o.runCmdBackground("xcrun",eW(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await sq(d);try{let e=Date.now(),l=await o.runIosRunnerCommand(n,{command:"uptime",appBundleId:s$(i)},{verbose:a.flags?.verbose,logPath:s,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 sB(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:o,device:l,logPath:d,deps:u}=e;if(o.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(!e0("record",l))return eh("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tz.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(s.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=s$(o);if(!e)return eh("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await sU({req:r,activeSession:o,sessionStore:n,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=s$(o);if(!e)return eh("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await sV({req:r,activeSession:o,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await sH({req:r,activeSession:o,device:l,logPath:d,deps:u,recordingBase:h,resolvedOut:m}):await sE({device:l,recordingBase:h});return"ok"in t?t:(o.recording=t,n.set(a,o),n.recordAction(o,{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 sK(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await sC({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: ${sA(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: ${sI(e)}`}return await sb({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function sz(e){var t;let r,{req:a,activeSession:i,device:n,logPath:o,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 sG({req:a,activeSession:i,device:n,logPath:o,deps:l,recording:d}):"macos-runner"===d.platform?await sj({req:a,activeSession:i,device:n,logPath:o,deps:l,recording:d}):await sK({deps:l,device:n,recording:d});return c||(u?eh("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:s.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return sm(e.clientOutPath)}(t),fileName:s.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function sW(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:Q,runCmdBackground:Y,runIosRunnerCommand:eH,waitForStableFile:su,isPlayableVideo:sc,trimRecordingStart:sy,resizeRecording:sS,overlayRecordingTouches:sv},s=a.get(r),o=s?.device??await ey(t.flags??{});s||await eB(o);let l=s??{name:r,device:o,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 sB({req:t,sessionName:r,sessionStore:a,activeSession:l,device:o,logPath:i,deps:n});let u=await sz({req:t,activeSession:l,device:o,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 sJ(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,o=t.command;if("record"===o)return sW({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===o){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=tz.expandHome(e);return i.mkdirSync(s.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:o,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=tz.expandHome(t.positionals[1]);i.mkdirSync(s.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:o,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function sZ(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 sX=new WeakMap;function sY(e){if(!e)return;let t=sX.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)&&sQ(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(sQ);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 sX.set(e,r),r}function sQ(e){return!!e&&e.width>0&&e.height>0}let s0={referenceWidth:1e3,referenceHeight:1e3};function s1(e,t,r,a,i={},n=Date.now(),s=Date.now()){var o,l,d;let u,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=s5(p.effectiveDurationMs)??s5(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:s5(p.gestureStartUptimeMs),gestureEndUptimeMs:s5(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:s},g="number"==typeof(o={gestureStartUptimeMs:s5(p.gestureStartUptimeMs),gestureEndUptimeMs:s5(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,fallbackFinishedAtMs:s}).gestureStartUptimeMs&&"number"==typeof o.gestureEndUptimeMs?Math.max(0,o.gestureEndUptimeMs-o.gestureStartUptimeMs):"number"==typeof o.reportedDurationMs?Math.max(0,o.reportedDurationMs):Math.max(0,o.fallbackFinishedAtMs-o.fallbackStartedAtMs),w="ios"===e.device.platform&&void 0===s5(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=s4(s5(t.count),1)??1,r=!0===t.doubleTap,a=s4(s5(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 sZ(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):sZ(h),y=(l=e.snapshot,u=s5((d=p).referenceWidth),c=s5(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:sY(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=s6(t,e);if(!i)return[];let{x:n,y:s}=i,o=s4(s5(t.count),1)??1,l=s4(s5(t.intervalMs),0)??0,d=!0===t.doubleTap,u=s4(s5(t.holdMs),1),c=[];for(let e=0;e<o;e+=1){let t=r+e*l;if(void 0!==u&&u>0){c.push(s8(t,n,s,u,a));continue}c.push(s2(t,n,s,a)),d&&c.push(s2(t+90,n,s,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=s6(t,e);if(!i)return[];let{x:n,y:s}=i;return[s2(r,n,s,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=s6(t,e);if(!n)return[];let{x:s,y:o}=n;return[s8(r,s,o,s7(a,[s5(t.durationMs),s5(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=s9(t,e),s=s3(t.contentDirection)??s3(t.direction);if(!n||!s)return[];let{x1:o,y1:l,x2:d,y2:u}=n,c=s7(a,[],250),f=s5(t.amount)??s5(e[1]),p=s5(t.pixels);return[{kind:"scroll",tMs:r,x:o,y:l,x2:d,y2:u,...i,durationMs:c,contentDirection:s,...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=s9(t,e);if(!n)return[];let{x1:s,y1:o,x2:l,y2:d}=n,u=s7(a,[s5(t.effectiveDurationMs),s5(t.durationMs),s5(e[4])],250),c=s4(s5(t.count),1)??1,f=s4(s5(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:s,n=t?d:o,c=t?s:l,h=t?o: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=s6(t,e,1),s=s5(t.scale)??s5(e[0]);if(!n||void 0===s||s<=0)return[];let{x:o,y:l}=n;return[{kind:"pinch",tMs:r,x:o,y:l,...i,scale:s,durationMs:s7(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),b({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 s2(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function s8(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function s3(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 s5(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 s4(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function s6(e,t,r=0){let a=s5(e.x)??s5(t[r]),i=s5(e.y)??s5(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function s9(e,t){let r=s5(e.x1)??s5(t[0]),a=s5(e.y1)??s5(t[1]),i=s5(e.x2)??s5(t[2]),n=s5(e.y2)??s5(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 s7(e,t,r){return s4(e,1)??t.map(e=>s4(e,1)).find(e=>void 0!==e)??r}function oe(e){var t,r,a;let i,n,{data:s,fallbackX:o,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=o,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 s?.message?s.message:void 0));return{x:o,y:l,...d??{},...u??{},...s??{},...ti(c)}}function ot(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:s,responseData:o,actionStartedAt:l,actionFinishedAt:d,androidFreshnessBaseline:u}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:s}),ep(a)&&e9(t,a,u??t.snapshot),s1(t,a,i,s,n??{},l,d),{ok:!0,data:o}}async function or(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 eM(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let s=sY(t.snapshot);if(s)return t.recording&&(t.recording.touchReferenceFrame=s),s;if(!t.recording)return;let o=sY(await n(t,r,a,i,{interactiveOnly:!0}));return o&&t.recording&&(t.recording.touchReferenceFrame=o),o}async function oa(e){try{return await or(e)}catch(t){b({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function oi(e){return sY({nodes:e,createdAt:0})}function on(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 os(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new J("SESSION_NOT_FOUND","No active session. Run open first.");return eN({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)=>oo(await ea(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)=>oo(await ea(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)=>oo(await ea(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&&(eS(t,r.snapshot),e.sessionStore.set(e.sessionName,t))}},policy:eu()})}function oo(e){return e&&"object"==typeof e?e:void 0}function ol(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function od(e){return"ref"===e.kind?{ref:ou(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 ou(e){return e?.startsWith("@")?e.slice(1):e}async function oc(e){switch(e.req.command){case"press":case"click":return await of(e);case"fill":return await op(e);default:return null}}async function of(e){let t,{req:r,sessionName:a,sessionStore:i}=e,n=i.get(a),s="click"===r.command?"click":"press";if(!n)return eh("SESSION_NOT_FOUND","No active session. Run open first.");let o=on(n,s);if(o)return o;if(!e0("press",n.device))return eh("UNSUPPORTED_OPERATION","press is not supported on this device");let l=eP(r.flags),d=en(l);if("primary"!==l){let e=ec({commandLabel:s,platform:n.device.platform,button:l,count:r.flags?.count,intervalMs:r.flags?.intervalMs,holdMs:r.flags?.holdMs,jitterPx:r.flags?.jitterPx,doubleTap:r.flags?.doubleTap});if(e)return eh(e.code,e.message,e.details)}let u=function(e,t){let r=ol(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`)}}(r.positionals??[],s);if(!u.ok)return u.response;if("ref"===u.target.kind){let a=e.refSnapshotFlagGuardResponse("press",r.flags);if(a)return a;t=await oh(e,n)}return await om(e,{androidFreshnessBaseline:t,run:async e=>{let t={session:a,requestId:r.meta?.requestId,button:l,count:r.flags?.count,intervalMs:r.flags?.intervalMs,holdMs:r.flags?.holdMs,jitterPx:r.flags?.jitterPx,doubleTap:r.flags?.doubleTap};return"click"===s?await e.interactions.click(u.target,t):await e.interactions.press(u.target,t)},afterRun:async e=>{var t;await eA(n,(t=u.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 t=>{let a="point"===t.kind?await oa({session:n,flags:r.flags,sessionStore:i,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):oi(n.snapshot?.nodes??[]),s=oe({data:t.backendResult,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:a,extra:{...od(t),...d}});return{result:s,responseData:s}}})}async function op(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=on(i,"fill");if(e)return e}if(i&&!e0("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=ol(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=tc(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;await oh(e,i)}return await om(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:oi(i.snapshot?.nodes??[]),r=oe({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...od(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:ou(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 om(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eh("SESSION_NOT_FOUND","No active session. Run open first.");let a=os(e),i=Date.now();try{let n=await t.run(a);await t.afterRun?.(n);let s=Date.now(),{result:o,responseData:l}=await t.buildPayloads(n);return ot({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:o,responseData:l,actionStartedAt:i,actionFinishedAt:s,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=z(t);if(eG(e))throw e;return{ok:!1,error:W(t)}}}async function oh(e,t){if(!eJ(t))return;let r=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:"ref-refresh"})}catch(t){b({level:"warn",phase:"android_ref_snapshot_refresh_failed",data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return r}async function og(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},s=a(n,e.appBundleId,e.trace?.outPath),{snapshot:o}=await eD({device:e.device,session:e,flags:n,outPath:n.out,logPath:s.logPath??"",androidFreshnessMode:i.androidFreshnessMode});return eS(e,o),r.set(e.name,e),o}let ow=/\bis(?:n't| not)\s+responding\b/i,oy=/^close app$/i;async function ov(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await oS(t),r=function(e){if(o_(e))return e.find(e=>{let t=ob(e);return t.length>0&&oy.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=tA(r.rect),n=await E(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))],{allowFailure:!0});if(0!==n.exitCode)return b({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 oI(t))return b({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await j(t.device,t.appBundleId),!await oA(t,t.appBundleId)))return b({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return b({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 b({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 oS(e){return tI(tS((await ew(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function oI(e){for(let t=0;t<12;t+=1){if(!o_(await oS(e)))return!0;await Z(500)}return!o_(await oS(e))}async function oA(e,t){for(let r=0;r<12;r+=1){if((await U(e.device)).package===t)return!0;await Z(500)}return(await U(e.device)).package===t}function ob(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 o_(e){return e.some(e=>{let t=ob(e);return t.length>0&&ow.test(t)})}async function oN(e){let t=await oc({...e,captureSnapshotForSession:og,refSnapshotFlagGuardResponse:ei});if(t)return t;switch(e.req.command){case"type":return await oM({...e,captureSnapshotForSession:og});case"get":return await eI(e);case"is":return await ek(e);default:return null}}async function oM(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(!e0("type",i.device))return eh("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await ov({session:i}))return eh("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),s=os(e),o=Date.now();try{let e=await s.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,...ti(e.message??`Typed ${Array.from(e.text).length} chars`)};return ot({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:d,responseData:d,actionStartedAt:o,actionFinishedAt:l})}catch(e){return{ok:!1,error:W(e)}}}function ox(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 oD(e){let{req:t,leaseRegistry:r}=e,a=ox(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 ok(e,t){if(!t)return[];let r=[],a=e.device,i=e3(t.platform);if(i&&!eQ(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=F(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oP(e){return`${function(e){switch(e){case"iosSimulatorDeviceSet":return"--ios-simulator-device-set";case"androidDeviceAllowlist":return"--android-device-allowlist";default:return`--${e}`}}(e.key)}=${e.value}`}let oR=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function oL(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:o}=e,l=eN({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let s={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?oO(await ea(t.device,"screenshot",[],i,s)):oO(await ea(t.device,"screenshot",[i],void 0,s))}}}({session:t,outputPlacement:i,dispatchContext:o}),artifacts:{resolveInput:async()=>{throw new J("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(s.join(c.tmpdir(),"agent-device-screenshot-")),r=s.join(t,"screenshot.png")),await n.mkdir(s.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(s.join(c.tmpdir(),`${e.prefix}-`));return{path:s.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:eu()});return await l.capture.screenshot({session:r,requestId:o.requestId,appBundleId:t.appBundleId,fullscreen:o.screenshotFullscreen,maxSize:o.screenshotMaxSize,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function oO(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let oE=[255,59,48,255],oC=[255,214,10,255],o$=[0,0,0,255],oT={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 oF(e){let t=e4(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oV(r)&&oB(r.rect)&&(!t||oK(r.rect)>oK(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&&oB(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 oB(e.rect)&&!("image"===tv((t=e).type??"")&&!oG(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oj)||oq(e.identifier);return oU(e)?t:t&&function(e){let t=tv(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let s=function(e,t){if(function(e){return oU(e)&&!oV(e)}(t)&&oB(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(oU(t)&&!oV(t)&&oB(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oB(r.rect))return r;if(t.hittable&&oB(t.rect)&&!oV(t))return t;let a=tf(e,t);return a?.rect&&oB(a.rect)&&!oV(a)?a:null}(e.nodes,a);if(!s?.rect||!oB(s.rect))continue;let o=function(e,t,r){let a=oH(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=oH(a);if(!i)continue;let n=function(e){let t=0;return tv(e.type??"").includes("text")&&(t+=2),oj(e.label)&&(t+=2),oj(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oH(t)??tw(t,r))}(a,s,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),oU(t)&&(a+=3),oU(e)&&(a+=2),r&&(a+=2),oq(t.identifier)&&(a+=1),oG(t.value)&&(a+=1),a}(a,s,o),d=function(e,t,r,a){if(!e)return oJ({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 oJ({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,s.rect,t,r);if(!oB(d))continue;let u=n.get(s.ref);(!u||l>u.score)&&n.set(s.ref,{ref:s.ref,label:o,rect:s.rect,overlayRect:d,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>oK(e.overlayRect)-oK(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oz(e.overlayRect,r.overlayRect)||oz(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oK(r.overlayRect)<oK(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:oW(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:oW(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:tA(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)oX(e,t.x,t.x+t.width-1,t.y+a,r),oX(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),oY(e,t.x+a,t.y,t.y+t.height-1,r),oY(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,oE),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oZ(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,s=n>=0?n:oZ(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 s=0;s<a;s+=1)oQ(e,t+s,r+n,i)})(e,i,s,a,oC),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oT[t];if(a)for(let t=0;t<a.length;t+=1)for(let s=0;s<a[t].length;s+=1)"1"===a[t][s]&&oQ(e,n+s,r+t,i);n+=6}}(e,i+3,s+2,r,o$)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,w.sync.write(t)),r}function oU(e){let t=[e.type,e.role,e.subrole].map(e=>tv(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 oV(e){let t=[e.type,e.role,e.subrole].map(e=>tv(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oG(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oj(e){var t;let r;return!!oG(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oq(e){var t;return"string"==typeof e&&!!oj(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oH(e){let t=[e.label,e.value].find(oj);return t?t.trim():oq(e.identifier)?e.identifier.trim():void 0}function oB(e){return!!(e&&e.width>0&&e.height>0)}function oK(e){return e.width*e.height}function oz(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 oW(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oJ(e,t,r){let a=oZ(e.x,0,Math.max(0,t-1)),i=oZ(e.y,0,Math.max(0,r-1)),n=Math.max(1,t-a),s=Math.max(1,r-i);return{x:a,y:i,width:oZ(e.width,1,n),height:oZ(e.height,1,s)}}function oZ(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oX(e,t,r,a,i){for(let n=t;n<=r;n+=1)oQ(e,n,a,i)}function oY(e,t,r,a,i){for(let n=r;n<=a;n+=1)oQ(e,t,n,i)}function oQ(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 o0=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),o1=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),o2=new Set(o1),o8=new Map;function o3(e){if(e$(e.meta?.requestId))throw ef()}function o5(e,t,r,a){let i=A().requestId;return{...eO(e,t,r,a,i),requestId:i}}async function o4(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||au(e.flags))try{let t=await ey(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function o6(e,t){if(t)return"android"===t.device.platform?t.device:void 0;if("open"!==e.command&&!au(e.flags))return;let r=await ey(e.flags??{});return"android"===r.platform?r:void 0}async function o9(e){let{req:t,existingSession:r,androidAdbProvider:a}=e;if(!a)return{};let i=await o6(t,r);if(!i)return{};let n=a({req:t,device:i,session:r}),s="function"==typeof n?n:n?.exec;return{provider:n,executor:s,serial:i.id}}async function o7(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:s,androidAdbExecutor:o,contextFromFlags:l}=e,d=await oD({req:t,leaseRegistry:n});if(d)return d;let u=await n7({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:s,androidAdbExecutor:o});if(u)return u;let c=await es({req:t,sessionName:r,logPath:a,sessionStore:i});if(c)return c;let f=await sJ({req:t,sessionName:r,sessionStore:i,logPath:a});if(f)return f;let p=await se({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:s});if(p)return p;let m=await oN({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:l});return m||null}async function le(e){var t,r;let a,i,n,s,o,l,d,{req:u,session:c,logPath:f,sessionStore:p}=e,m=u.command;if(!e0(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 ov({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,s="screenshot"===a&&i[0]?[tz.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,o="screenshot"===a&&n?tz.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?s:i,d="screenshot"===a&&o?{...t.flags??{},out:o}:t.flags??{},{resolvedPositionals:s,resolvedOut:o,recordedPositionals:l,recordedFlags:d}),v=Date.now(),S={...o5(f,u.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},I="screenshot"===m?await oL({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 ea(c.device,m,h,g,{...S});return"screenshot"===m&&u.flags?.overlayRefs&&"string"==typeof I?.path&&await lt(c,I,f),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:s,data:o,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=sY(e.snapshot),n={...a??{}},s=s3(n.direction)??s3(r[0]);if(!s)return a;let o=s5(n.amount)??s5(r[1]),l=s5(n.pixels),d=s9(n,[]),u=s5(n.referenceWidth),c=s5(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??s0;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:s,...void 0!==o?{amount:o}:{},...void 0!==l?{pixels:l}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=e6({direction:s,amount:o,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:s,...void 0!==o?{amount:o}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,o);s1(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:s,result:o??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:I,actionStartedAt:v,actionFinishedAt:Date.now(),flags:u.flags??{}}),ep(m)&&e9(c,m),{ok:!0,data:I??{}}}async function lt(e,t,r){let a=eL(await eE({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);eS(e,a);let i=await oF({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}async function lr(e,t=5e3){await Promise.all(e.map(async e=>{let r;await new Promise(a=>{r=setTimeout(()=>{!function(e){e.destroyConnections?.();let t="closeAllConnections"in e?e.closeAllConnections:void 0;if("function"==typeof t)return t.call(e);let r="closeIdleConnections"in e?e.closeIdleConnections:void 0;"function"==typeof r&&r.call(e)}(e),a()},t);try{e.close(()=>a())}catch{a()}}),r&&clearTimeout(r)}))}function la(e){i.existsSync(e)&&i.unlinkSync(e)}function li(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 ln(e){let t=li(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function ls(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:lo,infoPath:ll,lockPath:ld,logPath:lu,sessionsDir:lc}=tt(process.env.AGENT_DEVICE_STATE_DIR),lf=ta(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var lp=lc;if(i.existsSync(lp))for(let e of i.readdirSync(lp,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=s.join(lp,e.name,tJ);if(i.existsSync(t))try{let e=tZ(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=D(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=N(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{tY(t)}}let lm=new tz(lc),lh=new r4({maxActiveSimulatorLeases:ls(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:ls(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:ls(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:ls(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),lg=tN(),lw=a.randomBytes(24).toString("hex"),ly=D(process.pid)??void 0,lv=to(),lS=function(e){let{logPath:t,token:r,androidAdbProvider:a,deviceInventoryProvider:i,trackDownloadableArtifact:n}=e,{sessionStore:o,leaseRegistry:l}=e;async function d(e){let u=!!(e.meta?.debug||e.flags?.verbose);return await S({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:u,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:W(new J("UNAUTHORIZED","Invalid token"))};try{return await eo(i,async()=>{let r=function(e){let t=tr(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=e7(r);if(r&&!a)throw new J("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new J("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);b({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let i=r.command,u=ox(r);o1.has(i)||r.meta?.sessionIsolation!=="tenant"||l.assertLeaseAdmission({tenantId:u.tenantId,runId:u.runId,leaseId:u.leaseId,backend:u.leaseBackend});let c=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,o),f=o2.has(i)?null:await o4(r,c,o),p=async()=>{o3(r);let e=o.get(c);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),o.set(c,e));let u=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?ok(t,a):function(e,t,r){var a,i;let n=[],s=e3(t);if(void 0!==e.platform&&s&&(a=e3(e.platform),i=s,a&&i&&a!==i&&("apple"===a?!e2(i):"apple"!==i||!e2(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of oR){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 oR)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new J("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oP).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),f=e=>(function(e,t,r){let a=A();if(!t.ok){b({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=I({force:!0})??void 0;return{ok:!1,error:W(new J(K(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 b({level:"info",phase:"request_success"}),I(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let o=(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:s.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===o.length?t:{...t,artifacts:o.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(u,e,n);if(e?.recording?.invalidatedReason&&"record"!==i&&"close"!==i)return f({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||u.meta?.lockPolicy||o0.has(i)||function(e,t){let r=ok(e,t);if(0!==r.length){var a;let t,i,n;throw new J("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oP).join(", ")}. Use a different --session name or close this session first.`)}}(e,u.flags);let p=await o9({req:u,existingSession:e,androidAdbProvider:a});return await k(p.provider,{serial:p.serial??""},async()=>{let e=await o7({req:u,sessionName:c,logPath:t,sessionStore:o,leaseRegistry:l,invoke:d,androidAdbExecutor:p.executor,contextFromFlags:(e,r,a)=>({...o5(t,e,r,a),surface:o.get(c)?.surface})});if(e)return f(e);let r=o.get(c);if(!r)return f({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let a=await le({req:u,session:r,sessionName:c,logPath:t,sessionStore:o});return f(a)})};return f?(o3(r),await ev(o8,f,p)):(o3(r),await p())})}catch(r){b({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=A(),t=I({force:!0})??void 0;return{ok:!1,error:W(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return d}({logPath:lu,token:lw,sessionStore:lm,leaseRegistry:lh,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{rx(t)},9e5);return r.unref(),rM.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});async function lI(e){await S({command:"daemon",session:"daemon",logPath:lu,debug:!0},async()=>{b({level:"error",phase:"daemon_fatal",data:{error:e instanceof Error?e.message:String(e)}}),I({force:!0})})}async function lA(){let e=lm.toArray();await Promise.all(e.map(lb))}async function lb(e){let t=iA(e,e.name).catch(t=>{process.stderr.write(`Daemon session teardown error (${e.name}): ${t instanceof Error?t.message:String(t)}
39
- `)});await Promise.race([t,Z(5e3).then(()=>{process.stderr.write(`Daemon session teardown timed out (${e.name}).
40
- `)})]),lm.writeSessionLog(e),lm.delete(e.name)}async function l_(){let e,t,r=[];if("http"!==lf){let t,a,i=(t=new Set,(a=y.createServer(e=>{t.add(e),e.on("close",()=>t.delete(e));let r="",a=0,i=new Set,n=!1,s=()=>{if(!n&&0!==a){for(let e of(n=!0,i))ej(e);b({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:a}}),(async()=>{try{let e=Date.now()+15e3;for(;a>0&&Date.now()<e&&(await eF(),!(a<=0));)await Z(200)}catch(e){b({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:a}})}})()}};e.setEncoding("utf8"),e.on("close",s),e.on("error",s),e.on("data",async t=>{let n=(r+=t).indexOf("\n");for(;-1!==n;){let t,s,o=r.slice(0,n).trim();if(r=r.slice(n+1),0===o.length){n=r.indexOf("\n");continue}a+=1;try{let e=JSON.parse(o);if(s=eC(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:s},i.add(s),em(s),e$(s))throw ef();t=await lS(e)}catch(e){t={ok:!1,error:W(e)}}finally{a-=1,s&&(i.delete(s),ez(s))}e.destroyed||e.write(`${JSON.stringify(t)}
41
- `),n=r.indexOf("\n")}})})).destroyConnections=()=>{for(let e of t)e.destroy();t.clear()},a);r.push(i),e=await new Promise((e,t)=>{i.once("error",t),i.listen(0,"127.0.0.1",()=>{i.off("error",t);let r=i.address();"object"==typeof r&&r?.port?e(r.port):t(new J("COMMAND_FAILED","Failed to bind socket server"))})})}if("socket"!==lf){let e=await rQ({handleRequest:lS,token:lw});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 J("COMMAND_FAILED","Failed to bind HTTP server"))})})}return{servers:r,socketPort:e,httpPort:t}}!async function(){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 s=li(t);if(s?.pid&&s.pid!==process.pid&&x(s.pid,s.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(lo,ld,{pid:process.pid,version:lg,startedAt:Date.now(),processStartTime:ly})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let e=[];try{var t,r,a;let n,s=await l_();e=s.servers,t=s.socketPort,r=s.httpPort,a={socketPort:t,httpPort:r,token:lw,version:lg,codeSignature:lv,processStartTime:ly},i.existsSync(lo)||i.mkdirSync(lo,{recursive:!0}),i.writeFileSync(lu,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",i.writeFileSync(ll,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:lo},null,2),{mode:384}),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${t}
42
- `),r&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${r}
43
- `)}catch(r){let t=z(r);for(let r of(process.stderr.write(`Daemon error: ${t.message}
44
- `),e))try{r.close(()=>{})}catch{}la(ll),ln(ld),process.exit(1);return}let n=!1,s=async(t={})=>{n||(n=!0,t.cause&&await lI(t.cause),await lr(e),await lA(),await eb(),la(ll),ln(ld),process.exit(t.exitCode??0))};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof J?e:z(e);process.stderr.write(`Daemon error: ${t.message}
45
- `),s({exitCode:1,cause:e})}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof J?t:z(t);process.stderr.write(`Daemon error: ${r.message}
46
- `),s({exitCode:1,cause:t})})}();
55
+ `.trim();async function fw(e,t={}){let r,n=t.pollMs??150,a=t.attempts??12,i=0;for(let t=0;t<a;t+=1){let t=0;try{t=s.statSync(e).size}catch{t=0}if(t>0&&t===r){if((i+=1)>=2)return}else i=0;r=t,await ef(n)}}async function fg(e){try{var t,r;let n,a=await P("swift",["-",e],{stdin:fh,allowFailure:!0,timeoutMs:1e4});if(0===a.exitCode)return!0;if(t=a.stderr,r=a.stdout,n=`${t}
56
+ ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(n))return fv(e);return!1}catch(t){if(t instanceof k&&"TOOL_MISSING"===t.code)return fv(e);throw t}}async function fy(e,t={}){let r=t.pollMs??150,n=t.attempts??12;for(let t=0;t<n;t+=1){if(await fg(e))return;await ef(r)}}function fv(e){try{let t=s.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=s.openSync(e,"r");try{let e=s.fstatSync(t).size,r=0,n=[];for(;r+8<=e&&n.length<16;){let e=Buffer.alloc(8);if(8>s.readSync(t,e,0,8,r))break;let a=e.readUInt32BE(0),i=e.toString("latin1",4,8);if(n.push(i),1===a){let e=Buffer.alloc(8);if(8>s.readSync(t,e,0,8,r+8))break;a=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(a)||a<=0)break;r+=a}return n}finally{s.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function fI(e){let t=p.parse(e);return p.join(t.dir,`${t.name}.gesture-telemetry.json`)}function fA(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function fS(e){let t=p.dirname(g(import.meta.url)),r=[g(new URL(`./${e}`,import.meta.url)),p.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),p.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),p.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(s.existsSync(e))return e;throw new k("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 fb(e){let{videoPath:t,scriptPath:r,scriptArgs:n,commandDescription:a}=e;await fw(t),await fy(t);let i=s.mkdtempSync(p.join(d.tmpdir(),"agent-device-record-overlay-")),o=p.join(i,`input${p.extname(t)||".mp4"}`),l=p.join(i,p.basename(t)),u=p.join(i,"home"),c=p.join(i,"module-cache");s.copyFileSync(t,o),s.mkdirSync(u,{recursive:!0}),s.mkdirSync(c,{recursive:!0});try{await P("xcrun",["swift",r,"--input",o,"--output",l,...n],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:c}}),await fy(l),s.copyFileSync(l,t)}catch(n){let e=n instanceof k?n:new k("COMMAND_FAILED",String(n),void 0,n instanceof Error?n:void 0);throw new k("COMMAND_FAILED",a,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{s.rmSync(i,{recursive:!0,force:!0})}}async function f_(e){let{videoPath:t,trimStartMs:n}=e;n>0&&await fb({videoPath:t,scriptPath:r??=fS("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(n)],commandDescription:"Failed to trim the start of the iOS recording"})}async function fN(e){let{videoPath:r,telemetryPath:n,targetLabel:a="recording"}=e;await fb({videoPath:r,scriptPath:t??=fS("recording-overlay.swift"),scriptArgs:["--events",n],commandDescription:`Failed to add touch overlays to the ${a}`})}async function fx(e){let{videoPath:t,quality:r,targetLabel:a="recording"}=e;await fb({videoPath:t,scriptPath:n??=fS("recording-resize.swift"),scriptArgs:["--quality",String(r)],commandDescription:`Failed to resize the ${a}`})}function fM(e){return e instanceof Error?e.message:String(e)}function fD(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function fk(e){let{recording:t,deps:r,trimStartMs:n,targetLabel:a}=e,i=function(e){var t,r,n;let a,i,{recording:o,trimStartMs:l}=e,u=(a=fI((t={videoPath:o.outPath,events:o.gestureEvents,trimStartMs:l}).videoPath),i={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(n=t.trimStartMs??0)>0?fA(r.flatMap(e=>{let t=e.tMs-n,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):fA(r))},s.writeFileSync(a,JSON.stringify(i,null,2)),a);return o.telemetryPath=u,u}({recording:t,trimStartMs:n});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:i,targetLabel:a})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${fM(e)}`}}}async function fE(e,t,r){return await R(K(e),t,r)}async function fO(e,t){let r=await fE(e,["shell","ps","-o","pid=","-p",t],{allowFailure:!0});return 0===r.exitCode&&r.stdout.split(/\s+/).map(e=>e.trim()).includes(t)}async function fP(e,t){for(let r=0;r<40;r+=1){if(!await fO(e,t))return!0;await ef(250)}return!await fO(e,t)}async function fC(e,t){let r,n=0;for(let a=0;a<20;a+=1){let a=await fE(e,["shell","stat","-c","%s",t],{allowFailure:!0}),i=0===a.exitCode?a.stdout.trim():"";if(i.length>0&&i===r){if((n+=1)>=4)return}else n=0;r=i,await ef(250)}}async function fL(e,t,r){for(let n=0;n<8;n+=1){let a=await fE(e,["shell","stat","-c","%s",t],{allowFailure:!0}),i=0===a.exitCode?Number(a.stdout.trim()):NaN;if(Number.isFinite(i)&&i>0)return!0;if(!await fO(e,r))break;if(n+1>=2)return!0;await ef(250)}return!1}async function fR(e){let t,{deps:r,deviceId:n,remotePath:a,outPath:i}=e;for(let e=0;e<2;e+=1){try{s.rmSync(i,{force:!0})}catch{}let o=K(n),l=await e5(a,i,{allowFailure:!0,device:o});if(0!==l.exitCode)t=fD(l,"adb pull");else{await r.waitForStableFile(i,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(i);if(eM({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:n,remotePath:a,outPath:i,attempt:e+1,fileSize:(()=>{try{return s.statSync(i).size}catch{return 0}})(),playable:t}}),t)return;eM({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:n,remotePath:a,outPath:i,attempt:e+1}})}e<1&&await ef(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 fT(e){let{deviceId:t,quality:r}=e;if(void 0===r||r>=10)return;let n=await fE(t,["shell","wm","size"],{allowFailure:!0}),a=n.stdout.match(/Override size:\s*(\d+)x(\d+)/)??n.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==n.exitCode||!a)throw Error(`failed to resolve Android screen size for recording quality: ${fD(n,"adb shell wm size")}`);return{width:f$(Number(a[1]),r),height:f$(Number(a[2]),r)}}function f$(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function fF(e,t){await fE(e,["shell","rm","-f",t],{allowFailure:!0})}async function fU(e,t){let r=await fE(e,["shell","kill","-9",t],{allowFailure:!0});return eM({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:e,remotePid:t,exitCode:r.exitCode,stdout:r.stdout.trim(),stderr:r.stderr.trim()}}),!(0!==r.exitCode&&await fO(e,t))&&await fP(e,t)}async function fG(e){var t;let r,n,{device:a,recordingBase:i}=e,o="failed to start recording: Android screenrecord did not begin producing frames";try{r=await fT({deviceId:a.id,quality:i.quality})}catch(e){return dG("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),n=`agent-device-recording-${t}.mp4`,[`/sdcard/${n}`,`/data/local/tmp/${n}`])){let t=await fE(a.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){o=`failed to start recording: ${fD(t,"adb shell screenrecord")}`;continue}let n=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!n){o="failed to start recording: adb did not return a valid Android screenrecord pid",await fF(a.id,e);continue}if(eM({level:"debug",phase:"record_start_android_started",data:{deviceId:a.id,remotePath:e,remotePid:n}}),await fL(a.id,e,n))return{platform:"android",remotePath:e,remotePid:n,...i,startedAt:Date.now()};o="failed to start recording: Android screenrecord did not begin producing frames",await fU(a.id,n),await fF(a.id,e)}return dG("COMMAND_FAILED",o)}async function fV(e){let t,r,{deps:n,device:a,recording:i}=e;eM({level:"debug",phase:"record_stop_android_enter",data:{deviceId:a.id,remotePath:i.remotePath,remotePid:i.remotePid}});let o=await fE(a.id,["shell","kill","-2",i.remotePid],{allowFailure:!0});if(eM({level:"debug",phase:"record_stop_android_signal",data:{deviceId:a.id,remotePath:i.remotePath,remotePid:i.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await fO(a.id,i.remotePid)&&!await fU(a.id,i.remotePid)&&(t=`failed to stop recording: ${fD(o,"adb shell kill")}`):await fP(a.id,i.remotePid)||await fU(a.id,i.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${i.remotePid} did not exit`),!t){await fC(a.id,i.remotePath);let e=await fR({deps:n,deviceId:a.id,remotePath:i.remotePath,outPath:i.outPath});if(e)return await s(),dG("COMMAND_FAILED",e);await fk({recording:i,deps:n,targetLabel:"Android recording"})}if(await s(),t)return dG("COMMAND_FAILED",t);if(r)return dG("COMMAND_FAILED",r);return null;async function s(){let e=await fE(a.id,["shell","rm","-f",i.remotePath],{allowFailure:!0});eM({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:a.id,remotePath:i.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${fD(e,"adb shell rm")}`)}}function fj(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function fB(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath,requestId:e.meta?.requestId}}async function fq(e){let{req:t,activeSession:r,device:n,logPath:a,deps:i}=e,o=fj(r);try{await i.runIosRunnerCommand(n,{command:"recordStop",appBundleId:o},fB(t,a,r))}catch(e){eM({level:"warn",phase:"record_stop_runner_failed",data:{platform:n.platform,kind:n.kind,deviceId:n.id,session:r.name,error:fM(e)}})}}async function fH(e){let{req:t,activeSession:r,device:n,logPath:a,deps:i}=e,o=fj(r);if(o)try{await i.runIosRunnerCommand(n,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},fB(t,a,r))}catch(e){eM({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:n.id,session:r.name,appBundleId:o,error:fM(e)}})}}async function fW(e){let t,r,{req:n,activeSession:a,sessionStore:i,device:o,logPath:s,deps:l,fpsFlag:u,recordingBase:d,appBundleId:c}=e,p=`agent-device-recording-${Date.now()}.mp4`,f=`tmp/${p}`,m=fB(n,s,a),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:p,fps:u,quality:d.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(n){var w,g;if(!fM(n).toLowerCase().includes("recording already in progress"))return dG("COMMAND_FAILED",`failed to start recording: ${fM(n)}`);eM({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:a.name,error:fM(n)}});let e=(w=o.id,g=a.name,i.toArray().find(e=>e.name!==g&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===w&&e.recording?.platform==="ios-device-runner"));if(e)return dG("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 dG("COMMAND_FAILED",`failed to start recording: ${fM(e)}`)}}return{platform:"ios-device-runner",remotePath:f,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...d}}async function fz(e){let{req:t,activeSession:r,device:n,logPath:a,deps:i,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await i.runIosRunnerCommand(n,{command:"recordStart",outPath:s.outPath,fps:o,quality:s.quality,appBundleId:l},fB(t,a,r))}catch(e){return dG("COMMAND_FAILED",`failed to start recording: ${fM(e)}`)}return{platform:"macos-runner",...s}}async function fK(e){let{req:t,activeSession:r,device:n,logPath:a,deps:i,recording:o}=e;await fq({req:t,activeSession:r,device:n,logPath:a,deps:i});let s={stdout:"",stderr:"",exitCode:1};for(let e of np)if(0===(s=await i.runCmd("xcrun",["devicectl","device","copy","from","--device",n.id,"--source",o.remotePath,"--destination",o.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==s.exitCode){let e=s.stderr.trim()||s.stdout.trim()||`devicectl exited with code ${s.exitCode}`;return dG("COMMAND_FAILED",`failed to copy recording from device: ${e}`)}let l="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);return l>0&&await i.trimRecordingStart({videoPath:o.outPath,trimStartMs:l}),await fk({recording:o,deps:i,trimStartMs:l,targetLabel:"iOS recording"}),null}async function fJ(e){let{req:t,activeSession:r,device:n,logPath:a,deps:i,recording:o}=e;return await fq({req:t,activeSession:r,device:n,logPath:a,deps:i}),await fk({recording:o,deps:i,targetLabel:"macOS recording"}),null}async function fX(e){"ios"!==e.platform||0!==e.gestureEvents.length&&await ef(350)}async function fY(e){for(let t=0;t<2;t+=1){try{if(s.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await ef(250)}return Date.now()}async function fZ(e){let t,r,{req:n,activeSession:a,device:i,logPath:o,deps:s,recordingBase:l,resolvedOut:u}=e;await fH({req:n,activeSession:a,device:i,logPath:o,deps:s});let{child:d,wait:c}=s.startIosSimulatorRecording({device:i,outPath:u}),p=await fY(u);try{let e=Date.now(),l=await s.runIosRunnerCommand(i,{command:"uptime",appBundleId:fj(a)},fB(n,o,a)),u=Date.now();t=Math.round((e+u)/2),r="number"==typeof l.currentUptimeMs?l.currentUptimeMs:void 0}catch{}return{platform:"ios",child:d,wait:c,...l,startedAt:p,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function fQ(e){let t,{req:r,sessionName:n,sessionStore:a,activeSession:i,device:o,logPath:l,deps:u}=e;if(i.recording)return dG("INVALID_ARGS","recording already in progress");let d=r.flags?.fps,c=r.flags?.quality;if(void 0!==d&&(!Number.isInteger(d)||d<1||d>120))return dG("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==c&&(!Number.isInteger(c)||c<5||c>10))return dG("INVALID_ARGS","quality must be an integer between 5 and 10");if(!d7("record",o))return dG("UNSUPPORTED_OPERATION","record is not supported on this device");let f=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=aD.expandHome(f,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(s.mkdirSync(p.dirname(m),{recursive:!0}),s.rmSync(m,{force:!0}),"ios"===o.platform&&"device"===o.kind){let e=fj(i);if(!e)return dG("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await fW({req:r,activeSession:i,sessionStore:a,device:o,logPath:l,deps:u,fpsFlag:d,recordingBase:h,appBundleId:e})}else if("macos"===o.platform){let e=fj(i);if(!e)return dG("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await fz({req:r,activeSession:i,device:o,logPath:l,deps:u,fpsFlag:d,recordingBase:h,appBundleId:e})}else t="ios"===o.platform?await fZ({req:r,activeSession:i,device:o,logPath:l,deps:u,recordingBase:h,resolvedOut:m}):await fG({device:o,recordingBase:h});return"ok"in t?t:(i.recording=t,a.set(n,i),a.recordAction(i,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??f,showTouches:t.showTouches}})}async function f0(e){let{deps:t,device:r,recording:n}=e;if("android"===n.platform)return await fV({deps:t,device:r,recording:n});await t.waitForRecordingTail(n),n.child.kill("SIGINT");let a=await n.wait;if(0!==a.exitCode)return dG("COMMAND_FAILED",`failed to stop recording: ${fD(a,"simctl recordVideo")}`);if(void 0!==n.quality&&n.quality<10)try{await t.resizeRecording({videoPath:n.outPath,quality:n.quality,targetLabel:"iOS recording"})}catch(e){n.overlayWarning=`failed to resize recording: ${fM(e)}`}return await fk({recording:n,deps:t,targetLabel:"iOS recording"}),null}async function f1(e){var t;let r,{req:n,activeSession:a,device:i,logPath:o,deps:s}=e;if(!a.recording)return dG("INVALID_ARGS","no active recording");let l=a.recording,u=l.invalidatedReason;a.recording=void 0;let d="ios-device-runner"===l.platform?await fK({req:n,activeSession:a,device:i,logPath:o,deps:s,recording:l}):"macos-runner"===l.platform?await fJ({req:n,activeSession:a,device:i,logPath:o,deps:s,recording:l}):await f0({deps:s,device:i,recording:l});return d||(u?dG("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=l).outPath,localPath:t.clientOutPath,fileName:p.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return fI(e.clientOutPath)}(t),fileName:p.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function f2(e){let{req:t,sessionName:r,sessionStore:n,logPath:a}=e,i={runCmd:async(e,t,r)=>"xcrun"===e?await rm(t,r):await P(e,t,r),startIosSimulatorRecording:e=>dY.resolve(void 0).startIosSimulatorRecording(e),runIosRunnerCommand:at,waitForRecordingTail:fX,waitForStableFile:fw,isPlayableVideo:fg,trimRecordingStart:f_,resizeRecording:fx,overlayRecordingTouches:fN},o=n.get(r),s=o?.device??await op(t.flags??{});o||await oY(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},u=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(u))return dG("INVALID_ARGS","record requires start|stop");if("start"===u)return fQ({req:t,sessionName:r,sessionStore:n,activeSession:l,device:s,logPath:a,deps:i});let d=await f1({req:t,activeSession:l,device:s,logPath:a,deps:i});return d.ok&&n.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:d.data?.outPath,showTouches:d.data?.showTouches}}),d}async function f3(e){let{req:t,sessionName:r,sessionStore:n,logPath:a}=e,i=t.command;if("record"===i)return f2({req:t,sessionName:r,sessionStore:n,logPath:a});if("trace"===i){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return dG("INVALID_ARGS","trace requires start|stop");let a=n.get(r);if(!a)return dG("SESSION_NOT_FOUND","No active session");if("start"===e){if(a.trace)return dG("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??n.defaultTracePath(a),r=aD.expandHome(e);return s.mkdirSync(p.dirname(r),{recursive:!0}),s.appendFileSync(r,""),a.trace={outPath:r,startedAt:Date.now()},n.recordAction(a,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!a.trace)return dG("INVALID_ARGS","no active trace");let o=a.trace.outPath;if(t.positionals?.[1]){let e=aD.expandHome(t.positionals[1]);s.mkdirSync(p.dirname(e),{recursive:!0}),s.existsSync(o)?s.renameSync(o,e):s.appendFileSync(e,""),o=e}return a.trace=void 0,n.recordAction(a,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:o}}),{ok:!0,data:{trace:"stopped",outPath:o}}}return null}let f5=em(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),f4=new Map;async function f8(e){let t=await S.mkdtemp(p.join(d.tmpdir(),"agent-device-materialized-"));try{let r=await f7(e.installablePath,p.join(t,"installable")),n=e.archivePath?await f7(e.archivePath,p.join(t,"archive")):void 0,a=i.randomUUID(),o=e.ttlMs??f5,s=Date.now()+o,l=setTimeout(()=>{f6(a)},o);return f4.set(a,{rootPath:t,installablePath:r,archivePath:n,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:s,timer:l}),{materializationId:a,installablePath:r,...n?{archivePath:n}:{},expiresAt:new Date(s).toISOString()}}catch(e){throw await S.rm(t,{recursive:!0,force:!0}),e}}async function f6(e,t){let r=f4.get(e);if(!r)throw new k("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new k("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),f4.delete(e),await S.rm(r.rootPath,{recursive:!0,force:!0})}async function f9(e){let t=Array.from(f4.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await f6(e)}))}async function f7(e,t){let r=await S.stat(e);await S.mkdir(t,{recursive:!0});let n=p.join(t,p.basename(e));return r.isDirectory()?await S.cp(e,n,{recursive:!0}):await S.copyFile(e,n),n}async function me(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 k("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await oY(e.session.device),e.session.device}if(!r)throw new k("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let n=await op(e.flags??{});return await oY(n),n}async function mt(e){let{prepared:t,retention:r,req:n,session:a,sessionName:i}=e;if(r.enabled)return await f8({archivePath:t.archivePath,installablePath:t.installablePath,tenantId:n.meta?.tenantId,sessionName:a?i:void 0,ttlMs:r.ttlMs})}function mr(e){return e?{...e.archivePath?{archivePath:e.archivePath}:{},installablePath:e.installablePath,materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}}async function mn(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);try{let e,i,o=(e=function(e){let t=e.meta?.installSource;if(!t)throw new k("INVALID_ARGS","install_from_source requires a source payload");switch(t.kind){case"url":if(!t.url||0===t.url.trim().length)throw new k("INVALID_ARGS","install_from_source url source requires a non-empty url");return t;case"path":if(!t.path||0===t.path.trim().length)throw new k("INVALID_ARGS","install_from_source path source requires a non-empty path");return t;case"github-actions-artifact":throw new k("UNSUPPORTED_OPERATION","install_from_source github-actions-artifact sources require a compatible remote daemon");default:throw new k("UNSUPPORTED_OPERATION",`install_from_source ${String(t.kind)} sources require a compatible remote daemon`)}}(t),(i=t.meta?.uploadedArtifactId)&&"path"===e.kind?{source:{kind:"path",path:ig(i,t.meta?.tenantId)},cleanup:()=>{iy(i)}}:{source:e,cleanup:()=>{}}),s=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 k("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),l=await me({session:a,flags:t.flags});if(!d7("install",l))return dG("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=t9(t.meta?.requestId),d=async(e,i)=>{let l;try{var u;l=await mt({prepared:e,retention:s,req:t,session:a,sessionName:r});let o=await i(l),d=ez(o,(u=o,`Installed: ${eZ(u)}`));return!function(e){let{session:t,sessionStore:r,req:n,data:a}=e;t&&r.recordAction(t,{command:"install_source",positionals:[],flags:n.flags??{},result:a})}({session:a,sessionStore:n,req:t,data:d}),{ok:!0,data:d}}catch(e){throw l&&await f6(l.materializationId,t.meta?.tenantId).catch(()=>{}),e}finally{await e.cleanup(),o.cleanup()}};if("ios"===l.platform){let{installIosInstallablePath:e}=await Promise.resolve(tX),{prepareIosInstallArtifact:t}=await Promise.resolve(tY),r=await t(o.source,{signal:u});return await d(r,async t=>{if(await e(l,r.installablePath),!r.bundleId)throw new k("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");return{...mr(t),bundleId:r.bundleId,...r.appName?{appName:r.appName}:{},launchTarget:r.bundleId}})}let{prepareAndroidInstallArtifact:c}=await import("../1769.js"),{installAndroidInstallablePathAndResolvePackageName:p}=await import("../1769.js"),f=await c(o.source,{signal:u});return await d(f,async e=>{let t=await p(l,f.installablePath,f.packageName);if(!t)throw new k("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:r}=await import("../1769.js"),n=r(t);return{...mr(e),packageName:t,...n?{appName:n}:{},launchTarget:t}})}catch(e){return{ok:!1,error:D(e)}}}async function ma(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new k("INVALID_ARGS","release_materialized_paths requires a materializationId");return await f6(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:D(e)}}}let mi="shared_prefs/ReactNativeDevPrefs.xml",mo="debug_http_host",ms="dev_server_https",ml="RCT_jsLocation",mu="RCT_packager_scheme",md="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",mc='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function mp(e){return void 0!==ev(e)}async function mf(e){let{device:t,appId:r,runtime:n}=e;if(!r)return;let a=ev(n);if(a){if("android"===t.platform)return void await mh(t,r,a);"ios"===t.platform&&"simulator"===t.kind&&await mv(t,r,a)}}async function mm(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await mw(t,r);"ios"===t.platform&&"simulator"===t.kind&&await mI(t,r)}}async function mh(e,t,r){var n,a,i,o,s,l;let u,d;m_(t);let c=(n=await mg(e,t),a=mo,i=`${r.host}:${r.port}`,u=` <string name="${mN(a)}">${mN(i)}</string>`,mS(mb(n,a),u));o=c,s=ms,l="https"===r.scheme,d=` <boolean name="${mN(s)}" value="${l?"true":"false"}" />`,c=mS(mb(o,s),d),await my(e,t,c)}async function mw(e,t){m_(t);let r=await mg(e,t),n=mb(r,mo),a=mb(n,ms);a!==r&&await my(e,t,a)}async function mg(e,t){let r=await R(e,["shell","run-as",t,"cat",mi],{allowFailure:!0});return 0!==r.exitCode?mc:mA(r.stdout)}async function my(e,t,r){let n=["shell","run-as",t,"id"],a=await R(e,n,{allowFailure:!0});if(0!==a.exitCode){let e=mx(a.stdout,a.stderr);throw new k("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:n,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:e?md:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await R(e,["shell","run-as",t,"mkdir","-p","shared_prefs"]),await R(e,["shell","run-as",t,"tee",mi],{stdin:r.trimEnd()})}catch(n){let e=M(n);if("TOOL_MISSING"===e.code)throw e;let r=mx("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new k("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?md:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function mv(e,t,r){await rm(ry(e,["spawn",e.id,"defaults","write",t,ml,"-string",`${r.host}:${r.port}`])),await rm(ry(e,["spawn",e.id,"defaults","write",t,mu,"-string",r.scheme]))}async function mI(e,t){await rm(ry(e,["spawn",e.id,"defaults","delete",t,ml]),{allowFailure:!0}),await rm(ry(e,["spawn",e.id,"defaults","delete",t,mu]),{allowFailure:!0})}function mA(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
57
+ `:mc}function mS(e,t){return mA(e).replace("</map>",`${t}
58
+ </map>`)}function mb(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return mA(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function m_(e){if("binary"!==Q(e))return;let t=eo(e);throw new k("INVALID_ARGS",t,{package:e,hint:t})}function mN(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function mx(e,t){let r=`${e}
59
+ ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}let mM=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function mD(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function mk(e,t){if(void 0!==e){if("string"!=typeof e)throw new k("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return eg(e)}}function mE(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new k("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function mO(e){if("ios"===e||"android"===e)return e}async function mP(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:n,session:a}=e;!t||!a?.appBundleId||!mp(r)||mp(n)||await mm({device:a.device,appId:a.appBundleId})}async function mC(e){var t,r;let{req:n,sessionName:a,sessionStore:i}=e,o=(n.positionals?.[0]??"show").toLowerCase(),s=i.get(a),l=i.getRuntimeHints(a);if(!["set","show","clear"].includes(o))return dG("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){mp(l)&&s?.appBundleId&&await mm({device:s.device,appId:s.appBundleId});let e=i.clearRuntimeHints(a);return{ok:!0,data:{session:a,cleared:e}}}if("show"===o)return{ok:!0,data:{session:a,configured:!!l,runtime:l}};let u=mO(n.flags?.platform??l?.platform??s?.device.platform);if(!u)return dG("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!==u)return dG("INVALID_ARGS",`runtime set targets ${u}, but session "${a}" is already bound to ${s.device.platform}.`);let d={platform:(t=n.flags,r={platform:u,metroHost:eg(t?.metroHost),metroPort:mE(t?.metroPort),bundleUrl:eg(t?.bundleUrl),launchUrl:eg(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===mD(d)?dG("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(i.setRuntimeHints(a,d),{ok:!0,data:{session:a,configured:!0,runtime:d}})}let mL="open-command-roundtrip",mR="Not implemented for this platform in this release.",mT=new Set(["app","desktop","frontmost-app"]);async function m$(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await lS();return{appBundleId:t.bundleId,appName:t.appName}}function mF(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}function mU(e){return Math.round(10*e)/10}function mG(e){return Math.round(10*e)/10}let mV="adb-shell-dumpsys-gfxinfo-framestats";function mj(e,t,r){let n=t.get(r);if(void 0===n)return null;let a=Number(e[n]);return Number.isFinite(a)?a:null}function mB(e){return 0===e.length?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function mq(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function mH(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=e.match(RegExp(`^\\s*${r}:\\s*([0-9][0-9,]*)`,"im"));if(n)return mF(n[1])??void 0}async function mW(e,t,r={}){var n,a,i,o,s,l,u,d;let c=e6(e,r.adb);try{let u,d,p,f,m,h,w,g,y,v,I,A=(n=(await c(["shell","dumpsys","gfxinfo",t,"framestats"],{timeoutMs:15e3})).stdout,a=new Date().toISOString(),function(e,t){if(/no process found for:/i.test(e))throw new k("COMMAND_FAILED",`Android gfxinfo did not find a running process for ${t}`,{metric:"fps",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect."})}(n,t),p=function(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??"",r=mH(t,"Total frames rendered"),n=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(void 0===r||!n)return;let a=mF(n[1])??void 0,i=Number(n[2]);if(void 0===a||!Number.isFinite(i)||r<0)return;let o=mH(t,"Uptime"),s=mH(t,"Stats since");return{droppedFramePercent:mU(i),droppedFrameCount:a,totalFrameCount:r,sampleWindowMs:function(e){let{uptimeMs:t,statsSinceNs:r}=e;if(void 0===t||void 0===r)return;let n=t-Math.round(r/1e6);return n>=0?n:void 0}({uptimeMs:o,statsSinceNs:s}),uptimeMs:o,statsSinceNs:s}}(n),f=function(e){let t=[],r=null;for(let a of e.split("\n")){var n;let e=a.trim();if(0===e.length||"---PROFILEDATA---"===e)continue;let i=e.split(",").map(e=>e.trim());if((n=i).includes("IntendedVsync")&&n.includes("FrameCompleted")){r=new Map(i.map((e,t)=>[e,t]));continue}let o=function(e,t){if(!t||e.length<t.size)return;let r=mj(e,t,"Flags"),n=mj(e,t,"IntendedVsync"),a=mj(e,t,"FrameCompleted");if(0===r&&null!==n&&null!==a&&!(n<=0)&&!(a<=n))return{intendedVsyncNs:n,frameCompletedNs:a,durationNs:a-n}}(i,r);o&&t.push(o)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}(n),m=function(e,t,r){let n=function(e){var t;let r=(t=e.map(e=>e.intendedVsyncNs),[...new Set(t.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)),n=[];for(let e=1;e<r.length;e+=1){let t=r[e]-r[e-1];t>=4e6&&t<=5e7&&n.push(t)}if(0!==n.length){let e,t;return e=[...n].sort((e,t)=>e-t),t=Math.floor(e.length/2),e.length%2==1?e[t]:(e[t-1]+e[t])/2}}(e);if(t||0!==e.length||function(e){throw new k("COMMAND_FAILED",`Failed to parse Android framestats output for ${e}`,{metric:"fps",package:e,hint:"Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging."})}(r),t||void 0!==n)return n;throw new k("COMMAND_FAILED",`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:"fps",package:r,hint:"Retry perf after a longer interaction window so consecutive Android frame timestamps are available."})}(f,p,t),h=Date.parse(a),w=function(e){let{frames:t,measuredAtMs:r,summary:n}=e,a=mB(t),i=n?.statsSinceNs,o=i??a.firstFrameNs,s=mq(o,a.lastFrameNs),l=n?.sampleWindowMs??s;if(!Number.isFinite(r)||n?.uptimeMs===void 0||void 0===o)return{sampleWindowMs:l,windowStartNs:o};let u=r-n.uptimeMs;return{sampleWindowMs:l,windowStartNs:o,windowStartedAt:new Date(u+o/1e6).toISOString(),windowEndedAt:function(e){let{deviceBootWallClockMs:t,measuredAtMs:r,summaryStartNs:n,lastFrameNs:a}=e;return void 0!==n?new Date(r).toISOString():void 0===a?void 0:new Date(t+a/1e6).toISOString()}({deviceBootWallClockMs:u,measuredAtMs:r,summaryStartNs:i,lastFrameNs:a.lastFrameNs}),timestampSource:"estimated-from-device-uptime"}}({frames:f,measuredAtMs:h,summary:p}),g=function(e){let{frames:t,frameDeadlineNs:r,summaryDroppedFrameCount:n}=e;return void 0!==n?n<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,n).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs):void 0===r?[]:t.filter(e=>e.durationNs>r)}({frames:f,frameDeadlineNs:m,summaryDroppedFrameCount:p?.droppedFrameCount}),y=p?.sampleWindowMs??w.sampleWindowMs??function(e){if(0===e.length)return;let t=mB(e);return mq(t.firstFrameNs,t.lastFrameNs)}(f),i=p,o=f,s=g,u=i?.totalFrameCount??o.length,d=i?.droppedFrameCount??s.length,v={totalFrameCount:u,droppedFrameCount:d,droppedFramePercent:i?.droppedFramePercent??(u>0?mU(d/u*100):0)},I=function(e){let{droppedFrames:t,timing:r,measuredAtMs:n,summary:a}=e;if(0===t.length)return;let i=function(e){let{frames:t,windowStartNs:r,measuredAtMs:n,uptimeMs:a}=e;if(0===t.length||void 0===r)return[];let i=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}i.push(o),o=[e]}return o.length>0&&i.push(o),i.map(e=>(function(e){let{frames:t,windowStartNs:r,measuredAtMs:n,uptimeMs:a}=e,i=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((i-r)/1e6)),l=Math.max(s,Math.round((o-r)/1e6)),u=void 0!==a&&Number.isFinite(n)?n-a:void 0;return{startOffsetMs:s,endOffsetMs:l,startAt:void 0===u?void 0:new Date(u+i/1e6).toISOString(),endAt:void 0===u?void 0:new Date(u+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:mG(Math.max(...t.map(e=>e.durationNs))/1e6)}})({frames:e,windowStartNs:r,measuredAtMs:n,uptimeMs:a})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}({frames:t,windowStartNs:r.windowStartNs,measuredAtMs:n,uptimeMs:a?.uptimeMs});return i.length>0?i:void 0}({droppedFrames:g,timing:w,measuredAtMs:h,summary:p}),{...v,sampleWindowMs:y,...(l=m,{frameDeadlineMs:void 0===l?void 0:mG(l/1e6),refreshRateHz:void 0===l?void 0:mG(1e9/l)}),windowStartedAt:w.windowStartedAt,windowEndedAt:w.windowEndedAt,timestampSource:w.timestampSource,measuredAt:a,method:mV,source:p?"android-gfxinfo-summary":"framestats-rows",worstWindows:I&&I.length>0?I:void 0});return await mz(e,t,r),A}catch(e){throw u=t,(d=e)instanceof k?new k(d.code,d.message,{...d.details??{},metric:"fps",package:u},d):new k("COMMAND_FAILED",`Failed to sample Android fps for ${u}`,{metric:"fps",package:u},d)}}async function mz(e,t,r={}){let n=e6(e,r.adb);try{await n(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let mK="adb-shell-dumpsys-cpuinfo",mJ="adb-shell-dumpsys-meminfo";async function mX(e,t,r={}){let n=e6(e,r.adb);try{let e=await n(["shell","dumpsys","cpuinfo"],{timeoutMs:15e3});return function(e,t,r){let n=new Set,a=0;for(let r of e0(e)){var i,o;let e=r.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!e)continue;let s=Number(e[1]),l=e[2];Number.isFinite(s)&&(i=l,o=t,i===o||i.startsWith(`${o}:`))&&(a+=s,n.add(l))}return{usagePercent:mU(a),measuredAt:r,method:mK,matchedProcesses:[...n]}}(e.stdout,t,new Date().toISOString())}catch(e){throw mZ("cpu",t,e)}}async function mY(e,t,r={}){let n=e6(e,r.adb);try{let e=await n(["shell","dumpsys","meminfo",t],{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new k("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 n=mQ(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!==mF(e));if(!r)break;return mF(r)??void 0}}(e);if(void 0===n)throw new k("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:n,totalRssKb:mQ(e,"TOTAL RSS"),measuredAt:r,method:mJ}}(e.stdout,t,new Date().toISOString())}catch(e){throw mZ("memory",t,e)}}function mZ(e,t,r){return r instanceof k?new k(r.code,r.message,{...r.details??{},metric:e,package:t},r):new k("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function mQ(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(n)return mF(n[1])??void 0}async function m0(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return ea(t)?"macos"===e.platform?void 0:"device"===e.kind?F(r,t):void 0:await m1(e,t)}async function m1(e,t){try{let{resolveIosApp:r}=await Promise.resolve(tX);return await r(e,t)}catch{return}}async function m2(e,t){if(!("android"!==e.platform||!t||ea(t)))try{let{resolveAndroidApp:r}=await import("../1769.js"),n=await r(e,t);return"package"===n.type?n.value:void 0}catch{return}}async function m3(e,t,r){if(r||"android"!==e.platform||!t||!ea(t))return r;try{let{getAndroidAppState:t}=await import("../1769.js"),n=await t(e);return n.package?.trim()||r}catch{return r}}async function m5(e,t,r,n){return await m0(e,t,r)??await n(e,t)??("android"===e.platform&&t&&ea(t)?r:void 0)}function m4(e){return dG("INVALID_ARGS",e)}function m8(e,t,r,n){try{return function(e){let{device:t,surfaceFlag:r,openTarget:n,existingSurface:a}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return a??"app";if("linux"===t.platform){if(!r)return"app";let e=tu(r);if(!mT.has(e))throw new k("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&n)throw new k("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new k("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let i=r?tu(r):"app";if("app"!==i&&"menubar"!==i&&n)throw new k("INVALID_ARGS",`open --surface ${i} does not accept an app target`);return i}({device:e,surfaceFlag:t,openTarget:r,existingSurface:n})}catch(e){return dG(e instanceof k?e.code:"INVALID_ARGS",String(e.message))}}function m6(e){let{shouldRelaunch:t,openTarget:r,surface:n,device:a}=e;return t?r&&ea(r)?m4("open --relaunch does not support URL targets."):"app"!==n?m4("open --relaunch is supported only for app surfaces."):"android"===a.platform&&r&&"binary"===Q(r)?m4(eo(r)):null:null}async function m9(e){let{req:t,sessionName:r,sessionStore:n,device:a,surface:i,openTarget:o,existingSession:s}=e;await oY(a);let{appBundleId:l,appName:u}=await m7({device:a,surface:i,openTarget:o,existingAppBundleId:s?.appBundleId}),d=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:n,device:a}=e,i=r.getRuntimeHints(n),o=function(e){let{runtime:t,sessionName:r,platform:n}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new k("INVALID_ARGS","open runtime must be an object.");let a=Object.keys(t).find(e=>!mM.includes(e));if(a)throw new k("INVALID_ARGS",`Invalid open runtime field: ${a}. Supported fields are ${mM.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new k("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new k("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,n),metroHost:mk(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new k("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return mE(e)}}(t.metroPort),bundleUrl:mk(t.bundleUrl,"bundleUrl"),launchUrl:mk(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:n,platform:mO(a.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let n=e.getRuntimeHints(t);if(!n)return;let a=r?.platform,i=mO(a);if(n.platform&&r&&!i)throw new k("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${a}.`);if(n.platform&&i&&n.platform!==i)throw new k("INVALID_ARGS",`Session runtime hints target ${n.platform}, but session "${t}" is bound to ${a}. Clear the runtime hints or use a different session.`);return i&&n.platform!==i?{...n,platform:i}:n}(r,n,a),previousRuntime:i,replacedStoredRuntime:!1}:{runtime:o&&mD(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=M(t);return dG(e.code,e.message,e.details)}}({req:t,sessionStore:n,sessionName:r,device:a});if(!d.ok)return{type:"response",response:d};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=d.data;await mP({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:u,runtime:d.data.runtime}}}async function m7(e){let{device:t,surface:r,openTarget:n,existingAppBundleId:a}=e,i=await m$(r);return{appBundleId:i.appBundleId??await m5(t,n,a,m2),appName:i.appName??n}}let he=new Map;async function ht(e){let{device:t,closeTarget:r,outFlag:n,context:a}=e;"android"!==t.platform&&await nY(t.id),await dC(t,"close",[r],n,a),await dW(t,dV)}async function hr(e){let{runtime:t,device:r,req:n,logPath:a,appBundleId:i,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let u=s[0]?.trim();!u||ea(u)||await dC(r,"open",[l],n.flags?.out,{...co(a,n.flags,i,o)})}async function hn(e){var t,r,n,a;let{req:i,sessionName:o,sessionStore:s,logPath:l,device:u,openTarget:d,openPositionals:c,appName:p,surface:f,appBundleId:m,runtime:h,existingSession:w}=e,g=i.flags?.relaunch===!0,y=w?.trace?.outPath,v=m;if(g&&d){let e=v??d;await ht({device:u,closeTarget:e,outFlag:i.flags?.out,context:{...co(l,i.flags,v??w?.appBundleId,y)}})}await mf({device:u,appId:v,runtime:h});let I="ios"===u.platform&&"app"===f&&c.length>0,A={verbose:i.flags?.verbose,logPath:l,traceLogPath:y,requestId:i.meta?.requestId};I&&v?function(e,t={}){if("ios"===e.platform){if(n6(e,{requestId:t.requestId}))return eM({level:"debug",phase:"ios_runner_session_prewarm_skipped_scoped_provider",data:{deviceId:e.id}});nz(e,t).catch(t=>{eM({level:"warn",phase:"ios_runner_session_prewarm_failed",data:{deviceId:e.id,error:t instanceof Error?t.message:String(t)}})})}}(u,A):I&&function(e,t={}){if("ios"===e.platform){if(n6(e,{requestId:t.requestId}))return eM({level:"debug",phase:"ios_runner_xctestrun_prewarm_skipped_scoped_provider",data:{deviceId:e.id}});ny(e,t).catch(t=>{eM({level:"warn",phase:"ios_runner_xctestrun_prewarm_failed",data:{deviceId:e.id,error:t instanceof Error?t.message:String(t)}})})}}(u,A);let S=Date.now();await dC(u,"open",c,i.flags?.out,{...co(l,i.flags,v)}),await hr({runtime:h,device:u,req:i,logPath:l,appBundleId:v,traceLogPath:y,openPositionals:c}),v=await m3(u,d,v),"android"===u.platform&&v&&await mz(u,v);let b=d?(t=v,{durationMs:Math.max(0,Date.now()-S),measuredAt:new Date().toISOString(),method:mL,appTarget:d,appBundleId:t}):void 0;if(await dW(u,dj),t6(i.meta?.requestId)){let e=t7();return dG(e.code,e.message,e.details)}w&&ct(w,"open",w.snapshot);let _=function(e){let{existingSession:t,sessionName:r,device:n,surface:a,appBundleId:i,appName:o,saveScript:s}=e;return t?{...t,device:n,surface:a,appBundleId:i,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:n,createdAt:Date.now(),surface:a,appBundleId:i,appName:o,recordSession:s,actions:[]}}({existingSession:w,sessionName:o,device:u,surface:f,appBundleId:v,appName:p,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(r=s,n=o,(a=h)&&(0===mD(a)?r.clearRuntimeHints(n):r.setRuntimeHints(n,a)));let N=function(e){let{sessionName:t,appName:r,appBundleId:n,surface:a,startup:i,device:o,runtime:s,runtimeHintCount:l}=e,u={session:t,surface:a};return r&&(u.appName=r),n&&(u.appBundleId=n),i&&(u.startup=i),s&&l(s)>0&&(u.runtime=s),o&&(u.platform=o.platform,u.target=o.target??"mobile",u.device=o.name,u.id=o.id,u.kind=o.kind,"android"===o.platform&&(u.serial=o.id)),o?.platform==="ios"&&(u.device_udid=o.id,u.ios_simulator_device_set=o.simulatorSetPath??null),{...u,...eG(`Opened: ${r??n??t}`)}}({sessionName:o,appName:p,appBundleId:v,surface:f,startup:b,device:u,runtime:h,runtimeHintCount:mD});return s.recordAction(_,{command:"open",positionals:c,flags:i.flags??{},runtime:void 0!==i.runtime?h:void 0,result:N}),s.set(o,_),{ok:!0,data:N}}async function ha(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e;if(a.has(r)){let e=a.get(r);if(!e)return dG("SESSION_NOT_FOUND",`Session "${r}" not found.`);let i=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(i?e.appName:void 0),l=m8(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return i?m4("open --relaunch requires an app name or an active session app."):m4("Session already active. Close it first or pass a new --session name.");let u=m6({shouldRelaunch:i,openTarget:s,surface:l,device:e.device});if(u)return u;let d=await dK(e.device),c=await m9({req:t,sessionName:r,sessionStore:a,device:d,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await hn({req:t,sessionName:r,sessionStore:a,logPath:n,device:d,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let i=t.flags?.relaunch===!0,o=t.positionals?.[0];if(i&&!o)return m4("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:n}=e;return t?r&&ea(r)?m4("open --relaunch does not support URL targets."):"android"===n&&r&&"binary"===Q(r)?m4(eo(r)):null:null}({shouldRelaunch:i,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await op(t.flags??{}),u=m8(l,t.flags?.surface,o);if("string"!=typeof u)return u;let d=m6({shouldRelaunch:i,openTarget:o,surface:u,device:l});return d||await rJ(he,l.id,async()=>{let e=a.toArray().find(e=>e.device.id===l.id);if(e)return dG("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name,hint:`Run agent-device session list and reuse --session ${e.name}, or close that session before opening a new one on this device.`});let i=await m9({req:t,sessionName:r,sessionStore:a,device:l,surface:u,openTarget:o});return"response"===i.type?i.response:await hn({req:t,sessionName:r,sessionStore:a,logPath:n,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:i.details.appBundleId,appName:i.details.appName,runtime:i.details.runtime,surface:u})})}async function hi(e){let t=await R(e,["emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function ho(e){let{device:t,shutdownRequested:r}=e;if(r&&(dH(t)||"android"===t.platform&&"emulator"===t.kind))try{return dH(t)?await le(t):await hi(t)}catch(t){let e=D(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function hs(e){if(await nY(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await lN("dismiss",t).catch(t=>{eM({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function hl(e,t){e.appLog&&await iu(e.appLog),rX(e.device.platform)&&await hs(e),await f9(t).catch(()=>{})}async function hu(e){let t,{req:r,sessionName:n,logPath:a,sessionStore:i}=e,o=i.get(n);if(!o)return dG("SESSION_NOT_FOUND","No active session");o.appLog&&await iu(o.appLog),r.positionals&&r.positionals.length>0&&(rX(o.device.platform)&&await hs(o),await dC(o.device,"close",r.positionals,r.flags?.out,{...co(a,r.flags,o.appBundleId,o.trace?.outPath)}),await dW(o.device,dV)),rX(o.device.platform)&&(t=(r.positionals?.length??0)>0,!dH(o.device)||t||r.flags?.shutdown||o.recording)?await hs(o):rX(o.device.platform)&&eM({level:"debug",phase:"ios_runner_retained_after_close",data:{session:o.name,deviceId:o.device.id}}),mp(i.getRuntimeHints(n))&&o.appBundleId&&await mm({device:o.device,appId:o.appBundleId}).catch(()=>{}),i.recordAction(o,{command:"close",positionals:r.positionals??[],flags:r.flags??{},result:{session:n,...eG(`Closed: ${n}`)}}),r.flags?.saveScript&&(o.recordSession=!0),i.writeSessionLog(o),await f9(n).catch(()=>{}),i.delete(n);let s=await ho({device:o.device,shutdownRequested:r.flags?.shutdown});return s?{ok:!0,data:ez({session:n,shutdown:s},`Closed: ${n}`)}:{ok:!0,data:{session:n,...eG(`Closed: ${n}`)}}}let hd={ios:async(e,t,r)=>{let{reinstallIosApp:n}=await Promise.resolve(tX);return await n(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:n}=await import("../1769.js");return await n(e,t,r)}},hc={ios:async(e,t,r)=>{let{installIosApp:n}=await Promise.resolve(tX),a=await n(e,r,{appIdentifierHint:t});return{bundleId:a.bundleId,appName:a.appName,launchTarget:a.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:n}=await import("../1769.js"),a=await n(e,r);return{package:a.packageName,appName:a.appName,launchTarget:a.launchTarget}}};async function hp(e){let{req:t,command:r,sessionName:n,sessionStore:a,deployOps:i}=e,o=a.get(n),l=t.flags??{},u=dB(r,o,l);if(u)return u;let d=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!d||!c)return dG("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let p=t.meta?.uploadedArtifactId;try{var f;let e,n=p?ig(p,t.meta?.tenantId):aD.expandHome(c);if(!s.existsSync(n))return dG("INVALID_ARGS",`App binary not found: ${n}`);let u=await dz({session:o,flags:l,ensureReady:!1});if(!d7(r,u))return dG("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===u.platform){let t=await i.ios(u,d,n),r=t.bundleId;e=r?{app:d,appPath:n,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:d,appPath:n,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await i.android(u,d,n),r=t.package;e=r?{app:d,appPath:n,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:d,appPath:n,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=ez(e,(f=e,`Installed: ${f.appName??eH(f)}`));return o&&a.recordAction(o,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&iy(p)}}async function hf(e,t,r){return await tK(e,t,r)}async function hm(e){let{req:t,sessionName:r,sessionStore:n}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:n.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("devices"===t.command)try{let e=er(t.flags?.androidDeviceAllowlist),r=t.flags?.platform,n=rZ({simulatorSetPath:T(t.flags?.iosSimulatorDeviceSet),platform:r,target:t.flags?.target}),a=await ow({platform:r,target:t.flags?.target,deviceName:t.flags?.device,udid:t.flags?.udid,serial:t.flags?.serial,iosSimulatorSetPath:n,androidSerialAllowlist:e?Array.from(e).sort():void 0}),i=r?a.filter(e=>{var t,n;return t=e,!(n=r)||("apple"===n?rX(t.platform):t.platform===n)}):a,o=(t.flags?.target?i.filter(e=>(e.target??"mobile")===t.flags?.target):i).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=M(t);return dG(e.code,e.message,e.details)}if("apps"===t.command){let e=n.get(r),a=t.flags??{},i=dB(t.command,e,a);if(i)return i;let o=await dz({session:e,flags:a,ensureReady:!0});if(!d7("apps",o))return dG("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=el(t.flags?.appsFilter);return rX(o.platform)?{ok:!0,data:{apps:(await uI(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}:{ok:!0,data:{apps:(await X(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function hh(e){let{ensureAndroidEmulatorBooted:t}=await import("../1769.js");return await t(e)}let hw='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',hg='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function hy(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r),i=t.flags??{},o=i.platform;if(!a&&"string"==typeof i?.session&&i.session.trim().length>0)return dG("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=dB("appstate",a,i);if(s)return s;let l=rX(a?.device.platform)&&function(e,t){if(!t)return!1;if(!dq(e))return!0;let r=e?.platform;return!(r&&!rY(t.device.platform,r)||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(i,a);if("ios"===o&&!l)return dG("SESSION_NOT_FOUND",hw);if("macos"===o&&!l)return dG("SESSION_NOT_FOUND",hg);if(l&&a){let e=a.appName??a.appBundleId;if(!a.appName&&!a.appBundleId){if("macos"===a.device.platform&&a.surface&&"app"!==a.surface&&"frontmost-app"!==a.surface)return{ok:!0,data:{platform:a.device.platform,appName:a.surface,appBundleId:a.appBundleId,source:"session",surface:a.surface}};let e="macos"===a.device.platform?"macOS":"iOS";return dG("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:a.device.platform,appName:e??"unknown",appBundleId:a.appBundleId,source:"session",surface:a.surface??"app",..."ios"===a.device.platform?{device_udid:a.device.id,ios_simulator_device_set:a.device.simulatorSetPath??null}:{}}}}let u=await dz({session:a,flags:i,ensureReady:!0});if("ios"===u.platform)return dG("SESSION_NOT_FOUND",hw);if("macos"===u.platform)return dG("SESSION_NOT_FOUND",hg);let{getAndroidAppState:d}=await import("../1769.js"),c=await d(u);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function hv(e){let{req:t,sessionName:r,sessionStore:n}=e;if("boot"===t.command){let e,a=n.get(r),i=t.flags??{},o=dB(t.command,a,i);if(o)return o;let s="android"===(i.platform??a?.device.platform),l=!0===i.headless;if(l&&!s)return dG("INVALID_ARGS","boot --headless is supported only for Android emulators.");let u=dJ({flags:i,sessionDevice:a?.device}),d=s&&!!u,c=!1;try{e=await dz({session:a,flags:i,ensureReady:!1})}catch(r){let t=M(r);if(s&&l&&!u&&"DEVICE_NOT_FOUND"===t.code)return dG("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!d||"DEVICE_NOT_FOUND"!==t.code||!u)throw r;e=await hh({avdName:u,serial:i.serial,headless:l}),c=!0}if(i.target&&(e.target??"mobile")!==i.target)return dG("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${i.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return dG("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=dJ({flags:i,sessionDevice:a?.device,resolvedDevice:e});if(!t)return dG("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await hh({avdName:t,serial:i.serial,headless:!0})}await oY(e)}else("android"!==e.platform||!0!==e.booted)&&await oY(e);return d7("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:dG("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await hy({req:t,sessionName:r,sessionStore:n}):null}function hI(e,t){for(let r of e){if(t(r))return r;let e=hI(r.children,t);if(e)return e}}function hA(e,t){let r=[];for(let n of e)t(n)&&r.push(n),r.push(...hA(n.children,t));return r}function hS(e,t){let r=hI(e,e=>"schema"===e.name&&e.attributes.name===t);return r?r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}):[]}function hb(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 h_(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:hb(e):null}let hN="xctrace-animation-hitches";function hx(e,t){let r=r5(e),n=hS(r,t);return{rows:0===n.length?[]:hA(r,e=>"row"===e.name),schema:n}}function hM(e,t){for(let r of e)hM(r.children,t),r.attributes.id&&t.set(r.attributes.id,{numberValue:hb(r),process:hD(r)})}function hD(e){if(!e||e.children.some(e=>"sentinel"===e.name))return null;let t=hb(hI(e.children,e=>"pid"===e.name)),r=(e.attributes.fmt??"").replace(/\s+\(\d+\)$/,"").trim();return null===t&&0===r.length?null:{pid:t??void 0,name:r.length>0?r:void 0}}let hk="ps-process-snapshot",hE="ps-process-snapshot",hO="xctrace-activity-monitor",hP="xctrace-activity-monitor";async function hC(e,t){if("ios"===e.platform&&"device"===e.kind)return await hB(e,t);let r=await hj(e,t),n=await hJ(e,r);if(0===n.length)throw new k("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 a=new Date().toISOString();return hX({usagePercent:n.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:n.reduce((e,t)=>e+t.rssKb,0),measuredAt:a,matchedProcesses:[r.executableName],cpuMethod:hk,memoryMethod:hE})}async function hL(e,t){var r;let n,a,i,o,s,l;if("ios"!==e.platform||"device"!==e.kind)throw new k("COMMAND_FAILED","Apple frame-health sampling is currently available only on connected iOS devices.",{metric:"fps",platform:e.platform,deviceKind:e.kind});let u=await hq(e,t),d=await hR(e,t,u);return n=hx((r={hitchesXml:d.hitchesXml,frameLifetimesXml:d.frameLifetimesXml,displayInfoXml:d.displayInfoXml,processIds:u.map(e=>e.pid),processNames:ao(u.map(e=>p.basename(g(e.executable)))),windowStartedAt:d.windowStartedAt,windowEndedAt:d.windowEndedAt,measuredAt:d.windowEndedAt}).frameLifetimesXml,"hitches-frame-lifetimes").rows.length,a=function(e){if(!e)return;let{rows:t,schema:r}=hx(e,"device-display-info"),n=r.indexOf("max-refresh-rate");if(n<0)return;let a=new Map;for(let e of t){hM(e.children,a);let t=h_(e.children[n],a);if(null!==t&&t>0)return t}}(r.displayInfoXml),o=(i=(function(e){let t,r,n=r5(e),a=Object.values(r={start:(t=hS(n,"hitches")).indexOf("start"),duration:t.indexOf("duration"),process:t.indexOf("process"),isSystem:t.indexOf("is-system")}).every(e=>e>=0)?r:null;if(!a)return[];let i=new Map;return hA(n,e=>"row"===e.name).map(e=>(function(e,t,r){var n,a,i;let o;if(hM(e.children,r),!0===(n=e.children[t.isSystem],null===(o=h_(n,r))?null:0!==o))return null;let s=h_(e.children[t.start],r),l=h_(e.children[t.duration],r);if(null===s||null===l)return null;let u=(a=e.children[t.process],i=r,a?a.attributes.ref?i.get(a.attributes.ref)?.process??null:hD(a):null);return{startNs:s,durationNs:l,pid:u?.pid,processName:u?.name}})(e,a,i)).filter(e=>!!e)})(r.hitchesXml).filter(e=>{var t,n,a;return t=e,n=r.processIds,a=r.processNames,!!(void 0!==t.pid&&n.includes(t.pid))||!!t.processName&&a.includes(t.processName)})).length,s=Math.max(0,Math.round(Date.parse(r.windowEndedAt)-Date.parse(r.windowStartedAt))),l=function(e,t){if(0===e.length)return[];let r=[...e].sort((e,t)=>e.startNs-t.startNs),n=[],a=[];for(let e of r){let t=a.at(-1);if(!t||e.startNs-(t.startNs+t.durationNs)<=5e8){a.push(e);continue}n.push(a),a=[e]}return a.length>0&&n.push(a),n.map(e=>{var r,n;let a,i,o,s;return r=e,n=t,a=Math.min(...r.map(e=>e.startNs)),i=Math.max(...r.map(e=>e.startNs+e.durationNs)),s=Math.max(o=Math.max(0,Math.round(a/1e6)),Math.round(i/1e6)),{startOffsetMs:o,endOffsetMs:s,startAt:new Date(n+o).toISOString(),endAt:new Date(n+s).toISOString(),missedDeadlineFrameCount:r.length,worstFrameMs:mU(Math.max(...r.map(e=>e.durationNs))/1e6)}}).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}(i,Date.parse(r.windowStartedAt)),{droppedFramePercent:n>0?mU(o/n*100):0,droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:s,windowStartedAt:r.windowStartedAt,windowEndedAt:r.windowEndedAt,measuredAt:r.measuredAt,method:hN,matchedProcesses:[...new Set(i.map(e=>e.processName).filter(e=>"string"==typeof e&&e.length>0))],frameDeadlineMs:void 0===a?void 0:mU(1e3/a),refreshRateHz:a,worstWindows:l.length>0?l:void 0}}async function hR(e,t,r){let n=await u.mkdtemp(p.join(d.tmpdir(),"agent-device-ios-frame-perf-")),a=p.join(n,"animation-hitches.trace"),i=p.join(n,"hitches.xml"),o=p.join(n,"frame-lifetimes.xml"),s=p.join(n,"display-info.xml");try{let n=await hT({device:e,appBundleId:t,tracePath:a,template:"Animation Hitches",duration:"2s",targetPids:r.map(e=>e.pid),validateTraceOutput:!0,failureMessage:`Failed to record iOS frame-health sample for ${t}`});await hU(e,t,a,"hitches",i),await hU(e,t,a,"hitches-frame-lifetimes",o);let l=await hG(e,t,a,"device-display-info",s);return{windowStartedAt:n.startedAt,windowEndedAt:n.endedAt,hitchesXml:await u.readFile(i,"utf8"),frameLifetimesXml:await u.readFile(o,"utf8"),displayInfoXml:l?await u.readFile(s,"utf8"):void 0}}finally{await u.rm(n,{recursive:!0,force:!0}).catch(()=>{})}}async function hT(e){let{device:t,appBundleId:r,tracePath:n,template:a,duration:i}=e,o=e.allProcesses?["--all-processes"]:(e.targetPids??[]).flatMap(e=>["--attach",String(e)]),s=["xctrace","record","--template",a,"--device",t.id,...o,"--time-limit",i,"--output",n,"--quiet","--no-prompt"],l=await h$(s,e.tracePath);if(0===l.result.exitCode)return e.validateTraceOutput&&await hF(e,l.result.stdout,l.result.stderr),{startedAt:l.startedAt,endedAt:l.endedAt,capturedAtMs:l.capturedAtMs};throw new k("COMMAND_FAILED",e.failureMessage,{cmd:"xcrun",args:s,exitCode:l.result.exitCode,stdout:l.result.stdout,stderr:l.result.stderr,appBundleId:r,deviceId:t.id,hint:hZ(l.result.stdout,l.result.stderr)})}async function h$(e,t){let r;for(let n=1;n<=3;n+=1){n>1&&(await u.rm(t,{recursive:!0,force:!0}).catch(()=>{}),await new Promise(e=>setTimeout(e,1500)));let a=new Date().toISOString(),i=await rm(e,{allowFailure:!0,timeoutMs:6e4});if(r={result:i,startedAt:a,endedAt:new Date().toISOString(),capturedAtMs:Date.now()},0===i.exitCode||!function(e){let t=`${e.stdout}
60
+ ${e.stderr}`.toLowerCase();return t.includes("_lockkperf")||t.includes("could not lock kperf")||t.includes("likely another session just started")}(i))break}return r}async function hF(e,t,r){let n=await u.stat(e.tracePath).catch(()=>null);if(!(n?.isDirectory()===!0?(await u.readdir(e.tracePath).catch(()=>[])).length>0:(n?.size??0)>0))throw new k("COMMAND_FAILED",`${e.failureMessage}: xctrace produced no trace data`,{tracePath:e.tracePath,appBundleId:e.appBundleId,deviceId:e.device.id,stdout:t,stderr:r,hint:"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf."})}async function hU(e,t,r,n,a){let i=["xctrace","export","--input",r,"--xpath",`/trace-toc/run/data/table[@schema="${n}"]`,"--output",a],o=await rm(i,{allowFailure:!0,timeoutMs:15e3});if(0!==o.exitCode)throw new k("COMMAND_FAILED",`Failed to export iOS device ${n} data`,{cmd:"xcrun",args:i,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:hZ(o.stdout,o.stderr)})}async function hG(e,t,r,n,a){try{return await hU(e,t,r,n,a),!0}catch{return!1}}async function hV(e){let t=r5(e),r=hS(t,"activity-monitor-process-live");if(0===r.length)throw new k("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let n=r.indexOf("pid"),a=r.indexOf("process"),i=r.indexOf("cpu-total"),o=r.indexOf("memory-real");if(n<0||a<0||i<0||o<0)throw new k("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let s=hA(t,e=>"row"===e.name),l=[],u=new Map;for(let e of s){var d,c;let t=e.children;if(0===t.length)continue;for(let e of t){let t=hI(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:hb(e),processName:hY(e)})}let r=h_(t[n],u),s=(d=t[a],c=u,d?d.attributes.ref?c.get(d.attributes.ref)?.processName??null:hY(d):null);null!==r&&Number.isFinite(r)&&s&&l.push({pid:r,processName:s,cpuTimeNs:h_(t[i],u),residentMemoryBytes:h_(t[o],u)})}return l}async function hj(e,t){let r="macos"===e.platform?await hz(t):await hK(e,t),n="macos"===e.platform?p.join(r,"Contents","Info.plist"):p.join(r,"Info.plist"),a=await lr(n,"CFBundleExecutable");if(!a)throw new k("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:a,executablePath:"macos"===e.platform?p.join(r,"Contents","MacOS",a):p.join(r,a)}}async function hB(e,t){let r=await hq(e,t),n=await hH(e,t),a=await hH(e,t),i=hW(await hV(n.xml),r,t,e),o=hW(await hV(a.xml),r,t,e),s=a.capturedAtMs-n.capturedAtMs;if(s<=0)throw new k("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===i.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new k("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 hX({usagePercent:Math.max(0,o.cpuTimeNs-i.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(a.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:hO,memoryMethod:hP})}async function hq(e,t){let r=(await oq(e,"all")).find(e=>e.bundleId===t);if(!r)throw new k("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new k("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let n=r.url.replace(/\/$/,""),a=g(n),i=(await oH(e)).filter(e=>e.executable.startsWith(`${n}/`));if(0===i.length)throw new k("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:a,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return i}async function hH(e,t){let r=await u.mkdtemp(p.join(d.tmpdir(),"agent-device-ios-perf-")),n=p.join(r,"sample.trace"),a=p.join(r,"activity-monitor-process-live.xml");try{let r=await hT({device:e,appBundleId:t,tracePath:n,template:"Activity Monitor",duration:"1s",allProcesses:!0,failureMessage:`Failed to record iOS device Activity Monitor sample for ${t}`});return await hU(e,t,n,"activity-monitor-process-live",a),{capturedAtMs:r.capturedAtMs,xml:await u.readFile(a,"utf8")}}finally{await u.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function hW(e,t,r,n){let a=new Set(t.map(e=>e.pid)),i=new Set(t.map(e=>p.basename(g(e.executable)))),o=e.filter(e=>a.has(e.pid)||i.has(e.processName));if(0===o.length)throw new k("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:n.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let s=new Map;for(let e of o){let t=s.get(e.pid);if(!t){s.set(e.pid,e);continue}s.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:hQ(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:hQ(t.residentMemoryBytes,e.residentMemoryBytes)})}let l=[...s.values()],u=l.map(e=>e.cpuTimeNs).filter(e=>null!==e),d=l.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:u.length>0?u.reduce((e,t)=>e+t,0):null,residentMemoryBytes:d.length>0?d.reduce((e,t)=>e+t,0):null,matchedProcesses:ao(l.map(e=>e.processName))}}async function hz(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await rf("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new k("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let n=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!n)throw new k("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return n}async function hK(e,t){let r=ry(e,["get_app_container",e.id,t,"app"]),n=await rm(r,{allowFailure:!0,timeoutMs:15e3});if(0!==n.exitCode)throw new k("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let a=n.stdout.trim();if(0===a.length)throw new k("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return a}async function hJ(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:ry(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e0(e)){let e=r.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!e)continue;let n=Number(e[1]),a=Number(e[2]),i=Number(e[3]),o=e[4].trim();Number.isFinite(n)&&Number.isFinite(a)&&Number.isFinite(i)&&t.push({pid:n,cpuPercent:a,rssKb:i,command:o})}return t})(("macos"===e.platform?await rf("ps",r,{timeoutMs:15e3}):await rm(r,{timeoutMs:15e3})).stdout).filter(e=>{var r,n;let a;return r=e.command,n=t,a=function(e){let[t=""]=e.trim().split(/\s+/,1);return t}(r),!!(n.executablePath&&(r===n.executablePath||a===n.executablePath||r.startsWith(`${n.executablePath} `)))||p.basename(a)===n.executableName})}function hX(e){return{cpu:{usagePercent:mU(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 hY(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function hZ(e,t){let r=oK(e,t);if(r)return r;let n=`${e}
61
+ ${t}`.toLowerCase();return n.includes("no device matched")||n.includes("failed to find device")?oz:n.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 hQ(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function h0(e,t={}){var r,n,a;let i,o,s,l,u=(s=(o=(i=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===mL&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:mL,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)}((r=e).actions)).at(-1))?{available:!0,lastDurationMs:o.durationMs,lastMeasuredAt:o.measuredAt,method:mL,sampleCount:i.length,samples:i}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:mL},{session:r.name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{startup:s,fps:{available:!1,reason:"Dropped-frame sampling is currently available only on Android."},memory:{available:!1,reason:mR},cpu:{available:!1,reason:mR}},sampling:{startup:{method:mL,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:mJ,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:mK,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:mV,description:"Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.",unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}};var t=e.device;let r="ios"===t.platform&&"device"===t.kind?{method:hN,description:"Rendered-frame hitch health from xctrace Animation Hitches on connected iOS devices. Dropped frames are counted from native hitch rows for the attached app process, with total frames from the same trace frame-lifetime table.",unit:"percent",primaryField:"droppedFramePercent",window:"short 2s xctrace Animation Hitches record of the active app process",resetsAfterRead:!1}:{method:hN,description:"Unavailable on iOS simulators and macOS because local Apple tooling does not expose reliable app frame hitches for these targets.",unit:"percent",primaryField:"droppedFramePercent"};if("ios"===t.platform&&"device"===t.kind)return{fps:r,memory:{method:hP,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:hO,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let n="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{fps:r,memory:{method:hE,description:`Resident memory snapshot from ${n}`,unit:"kB"},cpu:{method:hk,description:`Recent CPU usage snapshot from ${n}`,unit:"percent"}}}(r)}});return"android"!==(n=e).device.platform&&"ios"!==n.device.platform&&"macos"!==n.device.platform||(e.appBundleId?"android"===e.device.platform?await h1(u,e,t):await h2(u,e):(a=u,l="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.",a.metrics.fps={available:!1,reason:l},a.metrics.memory={available:!1,reason:l},a.metrics.cpu={available:!1,reason:l})),u}async function h1(e,t,r){let n=await h3(t,r);e.metrics.memory=h8(n.memory),e.metrics.cpu=h8(n.cpu),e.metrics.fps=h6(h8(n.fps),t)}async function h2(e,t){let r=await h5(t);e.metrics.memory=h8(r.memory),e.metrics.cpu=h8(r.cpu),e.metrics.fps=h6(h8(r.fps),t)}async function h3(e,t){let r=e.appBundleId,n={adb:t.androidAdb},[a,i,o]=await Promise.allSettled([mY(e.device,r,n),mX(e.device,r,n),mW(e.device,r,n)]);return{memory:a,cpu:i,fps:o}}async function h5(e){let t=e.appBundleId,r=await h4(hL(e.device,t)),n=await h4(hC(e.device,t));if("fulfilled"===n.status){let e=n.value;return{memory:{status:"fulfilled",value:e.memory},cpu:{status:"fulfilled",value:e.cpu},fps:r}}return{memory:{status:"rejected",reason:n.reason},cpu:{status:"rejected",reason:n.reason},fps:r}}async function h4(e){try{return{status:"fulfilled",value:await e}}catch(e){return{status:"rejected",reason:e}}}function h8(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=D(e.reason);return{available:!1,reason:t.message,error:t}}function h6(e,t){var r,n;let a,i;if(!0!==e.available)return e;let o=(r=t.actions,a=h9((n=e).windowStartedAt),i=h9(n.windowEndedAt)??h9(n.measuredAt),void 0===a||void 0===i?[]:r.filter(e=>e.ts>=a&&e.ts<=i).map(e=>({command:e.command,at:new Date(e.ts).toISOString(),offsetMs:Math.max(0,Math.round(e.ts-a)),target:function(e){let t=e.result;if(t)for(let e of["refLabel","ref","appName","appBundleId"]){let r=t[e];if("string"==typeof r&&r.length>0)return r}}(e)})).slice(-12));return 0===o.length?e:{...e,relatedActions:o}}function h9(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let h7=["path","start","stop","doctor","mark","clear"],we=`logs requires ${h7.slice(0,-1).join(", ")}, or ${h7.at(-1)}`,wt=["dump","log"],wr=`network requires ${wt.join(" or ")}`,wn=["summary","headers","body","all"],wa=`network include mode must be one of: ${wn.join(", ")}`;async function wi(e){let{req:t}=e;return"perf"===t.command?wo(e):"logs"===t.command?ws(e):"network"===t.command?wp(e):null}async function wo(e){let{sessionName:t,sessionStore:r,androidAdbExecutor:n}=e,a=r.get(t);if(!a)return dG("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await h0(a,{androidAdb:n})}}catch(e){return{ok:!1,error:D(e)}}}async function ws(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return dG("SESSION_NOT_FOUND","logs requires an active session");if(!d7("logs",a.device))return dG("UNSUPPORTED_OPERATION","logs is not supported on this device");let i=(t.positionals?.[0]??"path").toLowerCase(),o=!!t.flags?.restart;return h7.includes(i)?o&&"clear"!==i?dG("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===i?function(e,t,r){let n=r.resolveAppLogPath(t),a=function(e){if(!s.existsSync(e))return{exists:!1,sizeBytes:0};let t=s.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(n);return{ok:!0,data:{path:n,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:a.sizeBytes,modifiedAt:a.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>'}}}(a,r,n):"doctor"===i?wl(a,r,n):"mark"===i?function(e,t,r){let n,a=e.positionals?.slice(1).join(" ")??"",i=r.resolveAppLogPath(t);return ir(i),n=`[agent-device][mark][${new Date().toISOString()}] ${a.trim()||"marker"}
62
+ `,s.appendFileSync(i,n,"utf8"),{ok:!0,data:{path:i,marked:!0}}}(t,r,n):"clear"===i?wu(a,r,n,o):"start"===i?wd(a,r,n):"stop"===i?wc(a,r,n):dG("INVALID_ARGS",we):dG("INVALID_ARGS",we)}async function wl(e,t,r){let n=r.resolveAppLogPath(t),a=await id(e.device,e.appBundleId);return{ok:!0,data:{path:n,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:a.checks,notes:a.notes}}}async function wu(e,t,r,n){if(e.appLog&&!n)return dG("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(n&&!e.appBundleId)return dG("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let a=r.resolveAppLogPath(t);if(!n)return{ok:!0,data:ic(a)};e.appLog&&await iu(e.appLog);let i=ic(a),o=r.resolveAppLogPidPath(t);try{let n=await io(e.device,e.appBundleId,a,o);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:{...i,restarted:!0}}}catch(n){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:D(n)}}}async function wd(e,t,r){if(e.appLog)return dG("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return dG("INVALID_ARGS","logs start requires an app session; run open <app> first");let n=r.resolveAppLogPath(t),a=r.resolveAppLogPidPath(t);try{let i=await io(e.device,e.appBundleId,n,a);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:n,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}}),{ok:!0,data:{path:n,started:!0}}}catch(e){return{ok:!1,error:D(e)}}}async function wc(e,t,r){if(!e.appLog)return dG("INVALID_ARGS","no app log stream active");let n=e.appLog.outPath;return await iu(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:n,stopped:!0}}}async function wp(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return dG("SESSION_NOT_FOUND","network requires an active session");if(!d7("network",a.device))return dG("UNSUPPORTED_OPERATION","network is not supported on this device");let i=(t.positionals?.[0]??"dump").toLowerCase();if(!wt.includes(i))return dG("INVALID_ARGS",wr);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return dG("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 dG("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let n=(r??t??"summary").toLowerCase();return wn.includes(n)?{ok:!0,include:n}:dG("INVALID_ARGS",wa)}(t);if(!s.ok)return s;let{include:l}=s,u=await ia({device:a.device,appBundleId:a.appBundleId,appLogState:a.appLog?.getState(),appLogStartedAt:a.appLog?.startedAt,appLogPath:n.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...u.dump,active:!!a.appLog,state:a.appLog?.getState()??"inactive",backend:u.backend,notes:u.notes}}}let wf=/^[A-Z_][A-Z0-9_]*$/,wm=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-((?:[^}\\]|\\.)*))?\}/g,wh="AD_VAR_";function ww(e){return e.startsWith("AD_")}function wg(e){return new k("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function wy(e,t,r){return e.replace(wm,(e,n,a,i)=>{if(n)return"${";if(!a)return e;if(Object.prototype.hasOwnProperty.call(t.values,a))return t.values[a];if(void 0!==i)return i.replace(/\\(.)/g,"$1");throw new k("INVALID_ARGS",`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function wv(e,t,r){if(!e)return e;let n={...e};for(let[e,a]of Object.entries(n))"string"==typeof a&&(n[e]=wy(a,t,r));return n}let wI=new Set(["ios","android","macos","linux"]),wA=new Set(["mobile","tv","desktop"]);function wS(e){let t=e.split(/\r?\n/),r={};for(let e=0;e<t.length;e+=1){let n=t[e].trim();if(0===n.length||n.startsWith("#"))continue;if(wb(n)){!function(e,t,r){let{key:n,value:a}=function(e,t){let r=e.slice(3).replace(/^[\s]+/,""),n=r.indexOf("=");if(n<=0)throw new k("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let a=r.slice(0,n);if(!wf.test(a))throw new k("INVALID_ARGS",`Invalid env key "${a}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(a.startsWith("AD_"))throw new k("INVALID_ARGS",`Invalid env key "${a}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${a} to avoid the AD_ prefix.`);return{key:a,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new k("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(r.slice(n+1),t)}}(t,r),i=e.env??{};if(Object.prototype.hasOwnProperty.call(i,n))throw new k("INVALID_ARGS",`Duplicate env directive "${n}" on line ${r}.`);i[n]=a,e.env=i}(r,n,e+1);continue}if(!n.startsWith("context "))break;let a=n.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&wI.has(e)&&w_(r,"platform",e)}let i=n.match(/(?:^|\s)target=([^\s]+)/);if(i){let e=i[1];e&&wA.has(e)&&w_(r,"target",e)}let o=n.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&w_(r,"timeoutMs",Math.floor(e))}let s=n.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&w_(r,"retries",Math.floor(e))}}return r}function wb(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function w_(e,t,r){let n=e[t];if(void 0!==n)throw new k("INVALID_ARGS",n===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(n)} vs ${String(r)}.`);e[t]=r}function wN(e){return!!e&&!Number.isNaN(Number(e))}let wx=/[*?[\]{}]/;async function wM(e){let t,{filePath:r,sessionName:n,requestId:a,timeoutMs:i,platform:o,target:s,artifactsDir:l,runReplay:u,cleanupSession:d}=e;t5(a);let c=new Set,p=!1,f=u({filePath:r,sessionName:n,platform:o,target:s,requestId:a,artifactsDir:l,artifactPaths:c}).catch(e=>{let t=M(e);return dG(t.code,t.message)}).finally(()=>{t8(a)});try{return"number"==typeof i?await Promise.race([f,new Promise(e=>{t=setTimeout(()=>{p=!0,t4(a),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(i,[...c]))},i)})]):await f}finally{t&&clearTimeout(t),p&&(await wD(f)||eM({level:"warn",phase:"test_timeout_cleanup_race",data:{session:n,requestId:a,graceMs:2e3}}));try{await d(n)}catch(e){eM({level:"warn",phase:"test_cleanup_failed",data:{session:n,error:M(e).message}})}}}async function wD(e){return await Promise.race([e.then(()=>!0),_(2e3).then(()=>!1)])}async function wk(e){let{req:t,sessionName:r,runReplay:n,cleanupSession:a}=e;if((t.positionals?.length??0)===0)return dG("INVALID_ARGS","test requires at least one path or glob");try{var i,o,l,u,d,c;let e,f,m,h,w,g=function(e){let{inputs:t,cwd:r,platformFilter:n}=e,a=r??process.cwd(),i=[...new Set(t.flatMap(e=>(function(e,t){var r,n;let a=aD.expandHome(e,t);if(s.existsSync(a)){let t=s.statSync(a);if(t.isDirectory())return s.globSync("**/*.ad",{cwd:a}).map(e=>p.join(a,e));if(t.isFile()){if(".ad"!==p.extname(a))throw new k("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[a]}return[]}if(r=e,!wx.test(r)&&(n=a,!wx.test(n)))throw new k("INVALID_ARGS",`test input not found: ${e}`);let i=p.isAbsolute(a)?a:e;return s.globSync(i,{cwd:p.isAbsolute(a)?void 0:t}).map(e=>p.isAbsolute(e)?e:p.resolve(t,e)).filter(e=>".ad"===p.extname(e)&&function(e){try{return s.statSync(e).isFile()}catch{return!1}}(e))})(e,a)))].map(e=>p.normalize(e)).sort((e,t)=>e.localeCompare(t)),o=[];for(let e of i){var l,u;let t=wS(s.readFileSync(e,"utf8"));if(!n){o.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){o.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${n}`});continue}l=n,u=t.platform,("apple"===l?"apple"===u||"ios"===u||"macos"===u:u===l)&&o.push({kind:"run",path:e,metadata:t})}if(0===o.filter(e=>"run"===e.kind).length){let e=n?` for --platform ${n}`:"";throw new k("INVALID_ARGS",`No .ad tests matched${e}.`)}return o}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(i=t.meta?.requestId,(i?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:n}=e,a=aD.expandHome(t??".agent-device/test-artifacts",r);return p.join(a,n)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),I=[],A=Date.now(),S=0;for(let e of g){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}S+=1;let i=await wE({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:S-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(o=t.flags?.timeoutMs,l=e.metadata.timeoutMs,"number"==typeof o?o:l),suiteArtifactsDir:v,runReplay:n,cleanupSession:a});if(I.push(i),t.flags?.failFast===!0)break}let b=(u=g.length,d=I,c=Date.now()-A,e=d.filter(e=>"passed"===e.status).length,m=(f=d.filter(e=>"failed"===e.status)).length,h=d.filter(e=>"skipped"===e.status).length,w=e+m,{total:u,executed:w,passed:e,failed:m,skipped:h,notRun:Math.max(0,u-w-h),durationMs:c,failures:f,tests:d});return{ok:!0,data:b}}catch(t){let e=M(t);return dG(e.code,e.message)}}async function wE(e){var t,r;let n,a,{entry:i,sessionName:o,suiteInvocationId:l,caseIndex:u,cwd:d,requestId:c,retries:f,timeoutMs:m,suiteArtifactsDir:h,runReplay:w,cleanupSession:g}=e,y=Date.now(),v=p.join(h,(t=i.path,(0===(a=d?p.relative(d,t):p.basename(t)).length||a.startsWith("..")?p.basename(t):a).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",A=0;for(let e=0;e<=f;e+=1){A=e+1;let t=function(e,t,r,n,a=0){let i=p.basename(r,p.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${n+1}${i?`-${i}`:""}:attempt-${a+1}`}(o,l,i.path,u,e),a=p.join(v,`attempt-${A}`);r=i.path,s.mkdirSync(a,{recursive:!0}),s.copyFileSync(r,p.join(a,"replay.ad"));let d=function(e){let{requestId:t,suiteInvocationId:r,filePath:n,caseIndex:a,attemptIndex:i}=e;return t3(`${t??r}:test:${a+1}:${p.basename(n)}:attempt:${i+1}`,r)}({requestId:c,suiteInvocationId:l,filePath:i.path,caseIndex:u,attemptIndex:e}),h=await wM({filePath:i.path,sessionName:t,requestId:d,timeoutMs:m,platform:i.metadata.platform,target:i.metadata.target,artifactsDir:a,runReplay:w,cleanupSession:g});if(!function(e){let{response:t,filePath:r,sessionName:n,attempts:a,maxAttempts:i,attemptArtifactsDir:o}=e,l=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(t)];t.ok||"string"!=typeof t.error.logPath||l.push(t.error.logPath);let u=function(e,t){let r=[],n=new Map;for(let a of e){if(!function(e){try{return s.statSync(e).isFile()}catch{return!1}}(a))continue;let e=function(e,t){let r=p.extname(e),n=r?e.slice(0,-r.length):e,a=t.get(e)??0;return(t.set(e,a+1),0===a)?e:`${n}-${a+1}${r}`}(p.basename(a),n),i=p.join(t,e);p.resolve(a)!==p.resolve(i)&&s.copyFileSync(a,i),r.push(i)}return r}(l,o),d=[`file: ${r}`,`session: ${n}`,`attempt: ${a}/${i}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;d.push(`replayed: ${e}`,`healed: ${r}`)}else d.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&d.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&d.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&d.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&d.push("timeoutMode: cooperative");u.length>0&&d.push(`copiedArtifacts: ${u.map(e=>p.basename(e)).join(", ")}`);let c=p.join(o,"result.txt"),f=`${d.join("\n")}
63
+ `;s.writeFileSync(c,f),t.ok||s.writeFileSync(p.join(o,"failure.txt"),f)}({response:h,filePath:i.path,sessionName:t,attempts:A,maxAttempts:f+1,attemptArtifactsDir:a}),n=h,I=t,h.ok)break}let S=Date.now()-y;if(n?.ok)return{file:i.path,session:I,status:"passed",durationMs:S,attempts:A,artifactsDir:v,replayed:"number"==typeof n.data?.replayed?n.data.replayed:0,healed:"number"==typeof n.data?.healed?n.data.healed:0};let b=n?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:n?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:i.path,session:I,status:"failed",durationMs:S,attempts:A,artifactsDir:v,error:b}}function wO(e){return e.map((e,t)=>{if("string"==typeof e||wG(e))return e;throw new k("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function wP(e,t){if("string"==typeof e){var r;return[wC("label",r=e),wC("text",r),wC("id",r)].join(" || ")}if(!wG(e))throw new k("INVALID_ARGS",`${t} expects a string or selector map.`);let n=[];if("string"==typeof e.id&&n.push(wC("id",e.id)),"string"==typeof e.text&&n.push(wC("label",e.text)),"boolean"==typeof e.enabled&&n.push(wC("enabled",String(e.enabled))),0===n.length)throw new k("INVALID_ARGS",`${t} selector map must include one of id, text, or enabled.`);return n.join(" ")}function wC(e,t){return`${e}=${JSON.stringify(t)}`}function wL(e){if(!wG(e))return;let t={};return"number"==typeof e.repeat&&Number.isInteger(e.repeat)&&e.repeat>1&&(t.count=e.repeat),"number"==typeof e.delay&&Number.isInteger(e.delay)&&e.delay>=0&&(t.intervalMs=e.delay),Object.keys(t).length>0?t:void 0}function wR(e,t){return wG(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function wT(e,t){if(e.appId)return e.appId;throw new k("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function w$(e,t){if("string"==typeof t)return t;throw new k("INVALID_ARGS",`${e} expects a string value.`)}function wF(e){throw new k("INVALID_ARGS",`Prototype does not support Maestro command "${e}" yet.`)}function wU(e,t=[],r){return{ts:Date.now(),command:e,positionals:t,flags:r??{}}}function wG(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function wV(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),n=tL(r?e.slice(0,-1):e.slice());return!n||n.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:n.selectorExpression,selectorTimeout:r?t:null}}async function wj(e){let{action:t,sessionName:r,logPath:n,sessionStore:a}=e;if(!(ap(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let i=a.get(r);if(!i)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),ap(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}=tV(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=wV(e.positionals??[]);r&&t.push(r)}return ao(t).filter(e=>e.trim().length>0)})(t).map(e=>tF(e)).filter(e=>null!==e);if(0===o.length)return null;let s=ap(t.command)||"fill"===t.command,l=ap(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await wB(i,t,n,s,a);for(let e of o){let r=tj(u.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let n=tB(r.node,i.device.platform,{action:ap(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(ap(t.command))return{...t,positionals:[n]};if("fill"===t.command){let e=ai(t);if(!e)continue;return{...t,positionals:[n,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,n]}}if("is"===t.command){let{predicate:e,split:r}=tV(t.positionals);if(!e)continue;let a=r?.rest.join(" ").trim()??"",i=[e,n];return"text"===e&&a.length>0&&i.push(a),{...t,positionals:i}}if("wait"===t.command){let{selectorTimeout:e}=wV(t.positionals??[]),r=[n];return e&&r.push(e),{...t,positionals:r}}}return null}async function wB(e,t,r,n,a){let i=await dC(e.device,"snapshot",[],t.flags?.out,{...co(r,{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n},e.appBundleId,e.trace?.outPath)}),o=i?.nodes??[],s={nodes:tO(t.flags?.snapshotRaw?o:tH(o)),truncated:i?.truncated,createdAt:Date.now(),backend:i?.backend};return cI(e,s),a.set(e.name,e),s}async function wq(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}=e,o=t.positionals?.[0];if(!o)return dG("INVALID_ARGS","replay requires a path");let l="",u=new Set;try{var d,c,f;let e;l=aD.expandHome(o,t.meta?.cwd);let m=s.readFileSync(l,"utf8"),h=m.trimStart()[0];if("{"===h||"["===h)return dG("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let w=t.flags?.replayMaestro===!0,g=w?function(e){let t=N(e);for(let e of t)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new k("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}let{config:r,commands:n}=function(e){if(0===e.length)throw new k("INVALID_ARGS","Maestro flow is empty.");if(Array.isArray(e[0]))return{config:{},commands:wO(e[0])};let t=function(e){if(!wG(e))throw new k("INVALID_ARGS","Maestro flow config must be a YAML map.");let t={};if("string"==typeof e.appId&&e.appId.length>0&&(t.appId=e.appId),wG(e.env))for(let[r,n]of(t.env={},Object.entries(e.env)))("string"==typeof n||"number"==typeof n||"boolean"==typeof n)&&(t.env[r]=String(n));return t}(e[0]),r=e[1];if(!Array.isArray(r))throw new k("INVALID_ARGS","Maestro flow must contain a command list after the YAML document separator.");return{config:t,commands:wO(r)}}(t.map(e=>e.toJSON()).filter(e=>null!==e)),a=[],i=[];for(let e=0;e<n.length;e+=1){let t=function(e,t){if("string"==typeof e)return"launchApp"===e?[wU("open",[wT(t,"launchApp")])]:"hideKeyboard"===e?[wU("keyboard",["dismiss"])]:"back"===e?[wU("back")]:"waitForAnimationToEnd"===e?[wU("wait",["250"])]:wF(e);let r=Object.entries(e);if(1!==r.length)throw new k("INVALID_ARGS","Maestro command maps must contain exactly one command.");let[n,a]=r[0];switch(n){case"launchApp":return[function(e,t){if(null==e)return wU("open",[wT(t,"launchApp")]);if("string"==typeof e)return wU("open",[e]);if(!wG(e))throw new k("INVALID_ARGS","launchApp expects a string or map.");return wU("open",["string"==typeof e.appId?e.appId:wT(t,"launchApp")],{relaunch:!0===e.stopApp})}(a,t)];case"tapOn":return[function(e){if(wG(e)&&"string"==typeof e.point){let t=function(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw new k("INVALID_ARGS",'Prototype supports only absolute Maestro point selectors like "100,200".');return{x:Number(t[1]),y:Number(t[2])}}(e.point);return wU("click",[String(t.x),String(t.y)],wL(e))}return wU("click",[wP(e,"tapOn")],wL(e))}(a)];case"inputText":return[wU("type",[w$(n,a)])];case"openLink":return[wU("open",[w$(n,a)])];case"assertVisible":return[wU("wait",[wP(a,n),"5000"])];case"extendedWaitUntil":return function(e){if(!wG(e))throw new k("INVALID_ARGS","extendedWaitUntil expects a map.");let t=e.visible??e.notVisible;if(void 0===t)throw new k("INVALID_ARGS","Prototype supports only extendedWaitUntil.visible/notVisible.");let r=wP(t,"extendedWaitUntil"),n=String(wR(e,3e4));return void 0!==e.notVisible?[wU("wait",[n]),wU("is",["hidden",r])]:[wU("wait",[r,n])]}(a);case"takeScreenshot":return[wU("screenshot",[w$(n,a)])];case"hideKeyboard":return[wU("keyboard",["dismiss"])];case"pressKey":return[function(e){let t=w$("pressKey",e).toLowerCase();if("back"===t)return wU("back");if("enter"===t||"return"===t)return wU("press",["return"]);if("home"===t)return wU("home");throw new k("INVALID_ARGS",`Prototype does not support Maestro pressKey "${t}".`)}(a)];case"back":return[wU("back")];case"waitForAnimationToEnd":return[wU("wait",[String(wR(a,250))])];default:return wF(n)}}(n[e],r);a.push(...t),t.forEach(()=>i.push(e+1))}return{actions:a,actionLines:i,metadata:{env:r.env}}}(m):null,y=g?.metadata??wS(m),v=y.platform||y.target?{...t,flags:(d=t.flags,c=y,{...d??{},...void 0!==c.platform&&d?.platform===void 0?{platform:c.platform}:{},...void 0!==c.target&&d?.target===void 0?{target:c.target}:{}})}:t,I=g??function(e){let t=[],r=[],n=e.split(/\r?\n/),a=!1;for(let e=0;e<n.length;e+=1){let i=n[e],o=i.trim();if(0===o.length||o.startsWith("#"))continue;if(wb(o)){if(a)throw new k("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let s=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&&!((r=function(e,t){let r=t;for(;r<e.length&&/\s/.test(e[r]);)r+=1;return r}(e,r))>=e.length);){let n='"'===e[r]?function(e,t){let r=!1,n=t+1;for(;n<e.length;n+=1){let t=e[n];if('"'===t&&!r)break;if(r){r=!1;continue}r="\\"===t}if(n>=e.length)throw new k("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,n+1)),nextCursor:n+1}}(e,r):function(e,t){let r=t;for(;r<e.length&&!/\s/.test(e[r]);)r+=1;return{value:e.slice(t,r),nextCursor:r}}(e,r);t.push(n.value),r=n.nextCursor}return t}(t);if(0===r.length)return null;let[n,...a]=r;if("context"===n)return null;let i={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){i.positionals=[];for(let e=0;e<a.length;e+=1){let t=a[e];if("-i"===t){i.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){i.flags.snapshotCompact=!0;continue}if("--raw"===t){i.flags.snapshotRaw=!0;continue}if("--force-full"===t){i.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<a.length){let t=Number(a[e+1]);Number.isFinite(t)&&t>=0&&(i.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<a.length){i.flags.snapshotScope=a[e+1],e+=1;continue}if("--backend"===t&&e+1<a.length){e+=1;continue}}return i}if("open"===n){let e=function(e){var t;let r=[],n={};for(let t of e){if("--relaunch"===t){n.relaunch=!0;continue}r.push(t)}let a=aS(r);return{positionals:a.positionals,flags:n,runtime:(t=a.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?a.flags:void 0}}(a);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i.runtime=e.runtime,i}if("runtime"===n){let e=aS(a);return i.positionals=e.positionals,Object.assign(i.flags,e.flags),i}if(ap(n)){let e=aA(n,a);if(Object.assign(i.flags,e.flags),0===e.positionals.length)return i;let t=e.positionals[0];if(t.startsWith("@"))return i.positionals=[t],e.positionals[1]&&(i.result={refLabel:e.positionals[1]}),i;let r=e.positionals[0],o=e.positionals[1];return wN(r)&&wN(o)&&e.positionals.length>=2?i.positionals=[r,o]:i.positionals=[e.positionals.join(" ")],i}if("fill"===n){let e=aA(n,a);if(Object.assign(i.flags,e.flags),e.positionals.length<2)return i.positionals=e.positionals,i;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(i.positionals=[t,e.positionals.slice(2).join(" ")],i.result={refLabel:e.positionals[1]}):i.positionals=[t,e.positionals[1]],i):(i.positionals=[t,e.positionals.slice(1).join(" ")],i)}if("get"===n){if(a.length<2)return i.positionals=a,i;let e=a[0],t=a[1];return t.startsWith("@")?(i.positionals=[e,t],a[2]&&(i.result={refLabel:a[2]})):i.positionals=[e,a.slice(1).join(" ")],i}if("swipe"===n||"type"===n){let e=aA(n,a);return Object.assign(i.flags,e.flags),i.positionals=e.positionals,i}if("record"===n){let e=[];for(let t=0;t<a.length;t+=1){let r=a[t];if("--hide-touches"===r){i.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<a.length){let e=Number(a[t+1]);Number.isFinite(e)&&(i.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===r&&t+1<a.length){let e=Number(a[t+1]);Number.isFinite(e)&&(i.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return i.positionals=e,i}if("screenshot"===n){let e=[];for(let t=0;t<a.length;t+=1){let r=a[t],n=eV({args:a,index:t,flags:i.flags});if(n.handled){t=n.nextIndex;continue}e.push(r)}return i.positionals=e,i}return i.positionals=a,i}(i);s&&(t.push(s),r.push(e+1),a=!0)}return{actions:t,actionLines:r}}(m),A=I.actions,S=I.actionLines;if(t.flags?.replayUpdate===!0&&w)return dG("INVALID_ARGS","replay -u is not supported for Maestro flow input. Convert to .ad first, then update that replay file.");if(t.flags?.replayUpdate===!0&&y.env&&Object.keys(y.env).length>0)return dG("INVALID_ARGS","replay -u does not yet preserve env directives. Temporarily remove the env lines, run replay -u, then restore them.");if(t.flags?.replayUpdate===!0&&function(e){for(let t of e){for(let e of t.positionals??[])if("string"==typeof e&&e.includes("${"))return!0;if(t.flags){for(let e of Object.values(t.flags))if("string"==typeof e&&e.includes("${"))return!0}if(t.runtime){for(let e of Object.values(t.runtime))if("string"==typeof e&&e.includes("${"))return!0}}return!1}(A))return dG("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let b=function(e){let t={};if(e.builtins)for(let[r,n]of Object.entries(e.builtins))t[r]=n;for(let r of[e.fileEnv,e.shellEnv,e.cliEnv])if(r)for(let[e,n]of Object.entries(r)){if(ww(e))throw wg(e);t[e]=n}return{values:t}}({builtins:function(e){let{req:t,sessionName:r,metadata:n,resolvedPath:a}=e,i=t.flags??{},o=t.meta?.cwd??process.cwd(),s={AD_SESSION:r,AD_FILENAME:p.relative(o,a)||a},l=i.platform??n.platform;l&&(s.AD_PLATFORM=l);let u=i.target??n.target;u&&(s.AD_TARGET=u);let d=i.device;"string"==typeof d&&d.length>0&&(s.AD_DEVICE=d);let c=i.artifactsDir;return"string"==typeof c&&c.length>0&&(s.AD_ARTIFACTS=c),s}({req:v,sessionName:r,metadata:y,resolvedPath:l}),fileEnv:y.env,shellEnv:function(e){let t={};for(let[r,n]of Object.entries(e)){if("string"!=typeof n||!r.startsWith(wh))continue;let e=r.slice(wh.length);0!==e.length&&wf.test(e)&&(ww(e)||(t[e]=n))}return t}(function(e){let t=e.flags?.replayShellEnv;if(t&&"object"==typeof t&&!Array.isArray(t)){let e={};for(let[r,n]of Object.entries(t))"string"==typeof n&&(e[r]=n);return e}return process.env}(t)),cliEnv:function(e){let t={};for(let r of e){let e=r.indexOf("=");if(e<=0)throw new k("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let n=r.slice(0,e);if(!wf.test(n))throw new k("INVALID_ARGS",`Invalid -e key "${n}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(ww(n))throw wg(n);t[n]=r.slice(e+1)}return t}((f=t,e=f.flags?.replayEnv,Array.isArray(e)?e.filter(e=>"string"==typeof e):[]))}),_=t.flags?.replayUpdate===!0,x=0;for(let e=0;e<A.length;e+=1){let t=A[e];if(!t||"replay"===t.command)continue;let o=await wH({req:v,sessionName:r,action:t,scope:b,filePath:l,line:S[e]??0,step:e+1,tracePath:a.get(r)?.trace?.outPath,invoke:i});if(o.ok){wK(o).forEach(e=>u.add(e));continue}if(!_)return wz(o,t,e,l,[...u]);let s=await wj({action:t,sessionName:r,logPath:n,sessionStore:a});if(!s)return wz(o,t,e,l,[...u]);if(A[e]=s,!(o=await wH({req:v,sessionName:r,action:s,scope:b,filePath:l,line:S[e]??0,step:e+1,tracePath:a.get(r)?.trace?.outPath,invoke:i})).ok)return wz(o,s,e,l,[...u]);wK(o).forEach(e=>u.add(e)),x+=1}return _&&x>0&&function(e,t,r){let n=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";n.push(`context platform=${r.device.platform}${t} device=${ah(r.device.name)}${e} theme=unknown`)}for(let e of t){var a;n.push((a=e,a_(a,{runtimeIncludeAllPositionals:!0})))}let i=`${n.join("\n")}
64
+ `,o=`${e}.tmp-${process.pid}-${Date.now()}`;s.writeFileSync(o,i),s.renameSync(o,e)}(l,A,a.get(r)),{ok:!0,data:{replayed:A.length,healed:x,session:r,artifactPaths:[...u]}}}catch(t){let e=M(t);return dG(e.code,e.message,u.size>0?{artifactPaths:[...u]}:void 0)}}async function wH(e){var t,r;let{req:n,sessionName:a,action:i,scope:o,filePath:s,line:l,step:u,tracePath:d,invoke:c}=e,p=(t={file:s,line:l},{...i,positionals:(i.positionals??[]).map(e=>wy(e,o,t)),flags:wv(i.flags,o,t)??{},runtime:wv(i.runtime,o,t)}),f=Date.now();wW(d,{type:"replay_action_start",ts:new Date(f).toISOString(),replayPath:s,line:l,step:u,command:p.command,positionals:p.positionals??[]});let m=await c({token:n.token,session:a,command:p.command,positionals:p.positionals??[],flags:(r=n.flags,tJ(r,{...p.flags??{}})),runtime:p.runtime,meta:n.meta}),h=Date.now();return wW(d,{type:"replay_action_stop",ts:new Date(h).toISOString(),replayPath:s,line:l,step:u,command:p.command,ok:m.ok,durationMs:h-f,errorCode:m.ok?void 0:m.error.code}),m}function wW(e,t){e&&s.appendFileSync(e,`${JSON.stringify(t)}
65
+ `)}function wz(e,t,r,n,a=[]){let i;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${i=(t.positionals??[]).map(e=>am(e)),[t.command,...i].join(" ")}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:n,step:o,action:t.command,positionals:t.positionals??[],artifactPaths:a}}}}function wK(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,n="string"==typeof r.path?r.path:void 0;e?t.push(e):n&&t.push(n)}return[...new Set(t.filter(e=>(function(e){try{return s.statSync(e).isFile()}catch{return!1}})(e)))]}async function wJ(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}=e;return"replay"===t.command?await wq({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}):"test"===t.command?await wk({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,target:s,requestId:l,artifactsDir:u,artifactPaths:d})=>{let c=function(e){let{parentFlags:t,platform:r,target:n,artifactsDir:a}=e;return void 0===r&&void 0===n&&void 0===a?t:{...t??{},...void 0!==r?{platform:r}:{},...void 0!==n?{target:n}:{},...void 0!==a?{artifactsDir:a}:{}}}({parentFlags:t.flags,platform:o,target:s,artifactsDir:u});return await wq({req:{...t,command:"replay",session:r,positionals:[e],flags:c,meta:l?{...t.meta??{},requestId:l}:t.meta},sessionName:r,logPath:n,sessionStore:a,invoke:async e=>{var t;return t=await i(e),d&&wK(t).forEach(e=>d.add(e)),t}})},cleanupSession:async e=>{a.get(e)&&await hu({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:n,sessionStore:a})}}):null}let wX=eP.inventory,wY=eP.state,wZ=eP.observability,wQ=eP.replay;async function w0(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,command:i,positionals:o,recordPositionals:s,deriveNextSession:l}=e,u=a.get(r),d=t.flags??{},c=dB(i,u,d);if(c)return c;let p=await dz({session:u,flags:d,ensureReady:!0});if(!d7(i,p))return dG("UNSUPPORTED_OPERATION",`${i} is not supported on this device`);let f=await dC(p,i,o,t.flags?.out,{...co(n,t.flags,u?.appBundleId,u?.trace?.outPath)});if(u){let e=l?await l(u,f,p):u;a.recordAction(e,{command:i,positionals:s??o,flags:t.flags??{},result:f??{}}),e!==u&&a.set(r,e)}return{ok:!0,data:f??{}}}async function w1(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,i=a.get(r),o=t.flags??{},s=dB(eL.clipboard,i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return dG("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await dz({session:i,flags:o,ensureReady:!0});if(!d7(eL.clipboard,u))return dG("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let d=await dC(u,eL.clipboard,t.positionals??[],t.flags?.out,{...co(n,t.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:d??{}}),{ok:!0,data:{platform:u.platform,...d??{}}}}async function w2(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i,invokeReplayAction:o,androidAdbExecutor:s}=e;if(wX.has(t.command))return await hm({req:t,sessionName:r,sessionStore:a});if("runtime"===t.command)return await mC({req:t,sessionName:r,sessionStore:a});if(wY.has(t.command))return await hv({req:t,sessionName:r,sessionStore:a});if(t.command===eL.clipboard)return await w1({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===eL.keyboard){let e=a.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i||"ios"!==(t.flags??{}).platform?await w0({req:t,sessionName:r,logPath:n,sessionStore:a,command:eL.keyboard,positionals:t.positionals??[]}):dG("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(wZ.has(t.command))return await wi({req:t,sessionName:r,sessionStore:a,androidAdbExecutor:s});if(t.command===eL.install||t.command===eL.reinstall)return await hp({req:t,command:t.command,sessionName:r,sessionStore:a,deployOps:t.command===eL.install?hc:hd});if(t.command===eX.installSource)return await mn({req:t,sessionName:r,sessionStore:a});if(t.command===eX.releaseMaterializedPaths)return await ma({req:t});if(t.command===eL.push){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await w0({req:t,sessionName:r,logPath:n,sessionStore:a,command:eL.push,positionals:[i,"file"===(e=dE(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>aD.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):dG("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return t.command===eL.triggerAppEvent?await w0({req:t,sessionName:r,logPath:n,sessionStore:a,command:eL.triggerAppEvent,positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,n=r?await m5(e.device,r,e.appBundleId,m2)??e.appBundleId:e.appBundleId;return{...e,appBundleId:n}}}):t.command===eL.open?await ha({req:t,sessionName:r,logPath:n,sessionStore:a}):wQ.has(t.command)?await wJ({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o??i}):t.command===eL.batch?await hf(t,r,i):t.command===eL.close?await hu({req:t,sessionName:r,logPath:n,sessionStore:a}):null}async function w3(e){let{req:t,logPath:r,sessionStore:n,session:a,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=a?"frontmost-app"===a.surface?{surface:"frontmost-app"}:{bundleId:a.appBundleId,surface:a.surface}:{};if(!d7("alert",i))return dG("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===i.platform){let e=async()=>await lN("wait"===o?"get":o,s);if("wait"===o){let r=eF(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<r;){try{let r=await e();return ps(n,a,t,r),{ok:!0,data:r}}catch{}await ef(300)}return dG("COMMAND_FAILED","alert wait timed out")}let r="accept"===o||"dismiss"===o?o:"get";if("accept"===r||"dismiss"===r){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await lN(r,s);return ps(n,a,t,e),{ok:!0,data:e}}catch(r){e=r;let t=String(r?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await ef(300)}throw w5(e)}let i=await lN("get",s);return ps(n,a,t,i),{ok:!0,data:i}}if("wait"===o){let e=eF(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await at(i,{command:"alert",action:"get",appBundleId:a?.appBundleId},{verbose:t.flags?.verbose,logPath:r,traceLogPath:a?.trace?.outPath,requestId:t.meta?.requestId});return ps(n,a,t,e),{ok:!0,data:e}}catch{}await ef(300)}return dG("COMMAND_FAILED","alert wait timed out")}let l="accept"===o||"dismiss"===o?o:"get",u={verbose:t.flags?.verbose,logPath:r,traceLogPath:a?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,r=Date.now();for(;Date.now()-r<2e3;){try{let e=await at(i,{command:"alert",action:l,appBundleId:a?.appBundleId},u);return ps(n,a,t,e),{ok:!0,data:e}}catch(r){e=r;let t=String(r?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await ef(300)}throw w5(e)}let d=await at(i,{command:"alert",action:l,appBundleId:a?.appBundleId},u);return ps(n,a,t,d),{ok:!0,data:d}}function w5(e){if(!(e instanceof k))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new k(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}async function w4(e){let{req:t,logPath:r,sessionStore:n,session:a,device:i,parsed:o}=e,{setting:s,state:l,permissionTarget:u,latitude:d,longitude:c}=o;if(!d7("settings",i))return dG("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===i.platform&&!tc(s))return dG("INVALID_ARGS",tv(s));let p=a?.appBundleId,f="permission"===s?[s,l,u??"",t.positionals?.[3]??"",p??""]:"location"===s&&"set"===l?[s,l,d??"",c??"",p??""]:[s,l,p??""],m=await dC(i,"settings",f,t.flags?.out,{...co(r,t.flags,p,a?.trace?.outPath)});return ps(n,a,t,m??{setting:s,state:l}),{ok:!0,data:m??{setting:s,state:l}}}async function w8(e){return await w9({...e,command:"snapshot",unsupportedMessage:"snapshot is not supported on this device",execute:async({runtime:e,sessionName:t,req:r,snapshotScope:n})=>{let a=await e.capture.snapshot({session:t,interactiveOnly:r.flags?.snapshotInteractiveOnly,compact:r.flags?.snapshotCompact,depth:r.flags?.snapshotDepth,scope:n,raw:r.flags?.snapshotRaw,forceFull:r.flags?.snapshotForceFull});return{data:a,record:{kind:"snapshot",nodes:a.nodes.length,truncated:a.truncated}}}})}async function w6(e){return await w9({...e,command:"diff",unsupportedMessage:"diff is not supported on this device",execute:async({runtime:e,sessionName:t,req:r,snapshotScope:n})=>{let a=await e.capture.diffSnapshot({session:t,interactiveOnly:r.flags?.snapshotInteractiveOnly,compact:r.flags?.snapshotCompact,depth:r.flags?.snapshotDepth,scope:n,raw:r.flags?.snapshotRaw});return{data:a,record:{kind:"diff",mode:"snapshot",baselineInitialized:a.baselineInitialized,summary:a.summary}}}})}async function w9(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,{session:i,device:o}=await pi(a,r,t.flags);if(!d7(e.command,o))return dG("UNSUPPORTED_OPERATION",e.unsupportedMessage);let s=function(e,t){let r;if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return dG("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let n=tM(e.trim());if(!n)return dG("INVALID_ARGS",`Invalid ref scope: ${e}`);for(let e of[t.snapshot,...t.snapshotScopeSource?[t.snapshotScopeSource]:[]]){let t=tD(e.nodes,n);if(r=t?tG(t,e.nodes):void 0)break}return r?{ok:!0,scope:r}:dG("COMMAND_FAILED",`Ref ${e} not found or has no label`)}(t.flags?.snapshotScope,i);return s.ok?await po(i,o,async()=>{var l,u;let d,c=function(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,session:i,device:o,snapshotScope:s}=e;return tg({backend:function(e){let{req:t,logPath:r,session:n,device:a,snapshotScope:i}=e;return{platform:a.platform,captureSnapshot:async(e,o)=>{let s=await cd({device:a,session:n,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:r,snapshotScope:i});return{snapshot:s.snapshot,analysis:s.analysis,androidSnapshot:s.androidSnapshot,freshness:s.freshness,appName:n?.appBundleId?n.appName??n.appBundleId:void 0,appBundleId:n?.appBundleId}}}}({req:t,logPath:n,session:i,device:o,snapshotScope:s}),...py("snapshot"),sessions:cA({sessionName:r,getSession:()=>a.get(r),recordOptions:{includeSnapshot:!0},setRecord:e=>{var n;let i=function(e){if(!e.snapshot)throw new k("UNKNOWN","snapshot runtime did not produce session state");return e}(e),s=a.get(r);a.set(r,function(e){var t,r;let{current:n,sessionName:a,device:i,record:o,refScopedSnapshot:s}=e,l=(t=n,r=o,s&&r.snapshot?.nodes.length===0&&t?.snapshot!==void 0),u=l?n.snapshot:o.snapshot,d=function(e){let{session:t,sessionName:r,device:n,snapshot:a,appBundleId:i}=e;return t?{...t,snapshot:a}:{name:r,device:n,createdAt:Date.now(),appBundleId:i,snapshot:a,actions:[]}}({session:n,sessionName:a,device:i,snapshot:u,appBundleId:o.appBundleId});return d.snapshotScopeSource=function(e){let{current:t,keepCurrentSnapshot:r,refScopedSnapshot:n}=e;if(n)return r?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}({current:n,keepCurrentSnapshot:l,refScopedSnapshot:s}),o.appName&&(d.appName=o.appName),d}({current:s,sessionName:r,device:o,record:i,refScopedSnapshot:(n=t,n.flags?.snapshotScope?.trim().startsWith("@")===!0)}))}})})}({req:t,sessionName:r,logPath:n,sessionStore:a,session:i,device:o,snapshotScope:s.scope}),p=await e.execute({runtime:c,sessionName:r,req:t,snapshotScope:s.scope});return(d=(l={req:t,sessionName:r,sessionStore:a,result:p.record}).sessionStore.get(l.sessionName))&&l.sessionStore.recordAction(d,{command:l.req.command,positionals:l.req.positionals??[],flags:l.req.flags??{},result:"snapshot"===(u=l.result).kind?{nodes:u.nodes,truncated:u.truncated}:{mode:u.mode,baselineInitialized:u.baselineInitialized,summary:u.summary}}),{ok:!0,data:p.data}}):s}let w7=eP.snapshot,ge={snapshot:async({req:e,sessionName:t,logPath:r,sessionStore:n})=>await w8({req:e,sessionName:t,logPath:r,sessionStore:n}),diff:async({req:e,sessionName:t,logPath:r,sessionStore:n})=>e.positionals?.[0]!=="snapshot"?dG("INVALID_ARGS","diff currently supports only: diff snapshot"):await w6({req:e,sessionName:t,logPath:r,sessionStore:n}),wait:async({req:e,sessionName:t,logPath:r,sessionStore:n})=>await pL({req:e,sessionName:t,logPath:r,sessionStore:n}),alert:async({req:e,sessionName:t,logPath:r,sessionStore:n})=>{let{session:a,device:i}=await pi(n,t,e.flags);return await po(a,i,async()=>await w3({req:e,logPath:r,sessionStore:n,session:a,device:i}))},settings:async({req:e,sessionName:t,logPath:r,sessionStore:n})=>{let a,i,o,s=(a=e.positionals?.[0]?.toLowerCase(),i=e.positionals?.[1]?.toLowerCase(),o=e.positionals?.[2]?.toLowerCase(),a&&i&&("permission"!==a||o)&&("location"!==a||"set"!==i||e.positionals?.[2]&&e.positionals?.[3])?{ok:!0,parsed:{setting:a,state:i,permissionTarget:o,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}:dG("INVALID_ARGS",th));if(!s.ok)return s;let{session:l,device:u}=await pi(n,t,e.flags);return await po(l,u,async()=>await w4({req:e,logPath:r,sessionStore:n,session:l,device:u,parsed:s.parsed}))}};async function gt(e){let t=e.req.command;if(!w7.has(t))return null;let r=ge[t];return r?await r(e):dG("COMMAND_FAILED",`Snapshot command has no handler: ${t}`)}async function gr(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,leaseRegistry:i,invoke:o,invokeReplayAction:s,androidAdbExecutor:l,contextFromFlags:u}=e,d=await fm({req:t,leaseRegistry:i});if(d)return d;let c=await w2({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o,invokeReplayAction:s,androidAdbExecutor:l});if(c)return c;let p=await gt({req:t,sessionName:r,logPath:n,sessionStore:a});if(p)return p;let f=await f3({req:t,sessionName:r,sessionStore:a,logPath:n});if(f)return f;let m=await pK({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o});if(m)return m;let h=await fc({req:t,sessionName:r,logPath:n,sessionStore:a,contextFromFlags:u});return h||null}function gn(e,t){if(!t)return[];let r=[],n=e.device,a=t.platform;if(a&&!rY(n.platform,a)&&r.push({key:"platform",value:t.platform}),t.target&&t.target!==(n.target??"mobile")&&r.push({key:"target",value:t.target}),t.udid&&("ios"!==n.platform||t.udid!==n.id)&&r.push({key:"udid",value:t.udid}),t.serial&&("android"!==n.platform||t.serial!==n.id)&&r.push({key:"serial",value:t.serial}),t.device&&t.device.trim().toLowerCase()!==n.name.trim().toLowerCase()&&r.push({key:"device",value:t.device}),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),a=n.simulatorSetPath?.trim();("ios"!==n.platform||"simulator"!==n.kind||e!==a)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=Y(t.androidDeviceAllowlist);"android"===n.platform&&e.has(n.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function ga(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 gi=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"],go=eP.selectorValidationExempt,gs=eP.leaseAdmissionExempt,gl=new Set(gs);async function gu(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(a)return`device:${a.device.id}`;if("open"===t.command||dq(t.flags))try{let e=await op(t.flags??{});return`device:${e.id}`}catch{}return`session:${r}`}let gd=new WeakMap;async function gc(e){var t,r;let n,a,i,{sessionStore:o,leaseRegistry:s}=e,l=(n={...(t=function(e){let t=e$(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,n=eR(r);if(r&&!n)throw new k("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!n)throw new k("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let a=e.session||"default";return a.startsWith(`${n}:`)?{...e,meta:{...e.meta,tenantId:n,sessionIsolation:t}}:{...e,session:`${n}:${a}`,meta:{...e.meta,tenantId:n,sessionIsolation:t}}}(e.req)).flags??{}},((a=tf(t.command,n))||!t.flags)&&a?{...t,flags:n}:t);eM({level:"info",phase:"request_start",data:{session:l.session,command:l.command,tenant:l.meta?.tenantId,isolation:l.meta?.sessionIsolation}});let u=l.command;!function(e,t){if(gs.has(e.command)||e.meta?.sessionIsolation!=="tenant")return;let r=ff(e);t.assertLeaseAdmission({tenantId:r.tenantId,runId:r.runId,leaseId:r.leaseId,backend:r.leaseBackend})}(l,s);let d=function(e,t){var r;let n,a=e.session||"default";if(r=e,"string"==typeof(n=r.flags?.session)&&n.trim().length>0||"default"!==a||t.has(a))return a;let i=t.toArray();return 1===i.length?i[0].name:a}(l,o),c=gl.has(u)?null:await gu({req:l,sessionName:d,sessionStore:o}),p=(r=s,(i=gd.get(r))||(i=new Map,gd.set(r,i)),i);return{req:l,command:u,sessionName:d,throwIfCanceled:()=>re(l.meta?.requestId),runLocked:async e=>(re(l.meta?.requestId),c)?await rJ(p,c,async()=>(re(l.meta?.requestId),await e())):await e()}}function gp(e){var t,r;let{scope:n,logPath:a,sessionStore:i,trackDownloadableArtifact:o}=e;n.throwIfCanceled();let s=i.get(n.sessionName);s&&(!function(e){var t;let r,n=e.recording;if(!n||"ios"!==e.device.platform)return;let a=(t=e.device.id,(r=nH.get(t))?{sessionId:r.sessionId,alive:n0(r.child.pid)}:null);if(!n.runnerSessionId){a?.alive&&(n.runnerSessionId=a.sessionId);return}if(!a?.alive){n.invalidatedReason??="iOS runner session exited during recording";return}a.sessionId!==n.runnerSessionId&&(n.invalidatedReason??="iOS runner session restarted during recording")}(s),i.set(n.sessionName,s));let l=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let n={...e.flags??{}},a=t?gn(t,n):function(e,t,r){var n,a;let i=[];if(void 0!==e.platform&&t&&(n=e.platform,a=t,n&&a&&n!==a&&("apple"===n?!rX(a):"apple"!==a||!rX(n)))&&i.push({key:"platform",value:e.platform}),"open"===r)return i;for(let t of gi){let r=e[t];"string"==typeof r&&r.trim().length>0&&i.push({key:t,value:r})}return i}(n,e.meta?.lockPlatform,e.command);if(0===a.length)return!t&&e.meta?.lockPlatform&&void 0===n.platform&&(n.platform=e.meta.lockPlatform),{...e,flags:n};if("strip"===r)return t?(function(e,t){for(let r of t)delete e[r.key]}(n,a),n.platform=t.device.platform):function(e,t){for(let t of gi)delete e[t];t&&(e.platform=t)}(n,e.meta?.lockPlatform),{...e,flags:n};throw new k("INVALID_ARGS",`${e.command} cannot override session lock policy with ${a.map(ga).join(", ")}. Unset those selectors or remove the request lock policy.`)}(n.req,s),u=e=>(function(e,t,r){let n=e_();if(!t.ok){eM({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=eN({force:!0})??void 0;return{ok:!1,error:D(new k(x(t.error.code),t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:n.diagnosticId,logPath:e})}}return eM({level:"info",phase:"request_success"}),eN(),{ok:!0,data:function(e,t,r){var n,a;let i;if(!t)return t;let o=(n=e,i=Array.isArray((a=t).artifacts)?[...a.artifacts]:[],"screenshot"!==n.command||i.some(e=>e?.field==="path")||"string"!=typeof a.path||i.push({field:"path",path:a.path,localPath:n.meta?.clientArtifactPaths?.path,fileName:p.basename(n.meta?.clientArtifactPaths?.path??a.path)}),i.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===o.length?t:{...t,artifacts:o.map(t=>{let n=t.path;return{field:t.field,artifactId:r({artifactPath:n,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(l,e,o);if(s?.recording?.invalidatedReason&&"record"!==(t=n.command)&&"close"!==t)return{type:"response",response:u({ok:!1,error:{code:"COMMAND_FAILED",message:s.recording.invalidatedReason}})};!s||l.meta?.lockPolicy||(r=n.command,go.has(r))||function(e,t){let r=gn(e,t);if(0!==r.length){var n;let t,a,i;throw new k("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(n=e).device.platform,a=n.device.name.trim(),i=n.device.id,`${t} device "${a}" (${i})`)} and cannot be used with ${r.map(ga).join(", ")}. Use a different --session name or close this session first.`)}}(s,l.flags);let d=(e,t,r)=>{let n;return{...co(a,e,t,r,n=e_().requestId),requestId:n}};return{type:"scope",scope:{req:l,sessionName:n.sessionName,existingSession:s,finalize:u,contextFromFlags:d,handlerContextFromFlags:(e,t,r)=>({...d(e,t,r),surface:i.get(n.sessionName)?.surface})}}}async function gf(e){let{lockedScope:t,logPath:r,sessionStore:n}=e,a=n.get(t.sessionName);if(!a)return t.finalize({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let i=await pr({req:t.req,session:a,sessionName:t.sessionName,logPath:r,sessionStore:n,contextFromFlags:t.contextFromFlags});return t.finalize(i)}function gm(e){eM({level:"error",phase:"request_failed",data:{error:e instanceof Error?e.message:String(e)}});let t=e_(),r=eN({force:!0})??void 0;return{ok:!1,error:D(e,{diagnosticId:t.diagnosticId,logPath:r})}}async function gh(e,t=5e3){await Promise.all(e.map(async e=>{let r;await new Promise(n=>{r=setTimeout(()=>{!function(e){e.destroyConnections?.();let t="closeAllConnections"in e?e.closeAllConnections:void 0;if("function"==typeof t)return t.call(e);let r="closeIdleConnections"in e?e.closeIdleConnections:void 0;"function"==typeof r&&r.call(e)}(e),n()},t);try{e.close(()=>n())}catch{n()}}),r&&clearTimeout(r)}))}function gw(e){s.existsSync(e)&&s.unlinkSync(e)}function gg(e){if(!s.existsSync(e))return null;try{let t=JSON.parse(s.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function gy(e){let t=gg(e);if(!t||t.pid===process.pid)try{s.existsSync(e)&&s.unlinkSync(e)}catch{}}function gv(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}(async function(e={}){let t,r,n=e.env??process.env,a=e.stdout??process.stdout,o=e.stderr??process.stderr,l=e.exit??(e=>process.exit(e)),{baseDir:u,infoPath:d,lockPath:c,logPath:m,sessionsDir:h}=eK(n.AGENT_DEVICE_STATE_DIR),w=eY(n.AGENT_DEVICE_DAEMON_SERVER_MODE);var g,y,v,I=h;if(s.existsSync(I))for(let e of s.readdirSync(I,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=p.join(I,e.name,ak);if(s.existsSync(t))try{let e=aE(s.readFileSync(t,"utf8"));if(e&&function(e){let t,r=ew(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let n=ey(e.pid);return!!n&&!!((t=n.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||n===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{aP(t)}}let A=new aD(h),S=new iK({maxActiveSimulatorLeases:gv(n.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:gv(n.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:gv(n.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:gv(n.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),b=eD(),_=i.randomBytes(24).toString("hex"),N=ew(process.pid)??void 0,x=eO(),E=function(e){let{logPath:t,token:r,androidAdbProvider:n,appleRunnerProvider:a,appleToolProvider:i,linuxToolProvider:o,appLogProvider:s,recordingProvider:l,deviceInventoryProvider:u,trackDownloadableArtifact:d}=e,{sessionStore:c,leaseRegistry:p}=e;async function f(e){let m=!!(e.meta?.debug||e.flags?.verbose);return await eb({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:m,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:D(new k("UNAUTHORIZED","Invalid token"))};try{return await oh(u,async()=>{let u=await gc({req:e,sessionStore:c,leaseRegistry:p});return await u.runLocked(async()=>{let e=gp({scope:u,logPath:t,sessionStore:c,trackDownloadableArtifact:d});if("response"===e.type)return e.response;let m=e.scope;return await d0({req:m.req,existingSession:m.existingSession,providers:{androidAdbProvider:n,appleRunnerProvider:a,appleToolProvider:i,linuxToolProvider:o,appLogProvider:s,recordingProvider:l}},async e=>{let n=await gr({req:m.req,sessionName:m.sessionName,logPath:t,sessionStore:c,leaseRegistry:p,invoke:f,invokeReplayAction:function(e){let{parentScope:t,providerScope:r,handleRequest:n,deps:a}=e;return async e=>{var i,o;if(i=e,o=t,!(i.session===o.sessionName&&eP.replayScopedAction.has(i.command)))return await n(e);if(e.token!==a.token)return{ok:!1,error:D(new k("UNAUTHORIZED","Invalid token"))};try{let i=await gc({req:e,sessionStore:a.sessionStore,leaseRegistry:a.leaseRegistry});if(i.sessionName!==t.sessionName)return await n(e);let o=gp({scope:i,logPath:a.logPath,sessionStore:a.sessionStore,trackDownloadableArtifact:a.trackDownloadableArtifact});if("response"===o.type)return o.response;let s=o.scope,l=await gr({req:s.req,sessionName:s.sessionName,logPath:a.logPath,sessionStore:a.sessionStore,leaseRegistry:a.leaseRegistry,invoke:n,androidAdbExecutor:r.androidAdbExecutor,contextFromFlags:s.handlerContextFromFlags});if(l)return s.finalize(l);return await gf({lockedScope:s,logPath:a.logPath,sessionStore:a.sessionStore})}catch(e){return gm(e)}}}({parentScope:m,providerScope:e,handleRequest:f,deps:{logPath:t,token:r,sessionStore:c,leaseRegistry:p,trackDownloadableArtifact:d}}),androidAdbExecutor:e.androidAdbExecutor,contextFromFlags:m.handlerContextFromFlags});return n?m.finalize(n):await gf({lockedScope:m,logPath:t,sessionStore:c})})})})}catch(e){return gm(e)}})}return f}({logPath:m,token:_,sessionStore:A,leaseRegistry:S,trackDownloadableArtifact:im}),O=async e=>{await eb({command:"daemon",session:"daemon",logPath:m,debug:!0},async()=>{eM({level:"error",phase:"daemon_fatal",data:{error:e instanceof Error?e.message:String(e)}}),eN({force:!0})})},P=async e=>{let t=hl(e,e.name).catch(t=>{o.write(`Daemon session teardown error (${e.name}): ${t instanceof Error?t.message:String(t)}
66
+ `)});await Promise.race([t,ef(5e3).then(()=>{o.write(`Daemon session teardown timed out (${e.name}).
67
+ `)})]),A.writeSessionLog(e),A.delete(e.name)},C=async()=>{let e=A.toArray();await Promise.all(e.map(P))},L=async()=>{let e,t,r=[];if("http"!==w){let t,n,a=(t=new Set,(n=f.createServer(e=>{t.add(e),e.on("close",()=>t.delete(e));let r="",n=0,a=new Set,i=!1,o=()=>{if(!i&&0!==n){for(let e of(i=!0,a))t4(e);eM({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:n}}),(async()=>{try{let e=Date.now()+15e3;for(;n>0&&Date.now()<e&&(await nZ(),!(n<=0));)await ef(200)}catch(e){eM({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:n}})}})()}};e.setEncoding("utf8"),e.on("close",o),e.on("error",o),e.on("data",async t=>{let i=(r+=t).indexOf("\n");for(;-1!==i;){let t,o,s=r.slice(0,i).trim();if(r=r.slice(i+1),0===s.length){i=r.indexOf("\n");continue}n+=1;try{let e=JSON.parse(s);if(o=t3(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),t5(o),t6(o))throw t7();t=await E(e)}catch(e){t={ok:!1,error:D(e)}}finally{n-=1,o&&(a.delete(o),t8(o))}e.destroyed||e.write(`${JSON.stringify(t)}
68
+ `),i=r.indexOf("\n")}})})).destroyConnections=()=>{for(let e of t)e.destroy();t.clear()},n);r.push(a),e=await new Promise((e,t)=>{a.once("error",t),a.listen(0,"127.0.0.1",()=>{a.off("error",t);let r=a.address();"object"==typeof r&&r?.port?e(r.port):t(new k("COMMAND_FAILED","Failed to bind socket server"))})})}if("socket"!==w){let e=await iV({handleRequest:E,token:_});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 n=e.address();"object"==typeof n&&n?.port?t(n.port):r(new k("COMMAND_FAILED","Failed to bind HTTP server"))})})}return{servers:r,socketPort:e,httpPort:t}};if(!function(e,t,r){s.existsSync(e)||s.mkdirSync(e,{recursive:!0});let n=JSON.stringify(r,null,2),a=()=>{try{return s.writeFileSync(t,n,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(a())return!0;let i=gg(t);if(i?.pid&&i.pid!==process.pid&&eA(i.pid,i.processStartTime))return!1;try{s.unlinkSync(t)}catch{}return a()}(u,c,{pid:process.pid,version:b,startedAt:Date.now(),processStartTime:N}))return o.write("Daemon lock is held by another process; exiting.\n"),l(0),null;let R=[];try{let e,n=await L();R=n.servers,t=n.socketPort,r=n.httpPort,g=t,y=r,v={socketPort:g,httpPort:y,token:_,version:b,codeSignature:x,processStartTime:N},s.existsSync(u)||s.mkdirSync(u,{recursive:!0}),s.writeFileSync(m,""),e=v.socketPort&&v.httpPort?"dual":v.httpPort?"http":"socket",s.writeFileSync(d,JSON.stringify({port:v.socketPort,httpPort:v.httpPort,transport:e,token:v.token,pid:process.pid,version:v.version,codeSignature:v.codeSignature,processStartTime:v.processStartTime,stateDir:u},null,2),{mode:384}),g&&a.write(`AGENT_DEVICE_DAEMON_PORT=${g}
69
+ `),y&&a.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${y}
70
+ `)}catch(t){let e=M(t);for(let t of(o.write(`Daemon error: ${e.message}
71
+ `),R))try{t.close(()=>{})}catch{}return gw(d),gy(c),l(1),null}let T=!1,$=async(e={})=>{T||(T=!0,e.cause&&await O(e.cause),await gh(R),await C(),await nQ(),gw(d),gy(c),l(e.exitCode??0))};return!1!==e.registerProcessHandlers&&(process.on("SIGINT",()=>{$()}),process.on("SIGTERM",()=>{$()}),process.on("SIGHUP",()=>{$()}),process.on("uncaughtException",e=>{let t=e instanceof k?e:M(e);o.write(`Daemon error: ${t.message}
72
+ `),$({exitCode:1,cause:e})}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof k?t:M(t);o.write(`Daemon error: ${r.message}
73
+ `),$({exitCode:1,cause:t})})),{httpPort:r,shutdown:$,socketPort:t,token:_}})().catch(e=>{let t=M(e);process.stderr.write(`Daemon error: ${t.message}
74
+ `),process.exit(1)});