agent-device 0.12.9 → 0.13.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.
- package/README.md +20 -1
- package/dist/src/3918.js +28 -28
- package/dist/src/8564.js +1 -1
- package/dist/src/9076.js +1 -1
- package/dist/src/9542.js +2 -2
- package/dist/src/backend.js +1 -1
- package/dist/src/bin.js +32 -32
- package/dist/src/daemon.js +14 -14
- package/dist/src/index.d.ts +5 -0
- package/package.json +12 -3
- package/skills/agent-device/SKILL.md +2 -1
- package/skills/agent-device/references/debugging.md +3 -1
- package/skills/agent-device/references/exploration.md +4 -2
- package/skills/agent-device/references/verification.md +3 -2
- package/skills/dogfood/SKILL.md +1 -0
- package/skills/react-devtools/SKILL.md +53 -0
- package/skills/react-devtools/references/commands.md +91 -0
- package/skills/react-devtools/references/profiling.md +74 -0
- package/dist/src/4993.js +0 -1
package/dist/src/daemon.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import o from"node:path";import{spawn as s}from"node:child_process";import l from"node:http";import{fileURLToPath as d,pathToFileURL as u}from"node:url";import"node:https";import c from"node:os";import f from"node:fs/promises";import{setTimeout as p}from"node:timers/promises";import{PNG as m}from"pngjs";import h from"node:net";import{resolveUserPath as g}from"./3267.js";import{localCommandPolicy as w,createAgentDevice as y,readVersion as v,resolveDaemonCodeSignature as S,normalizeTenantId as I,resolveSessionIsolationMode as A,withDiagnosticsScope as b,resolveDaemonPaths as _,flushDiagnosticsToSessionFile as N,getDiagnosticsMeta as k,resolveDaemonServerMode as x,resolveDeployResultTarget as M,resolveInstallFromSourceResultTarget as D,emitDiagnostic as P}from"./8564.js";import{readProcessStartTime as L,isAgentDeviceDaemonProcess as R,readProcessCommand as O}from"./3883.js";import{toAppErrorCode as C,asAppError as E,normalizeError as $,AppError as T}from"./9152.js";import{runCmdBackground as U,runCmd as F}from"./9818.js";import{sleep as G,resolveTimeoutMs as V}from"./4829.js";import{resolveIosSimulatorDeviceSetPath as j,buildSimctlArgs as q,classifyAndroidAppTarget as H,parseSerialAllowlist as B,adbArgs as K,trimRuntimeValue as z,resolveAndroidSerialAllowlist as W,clearRuntimeHintsFromApp as J,hasRuntimeTransportHints as Z,buildSimctlArgsForDevice as X,formatAndroidInstalledPackageRequiredMessage as Y,applyRuntimeHintsToApp as Q}from"./9323.js";import{IOS_RUNNER_CONTAINER_BUNDLE_IDS as ee,resolveAppleSimulatorSetPathForSelector as et,dispatchCommand as er,validateAndNormalizeBatchSteps as ea,refSnapshotFlagGuardResponse as ei,buttonTag as en,handleSnapshotCommands as eo,shutdownSimulator as es,stopIosRunnerSession as el,getClickButtonValidationError as ed,createRequestCanceledError as eu,registerRequestAbort as ec,isNavigationSensitiveAction as ef,resolveIosDevicectlHint as ep,snapshotAndroid as em,resolveTargetDevice as eh,assertAndroidPressStayedInApp as eg,stopAllIosRunnerSessions as ew,withKeyedLock as ey,dispatchGetViaRuntime as ev,DEFAULT_BATCH_MAX_STEPS as eS,getAndroidAppState as eI,runMacOsAlertAction as eA,getAndroidScreenSize as eb,isDeepLinkTarget as e_,readTextForNode as eN,captureSnapshot as ek,dispatchIsViaRuntime as ex,resolveClickButton as eM,IOS_DEVICECTL_DEFAULT_HINT as eD,buildSnapshotState as eP,openAndroidApp as eL,context_contextFromFlags as eR,captureSnapshotData as eO,isRequestCanceled as eC,resolveRequestTrackingId as eE,resolvePayloadInput as e$,abortAllIosRunnerSessions as eT,getRunnerSessionSnapshot as eU,createUnsupportedArtifactAdapter as eF,isAndroidEscapeError as eG,markRequestCanceled as eV,resolveIosDeviceDeepLinkBundleId as ej,parseCoordinateTarget as eq,response_errorResponse as eH,runIosRunnerCommand as eB,dispatchFindReadOnlyViaRuntime as eK,ensureDeviceReady as ez,readInfoPlistString as eW,clearRequestCanceled as eJ,getActiveAndroidSnapshotFreshness as eZ,parseXmlDocumentSync as eX,resolveFrontmostMacOsApp as eY,IOS_SIMCTL_LIST_TIMEOUT_MS as eQ,listIosDeviceApps as e0,matchesPlatformSelector as e1,isCommandSupportedOnDevice as e2,isApplePlatform as e3,parseSessionSurface as e8,normalizePlatformSelector as e4,getRequestSignal as e5,markAndroidSnapshotFreshness as e9,buildScrollGesturePlan as e6,listIosDeviceProcesses as e7}from"./3918.js";import{withSuccessText as te,decodePng as tt,successText as tr}from"./9076.js";import{splitSelectorFromArgs as ta,findNearestHittableAncestor as ti,extractNodeText as tn,splitIsSelectorArgs as to,tryParseSelectorChain as ts,resolveSelectorChain as tl,resolveRefLabel as td,buildSelectorChainForNode as tu,normalizeType as tc,pruneGroupNodes as tf}from"./7847.js";import{attachRefs as tp,centerOfRect as tm}from"./4057.js";import{findBestMatchesByLocator as th,parseFindArgs as tg}from"./7556.js";function tw(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function ty(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tv=/^-?\d+(\.\d+)?$/,tS=/^[^\s"\\]+$/,tI=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tA=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tb=new Map([["--delay-ms","delayMs"]]);function t_(e){return"click"===e||"press"===e}function tN(e){return"type"===e||"fill"===e}function tk(e){return tM(e,tD)}function tx(e){return JSON.stringify(e)}function tM(e,t){return t(e)?e:tx(e)}function tD(e){return tP(e)&&e.startsWith("@")||tv.test(e)}function tP(e){return tS.test(e)}function tL(e,t){let r=t.flags??{};if(t_(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");let t=r.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern);return}tN(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tR(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",tM(t.metroHost,tP)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tM(t.bundleUrl,tP)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tM(t.launchUrl,tP)))}function tO(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tM(r,tP)),a))e.push(tk(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}function tC(e,t){let r=[],a={},i=t_(e)?tI:"swipe"===e?tA:tN(e)?tb:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(t_(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(t_(e)&&"--button"===o&&n+1<t.length){let e=t[n+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),n+=1;continue}let s=i?.get(o);if(s&&n+1<t.length){let e=t$(t[n+1]);if(null!==e){a[s]=e,n+=1;continue}}if("swipe"===e&&"--pattern"===o&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(o)}return{positionals:r,flags:a}}function tE(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let i=e[a];if("--platform"===i&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===i&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===i&&a+1<e.length){let t=t$(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===i&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===i&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(i)}return{positionals:t,flags:r}}function t$(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tT(e,t){for(let r of t.positionals??[])e.push(tk(r));t.flags?.relaunch&&e.push("--relaunch"),tR(e,t.runtime)}class tU{sessions=new Map;runtimeHints=new Map;sessionsDir;constructor(e){this.sessionsDir=e}get(e){return this.sessions.get(e)}has(e){return this.sessions.has(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){t.flags?.noRecord||(t.flags?.saveScript&&(e.recordSession=!0,"string"==typeof t.flags.saveScript&&(e.saveScriptPath=tU.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:function(e){if(!e)return{};let t={};for(let r of tF)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),P({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=o.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let i of(r.push(`context platform=${e.device.platform} device=${tx(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(t_(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tk(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tk(a)),tL(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tk(r)),tL(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tk(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tk(a)),e.positionals.length>1&&t.push(tk(i)),tL(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tk(r)),t.push(tk(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tk(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tk(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),"number"==typeof e.flags?.screenshotMaxSize&&t.push("--max-size",String(e.flags.screenshotMaxSize)),t.join(" ")}if("open"===e.command)return tT(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tM(r,tP)),tR(t,e.flags),t.join(" ")}if("record"===e.command)return tO(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tk(r));return tL(t,e),t.join(" ")}(i));return`${r.join("\n")}
|
|
2
|
-
`}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=
|
|
1
|
+
let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import o from"node:path";import{spawn as s}from"node:child_process";import l from"node:http";import{fileURLToPath as u,pathToFileURL as d}from"node:url";import"node:https";import c from"node:os";import f from"node:fs/promises";import{setTimeout as p}from"node:timers/promises";import{PNG as m}from"pngjs";import h from"node:net";import{resolveUserPath as g}from"./3267.js";import{localCommandPolicy as w,createAgentDevice as y,readVersion as v,resolveDaemonCodeSignature as I,normalizeTenantId as S,resolveSessionIsolationMode as A,withDiagnosticsScope as b,resolveDaemonPaths as _,flushDiagnosticsToSessionFile as N,getDiagnosticsMeta as k,resolveDaemonServerMode as x,resolveDeployResultTarget as D,resolveInstallFromSourceResultTarget as M,emitDiagnostic as P}from"./8564.js";import{readProcessStartTime as L,isAgentDeviceDaemonProcess as R,readProcessCommand as O}from"./3883.js";import{toAppErrorCode as E,asAppError as C,normalizeError as $,AppError as T}from"./9152.js";import{runCmdBackground as F,runCmd as U}from"./9818.js";import{sleep as G,resolveTimeoutMs as V}from"./4829.js";import{resolveIosSimulatorDeviceSetPath as j,buildSimctlArgs as q,classifyAndroidAppTarget as H,parseSerialAllowlist as B,adbArgs as K,trimRuntimeValue as z,resolveAndroidSerialAllowlist as W,clearRuntimeHintsFromApp as J,hasRuntimeTransportHints as Z,buildSimctlArgsForDevice as X,formatAndroidInstalledPackageRequiredMessage as Y,applyRuntimeHintsToApp as Q}from"./9323.js";import{IOS_RUNNER_CONTAINER_BUNDLE_IDS as ee,resolveAppleSimulatorSetPathForSelector as et,dispatchCommand as er,validateAndNormalizeBatchSteps as ea,refSnapshotFlagGuardResponse as ei,buttonTag as en,handleSnapshotCommands as eo,shutdownSimulator as es,stopIosRunnerSession as el,getClickButtonValidationError as eu,createRequestCanceledError as ed,registerRequestAbort as ec,isNavigationSensitiveAction as ef,resolveIosDevicectlHint as ep,snapshotAndroid as em,resolveTargetDevice as eh,assertAndroidPressStayedInApp as eg,stopAllIosRunnerSessions as ew,withKeyedLock as ey,dispatchGetViaRuntime as ev,DEFAULT_BATCH_MAX_STEPS as eI,getAndroidAppState as eS,runMacOsAlertAction as eA,getAndroidScreenSize as eb,isDeepLinkTarget as e_,readTextForNode as eN,captureSnapshot as ek,dispatchIsViaRuntime as ex,resolveClickButton as eD,IOS_DEVICECTL_DEFAULT_HINT as eM,buildSnapshotState as eP,openAndroidApp as eL,context_contextFromFlags as eR,captureSnapshotData as eO,isRequestCanceled as eE,resolveRequestTrackingId as eC,resolvePayloadInput as e$,abortAllIosRunnerSessions as eT,getRunnerSessionSnapshot as eF,createUnsupportedArtifactAdapter as eU,isAndroidEscapeError as eG,markRequestCanceled as eV,resolveIosDeviceDeepLinkBundleId as ej,parseCoordinateTarget as eq,response_errorResponse as eH,runIosRunnerCommand as eB,dispatchFindReadOnlyViaRuntime as eK,ensureDeviceReady as ez,readInfoPlistString as eW,clearRequestCanceled as eJ,getActiveAndroidSnapshotFreshness as eZ,parseXmlDocumentSync as eX,resolveFrontmostMacOsApp as eY,IOS_SIMCTL_LIST_TIMEOUT_MS as eQ,listIosDeviceApps as e0,matchesPlatformSelector as e1,isCommandSupportedOnDevice as e2,isApplePlatform as e3,parseSessionSurface as e8,normalizePlatformSelector as e4,getRequestSignal as e5,markAndroidSnapshotFreshness as e9,buildScrollGesturePlan as e6,listIosDeviceProcesses as e7}from"./3918.js";import{withSuccessText as te,decodePng as tt,successText as tr}from"./9076.js";import{splitSelectorFromArgs as ta,findNearestHittableAncestor as ti,extractNodeText as tn,splitIsSelectorArgs as to,tryParseSelectorChain as ts,resolveSelectorChain as tl,resolveRefLabel as tu,buildSelectorChainForNode as td,normalizeType as tc,pruneGroupNodes as tf}from"./7847.js";import{attachRefs as tp,centerOfRect as tm}from"./4057.js";import{findBestMatchesByLocator as th,parseFindArgs as tg}from"./7556.js";function tw(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function ty(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tv=/^-?\d+(\.\d+)?$/,tI=/^[^\s"\\]+$/,tS=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tA=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tb=new Map([["--delay-ms","delayMs"]]);function t_(e){return"click"===e||"press"===e}function tN(e){return"type"===e||"fill"===e}function tk(e){return tD(e,tM)}function tx(e){return JSON.stringify(e)}function tD(e,t){return t(e)?e:tx(e)}function tM(e){return tP(e)&&e.startsWith("@")||tv.test(e)}function tP(e){return tI.test(e)}function tL(e,t){let r=t.flags??{};if(t_(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");let t=r.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern);return}tN(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tR(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",tD(t.metroHost,tP)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tD(t.bundleUrl,tP)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tD(t.launchUrl,tP)))}function tO(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tD(r,tP)),a))e.push(tk(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}function tE(e,t){let r=[],a={},i=t_(e)?tS:"swipe"===e?tA:tN(e)?tb:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(t_(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(t_(e)&&"--button"===o&&n+1<t.length){let e=t[n+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),n+=1;continue}let s=i?.get(o);if(s&&n+1<t.length){let e=t$(t[n+1]);if(null!==e){a[s]=e,n+=1;continue}}if("swipe"===e&&"--pattern"===o&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(o)}return{positionals:r,flags:a}}function tC(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let i=e[a];if("--platform"===i&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===i&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===i&&a+1<e.length){let t=t$(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===i&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===i&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(i)}return{positionals:t,flags:r}}function t$(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tT(e,t){for(let r of t.positionals??[])e.push(tk(r));t.flags?.relaunch&&e.push("--relaunch"),tR(e,t.runtime)}class tF{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=tF.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 tU)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),P({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=o.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let i of(r.push(`context platform=${e.device.platform} device=${tx(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(t_(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tk(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tk(a)),tL(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tk(r)),tL(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tk(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tk(a)),e.positionals.length>1&&t.push(tk(i)),tL(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tk(r)),t.push(tk(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tk(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tk(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),"number"==typeof e.flags?.screenshotMaxSize&&t.push("--max-size",String(e.flags.screenshotMaxSize)),t.join(" ")}if("open"===e.command)return tT(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tD(r,tP)),tR(t,e.flags),t.join(" ")}if("record"===e.command)return tO(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tk(r));return tL(t,e),t.join(" ")}(i));return`${r.join("\n")}
|
|
2
|
+
`}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=tF.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return o.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return o.join(this.sessionsDir,tF.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return o.join(this.sessionsDir,tF.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return g(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tF.expandHome(e.saveScriptPath);i.existsSync(this.sessionsDir)||i.mkdirSync(this.sessionsDir,{recursive:!0});let t=tF.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return o.join(this.sessionsDir,`${t}-${r}.ad`)}buildOptimizedActions(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let a=Array.isArray(r.result?.selectorChain)&&r.result?.selectorChain.every(e=>"string"==typeof e)?r.result.selectorChain:[];if(a.length>0&&(t_(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(t_(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=tw(r);if(a.length>0){t.push({...r,positionals:[e,a]});continue}}if("get"===r.command){let a=r.positionals?.[0];if("text"===a||"attrs"===a){t.push({...r,positionals:[a,e]});continue}}}if(t_(r.command)||"fill"===r.command||"get"===r.command){let a=r.result?.refLabel;"string"==typeof a&&a.trim().length>0&&t.push({ts:r.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:a.trim()},result:{scope:a.trim()}})}t.push(r)}return t}}let tU=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw","screenshotFullscreen","screenshotMaxSize","relaunch","saveScript","noRecord","fps","quality","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"],tG="app-log.pid";function tV(e){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t))return{pid:Number.parseInt(t,10)};try{let e=JSON.parse(t);if(!Number.isInteger(e.pid)||e.pid<=0)return null;return e}catch{return null}}function tj(e,t){if(!e)return;let r=o.dirname(e);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:L(t)??void 0,command:O(t)??void 0};i.writeFileSync(e,`${JSON.stringify(a)}
|
|
3
3
|
`)}function tq(e){if(e&&i.existsSync(e))try{i.unlinkSync(e)}catch{}}async function tH(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}function tB(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],a="",i=a=>{(!(r.length>0)||r.some(e=>a.includes(e)))&&e.write(function(e,t){if(0===t.length)return e;let r=e;for(let e of t)r=r.replace(e,"[REDACTED]");return r}(a,t.redactionPatterns))};return{onChunk:e=>{let t=`${a}${e}`.split("\n");for(let e of(a=t.pop()??"",t))i(`${e}
|
|
4
|
-
`)},flush:()=>{a&&(i(a),a="")}}}function tK(e,t,r){let a=e.stdout,i=e.stderr;return a&&i?(a.setEncoding("utf8"),i.setEncoding("utf8"),a.on("data",r.writer.onChunk),i.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(a=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),a({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}function tz(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new T("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tW(e,t){let r=(await
|
|
5
|
-
`,recoveredLineCount:s.length}}async function tQ(e,t,r,a,i,n){let o="active",l=s("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return q(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tX(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tB(r,{redactionPatterns:a});"number"==typeof l.pid&&tj(n,l.pid);let u=tK(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(o="failed"),tq(n),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tH(u),l.killed||l.kill("SIGKILL"),await tH(u),tq(n)}}}async function t0(e,t,r,a){let i="active",n=s("log",["stream","--style","compact","--predicate",tX(e)],{stdio:["ignore","pipe","pipe"]}),o=tB(t,{redactionPatterns:r});"number"==typeof n.pid&&tj(a,n.pid);let l=tK(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tq(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tH(l),n.killed||n.kill("SIGKILL"),await tH(l),tq(a)}}}async function t1(e,t,r,a){let i="active",n=s("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tB(t,{redactionPatterns:r});"number"==typeof n.pid&&tj(a,n.pid);let l=tK(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tq(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tH(l),n.killed||n.kill("SIGKILL"),await tH(l),tq(a)}}}let t2=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),t3=/https?:\/\/[^\s"'<>\])]+/i,t8=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function t4(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t9(e)));for(let e of t.entries){let t=t9(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t5(e,t){let r=rs(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=rs(t?.maxPayloadChars,2048,64,16384),o=rs(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),d=s.slice(l),u=[];for(let e=d.length-1;e>=0&&u.length<r;e-=1){let t=d[e];if(!t?.trim())continue;let r=function(e,t,r,a,i,n){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=ra(s,["method","httpMethod"]),d=ra(s,["url","requestUrl"]),u=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(s,["status","statusCode","responseCode"]),c=t2.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=t3.exec(o),h=d??m?.[0];if(!h)return null;let g=u??t7(o)??void 0;if(!(l||f?.[1]||c?.[1]||void 0!==g||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let w={method:p,url:h,status:g,timestamp:re(o),packetId:rt(o)??void 0,durationMs:rr(o)??void 0,raw:ro(o,n),line:r};if("android"===a&&function(e,t,r){let a=t6(t,r,5),i=e.packetId??a.map(e=>rt(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t6(t,r,12).filter(e=>rt(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>re(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>t7(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>rr(e)).find(e=>"number"==typeof e))}(w,e,t),"headers"===i||"all"===i){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return rn(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=ro(e,n))}if("body"===i||"all"===i){let e=ri(o,s,["requestBody","body","payload","request"]),t=ri(o,s,["responseBody","response"]);e&&(w.requestBody=ro(e,n)),t&&(w.responseBody=ro(t,n))}return w}(d,e,l+e+1,a,i,n);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:o}}}function t9(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function t6(e,t,r){let a=[],i=Math.max(0,t-r),n=Math.min(e.length-1,t+r);for(let t=i;t<=n;t+=1){let r=e[t]?.trim();r&&a.push(r)}return a}function t7(e){for(let t of t8){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function re(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);if(t)return t[0];let r=/\b\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\b/.exec(e);return r?.[0]}function rt(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function rr(e){let t=/\b(?:duration|elapsed request\/response time, ms)[:= ]+(\d+)\b/i.exec(e);if(!t)return null;let r=Number.parseInt(t[1]??"",10);return Number.isInteger(r)?r:null}function ra(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function ri(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return rn(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(a?.[1])return a[1].trim()}}function rn(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ro(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function rs(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function rl(e,t){let r=process.env[e];if(!r)return t;let a=Number.parseInt(r,10);return Number.isInteger(a)&&a>0?a:t}function rd(e){let t=o.dirname(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),function(e,t){if(i.existsSync(e)&&!(i.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;i.existsSync(t)&&(i.existsSync(a)&&i.unlinkSync(a),i.renameSync(t,a))}}(e,{maxBytes:rl("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:rl("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function ru(e){var t,r,a,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",S=(t={backend:v,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y},o=rs(t?.maxEntries,25,1,200),s=t?.include??"summary",l=rs(t?.maxPayloadChars,2048,64,16384),d=rs(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?t5(i.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:d}}),I=[],A=await rc({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tJ(u.id,c);if(e){let t=t5(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(S=t4(t,S,h),I.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===S.entries.length){let e=await rp({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});e&&(e.dump.entries.length>0?(S=t4(e.dump,S,h),I.push(`Recovered ${e.dump.entries.length} iOS simulator HTTP entr${1===e.dump.entries.length?"y":"ies"} from simctl log show (${e.recoveredLineCount} app log lines scanned).`)):e.recoveredLineCount>0&&I.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===f?I.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===I.length&&("ios"===u.platform&&"simulator"===u.kind?I.push("Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop."):I.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===S.entries.length&&I.push("ios"===(n=u).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:S,notes:I}}async function rc(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tV(i.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(o.join(o.dirname(a),tG));if(!s)return null;let l=await tW(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function rf(e,t,r,a){rd(r);let n=i.createWriteStream(r,{flags:"a"}),o=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await t1(e.id,n,o,a):await tQ(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return tz(t),await tZ(e.id,t,n,o,a);if("macos"===e.platform)return await t0(t,n,o,a);throw n.end(),new T("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rp(e){let t=await tY({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t5(t.text,{path:`${e.appLogPath} (simctl log show recovery)`,backend:"ios-simulator",maxEntries:e.maxEntries,include:e.include,maxPayloadChars:e.maxPayloadChars,maxScanLines:e.maxScanLines}),recoveredLineCount:t.recoveredLineCount}:null}async function rm(e){await e.stop(),await tH(e.wait)}async function rh(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await F("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await F("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await F("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await F("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await F("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rg(e){let t=o.dirname(e),r=o.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let a=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{i.unlinkSync(o.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rw=new Map;function ry(e){let t=rw.get(e);if(t&&(clearTimeout(t.timer),rw.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rv=new Map;function rS(e,t){let r=rv.get(e);if(!r)throw new T("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rI(e){let t=rv.get(e);t&&(clearTimeout(t.timer),rv.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rA(e){let t=await rb(e);await F("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=o.join(e.tempDir,t);if(!i.existsSync(r))throw new T("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rb(e){let t=await F("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new T("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new T("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(r_),i=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new T("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new T("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new T("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===i||e.startsWith(`${i}/`)))throw new T("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,o=i;if(n!==o&&!n.startsWith(`${o}/`))throw new T("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await F("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new T("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function r_(e){if(e.includes("\0"))throw new T("INVALID_ARGS",`Invalid archive entry: ${e}`);if(o.posix.isAbsolute(e))throw new T("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=o.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new T("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rN=V(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function rk(e,t){return new Promise((r,a)=>{let n,o=i.createWriteStream(t),s=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},l=!1,d=0,u=e=>{if(!l){if(l=!0,n&&clearTimeout(n),e){o.destroy(),i.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new T("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rN});s(e),o.destroy(e),u(e)},rN)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");s(e),o.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new T("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",u),o.on("finish",()=>u()),c(),e.pipe(o)})}async function rx(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new T("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new T("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=o.basename(t);if(!r||"."===r||".."===r)throw new T("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),s=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),i.mkdtempSync(o.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=o.join(s,n);return await rk(e,t),{artifactPath:t,tempDir:s}}let t=o.join(s,"artifact.tar");await rk(e,t);let a=await rA({archivePath:t,tempDir:s,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:s}}catch(e){throw i.rmSync(s,{recursive:!0,force:!0}),e}}let rM=new Set(["agent_device.command","agent-device.command"]),rD=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rP=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rL={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},rR=new Set([...rM,...rD,...rP,...Object.keys(rL)]);function rO(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rC(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rE(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function r$(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function rT(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rU(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function rF(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=$(new T("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rO(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=$(new T(C(r.code,"UNAUTHORIZED"),r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rO(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=I(r.tenantId);if(!e){let e=$(new T("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rO(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rG(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=o.isAbsolute(t)?t:o.resolve(t);try{e=await import(u(a).href)}catch(e){throw new T("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let i=e[r];if("function"!=typeof i)throw new T("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rV(e){let t=await rG(),{handleRequest:r,token:a}=e;return l.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void rj(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void rq(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||rC(i,rO(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rC(i,rO(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rC(i,rO(a.id??null,-32600,"Invalid Request"),400);if(!rR.has(a.method))return void rC(i,rO(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rC(i,rO(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(rM.has(e))return{token:r$(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(rD.has(e)){let e,a=rT(t,"platform");if("ios"!==a&&"android"!==a)throw new T("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:r$(t,r),session:rT(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rT(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new T("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new T("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new T("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new T("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rU(t,"retentionMs")}}}if(rP.has(e)){let e=rT(t,"materializationId")?.trim();if(!e)throw new T("INVALID_ARGS","Invalid params: materializationId is required");return{token:r$(t,r),session:rT(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rT(t,"requestId"),materializationId:e}}}let a=rL[e];if(a)return{token:r$(t,r),session:rT(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rT(t,"tenantId")??rT(t,"tenant"),runId:rT(t,"runId"),leaseId:rT(t,"leaseId"),leaseTtlMs:rU(t,"ttlMs"),leaseBackend:rT(t,"backend")}};throw new T("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rM.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rC(i,rO(a.id??null,-32602,"Invalid params: command is required"),400);o=eE(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},ec(o);let d=()=>{i.writableFinished||eV(o)};e.on("aborted",d),i.on("close",d);let u=await rF(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rC(i,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void rC(i,{jsonrpc:"2.0",id:a.id??null,result:c});rC(i,rO(a.id??null,-32e3,c.error.message,c.error),rE(c.error.code))}catch(t){let e=$(t);rC(i,rO(a.id??null,-32e3,e.message,e),rE(e.code))}finally{eJ(o)}})})}async function rj(e,t,r,i){try{var n;let o,s,l=r$({},e.headers),d=rH(l,i);if(d){t.statusCode=rE(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await rF(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await rx(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=a.randomUUID(),(s=setTimeout(()=>{rI(o)},3e5)).unref(),rv.set(o,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:f}))}catch(r){let e=$(r);t.statusCode=rE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rq(e,t,r,a){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=r$({},e.headers),s=rH(o,a);if(s){t.statusCode=rE(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await rF(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:o,session:"default",command:"download_artifact",positionals:[n]}});if(!l.ok){t.statusCode=l.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.response.error?.data?.message??l.response.error?.message??"Unauthorized"}));return}let d=function(e,t){let r=rw.get(e);if(!r)throw new T("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw ry(e),new T("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=i.createReadStream(d.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),d.fileName&&t.setHeader("content-disposition",`attachment; filename="${d.fileName.replace(/"/g,"")}"`),u.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=$(e);t.statusCode=rE(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&ry(n)}),u.pipe(t)}catch(r){let e=$(r);t.statusCode=rE(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rH(e,t){return t&&e!==t?$(new T("UNAUTHORIZED","Invalid token")):null}function rB(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rK(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rz(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";if("ios-instance"===t||"android-instance"===t)return t;throw new T("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rW{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=rz(e.backend),r=I(e.tenantId);if(!r)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rB(e.runId);if(!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,i,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),d={leaseId:a.randomBytes(16).toString("hex"),tenantId:r,runId:i,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(d.leaseId,d),this.runBindings.set(o,d.leaseId),{...d}}heartbeatLease(e){let t=rK(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=rK(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=rz(e.backend),r=I(e.tenantId);if(!r)throw new T("INVALID_ARGS","tenant isolation requires tenant id.");let a=rB(e.runId);if(!a)throw new T("INVALID_ARGS","tenant isolation requires run id.");let i=rK(e.leaseId);if(!i)throw new T("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new T("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new T("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=I(t),i=rB(r);if(t&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rJ=V(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rZ=new Map;async function rX(e){let t=await f.mkdtemp(o.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await r0(e.installablePath,o.join(t,"installable")),i=e.archivePath?await r0(e.archivePath,o.join(t,"archive")):void 0,n=a.randomUUID(),s=e.ttlMs??rJ,l=Date.now()+s,d=setTimeout(()=>{rY(n)},s);return rZ.set(n,{rootPath:t,installablePath:r,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:n,installablePath:r,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await f.rm(t,{recursive:!0,force:!0}),e}}async function rY(e,t){let r=rZ.get(e);if(!r)throw new T("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rZ.delete(e),await f.rm(r.rootPath,{recursive:!0,force:!0})}async function rQ(e){let t=Array.from(rZ.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await rY(e)}))}async function r0(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=o.join(t,o.basename(e));return r.isDirectory()?await f.cp(e,a,{recursive:!0}):await f.copyFile(e,a),a}async function r1(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new T("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await ez(e.session.device),e.session.device}if(!r)throw new T("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await eh(e.flags??{});return await ez(a),a}async function r2(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,o,s=(n=function(e){let t=e.meta?.installSource;if(!t)throw new T("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new T("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new T("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:rS(o,t.meta?.tenantId)},cleanup:()=>{rI(o)}}:{source:n,cleanup:()=>{}}),l=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new T("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await r1({session:i,flags:t.flags});if(!e2("install",d))return eH("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=e5(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:n}=await import("./3918.js"),{prepareIosInstallArtifact:o}=await import("./3918.js"),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await rX({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs})),await n(d,c.installablePath),!c.bundleId)throw new T("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let o={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},s=te(o,r3(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await rY(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./3918.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./3918.js"),p=await c(s.source,{signal:u});try{l.enabled&&(e=await rX({archivePath:p.archivePath,installablePath:p.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs}));let n=await f(d,p.installablePath,p.packageName);if(!n)throw new T("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./3918.js"),s=o(n),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...s?{appName:s}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=te(u,r3(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await rY(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:$(e)}}}function r3(e){return`Installed: ${D(e)}`}async function r8(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new T("INVALID_ARGS","release_materialized_paths requires a materializationId");return await rY(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:$(e)}}}let r4=V(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r5=V(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r9(e,t,r){return t||r6(r)?null:eH("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function r6(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function r7(e){return"ios"===e.platform&&"simulator"===e.kind}async function ae(e,t){r7(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function at(e){let t=r6(e.flags)||!e.session?await eh(e.flags??{}):await ar(e.session.device);return!1!==e.ensureReady&&await ez(t),t}async function ar(e){if("ios"!==e.platform||"simulator"!==e.kind||"darwin"!==process.platform)return e;let t={platform:"ios",target:e.target,udid:e.id,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}};try{return await eh(t)}catch(e){if(!(e instanceof T)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await eh({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function aa(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let ai=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function an(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ao(e,t){if(void 0!==e){if("string"!=typeof e)throw new T("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return z(e)}}function as(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new T("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function al(e){if("ios"===e||"android"===e)return e}async function ad(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!Z(r)||Z(a)||await J({device:i.device,appId:i.appBundleId})}async function au(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(o))return eH("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){Z(l)&&s?.appBundleId&&await J({device:s.device,appId:s.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===o)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let d=al(e4(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return eH("INVALID_ARGS","runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first.");if(s&&s.device.platform!==d)return eH("INVALID_ARGS",`runtime set targets ${d}, but session "${i}" is already bound to ${s.device.platform}.`);let u={platform:(t=a.flags,r={platform:d,metroHost:z(t?.metroHost),metroPort:as(t?.metroPort),bundleUrl:z(t?.bundleUrl),launchUrl:z(t?.launchUrl)}).platform??l?.platform,metroHost:r.metroHost??l?.metroHost,metroPort:r.metroPort??l?.metroPort,bundleUrl:r.bundleUrl??l?.bundleUrl,launchUrl:r.launchUrl??l?.launchUrl};return 0===an(u)?eH("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(n.setRuntimeHints(i,u),{ok:!0,data:{session:i,configured:!0,runtime:u}})}let ac="open-command-roundtrip",af="Not implemented for this platform in this release.",ap=new Set(["app","desktop","frontmost-app"]);async function am(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eY();return{appBundleId:t.bundleId,appName:t.appName}}async function ah(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return e_(t)?"macos"===e.platform?void 0:"device"===e.kind?ej(r,t):void 0:await ag(e,t)}async function ag(e,t){try{let{resolveIosApp:r}=await import("./3918.js");return await r(e,t)}catch{return}}async function aw(e,t){if(!("android"!==e.platform||!t||e_(t)))try{let{resolveAndroidApp:r}=await import("./3918.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function ay(e,t,r,a){return await ah(e,t,r)??await a(e,t)??("android"===e.platform&&t&&e_(t)?r:void 0)}function av(e){return eH("INVALID_ARGS",e)}function aS(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:i}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return i??"app";if("linux"===t.platform){if(!r)return"app";let e=e8(r);if(!ap.has(e))throw new T("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new T("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new T("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?e8(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new T("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return eH(e instanceof T?e.code:"INVALID_ARGS",String(e.message))}}function aI(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&e_(r)?av("open --relaunch does not support URL targets."):"app"!==a?av("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===H(r)?av(Y(r)):null:null}async function aA(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await ez(i);let{appBundleId:l,appName:d}=await ab({device:i,surface:n,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new T("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ai.includes(e));if(i)throw new T("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ai.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new T("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new T("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:ao(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new T("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return as(e)}}(t.metroPort),bundleUrl:ao(t.bundleUrl,"bundleUrl"),launchUrl:ao(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:al(i.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let i=r?.platform,n=al(i);if(a.platform&&r&&!n)throw new T("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${i}.`);if(a.platform&&n&&a.platform!==n)throw new T("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${i}. Clear the runtime hints or use a different session.`);return n&&a.platform!==n?{...a,platform:n}:a}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&an(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=E(t);return eH(e.code,e.message,e.details)}}({req:t,sessionStore:a,sessionName:r,device:i});if(!u.ok)return{type:"response",response:u};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await ad({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function ab(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await am(r);return{appBundleId:n.appBundleId??await ay(t,a,i,aw),appName:n.appName??a}}let a_=new Map;async function aN(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await el(t.id),await er(t,"close",[r],a,i),await ae(t,r4)}async function ak(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||e_(d)||await er(r,"open",[l],a.flags?.out,{...eR(i,a.flags,n,o)})}async function ax(e){var t,r,a;let{req:i,sessionName:n,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:f,appBundleId:p,runtime:m,existingSession:h}=e,g=i.flags?.relaunch===!0,w=h?.trace?.outPath;if(g&&d){let e=p??d;await aN({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eR(s,i.flags,p??h?.appBundleId,w)}})}await Q({device:l,appId:p,runtime:m});let y=Date.now();await er(l,"open",u,i.flags?.out,{...eR(s,i.flags,p)}),await ak({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:ac,appTarget:d,appBundleId:p}:void 0;if(await ae(l,r5),eC(i.meta?.requestId)){let e=eu();return eH(e.code,e.message,e.details)}h&&e9(h,"open",h.snapshot);let S=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:n,device:l,surface:f,appBundleId:p,appName:c,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(t=o,r=n,(a=m)&&(0===an(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let I=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:i};return r&&(d.appName=r),a&&(d.appBundleId=a),n&&(d.startup=n),s&&l(s)>0&&(d.runtime=s),o&&(d.platform=o.platform,d.target=o.target??"mobile",d.device=o.name,d.id=o.id,d.kind=o.kind,"android"===o.platform&&(d.serial=o.id)),o?.platform==="ios"&&(d.device_udid=o.id,d.ios_simulator_device_set=o.simulatorSetPath??null),{...d,...tr(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:v,device:l,runtime:m,runtimeHintCount:an});return o.recordAction(S,{command:"open",positionals:u,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:I}),o.set(n,S),{ok:!0,data:I}}async function aM(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return eH("SESSION_NOT_FOUND",`Session "${r}" not found.`);let n=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(n?e.appName:void 0),l=aS(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?av("open --relaunch requires an app name or an active session app."):av("Session already active. Close it first or pass a new --session name.");let d=aI({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await ar(e.device),c=await aA({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await ax({req:t,sessionName:r,sessionStore:i,logPath:a,device:u,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let n=t.flags?.relaunch===!0,o=t.positionals?.[0];if(n&&!o)return av("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&e_(r)?av("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===H(r)?av(Y(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await eh(t.flags??{}),d=aS(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=aI({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await ey(a_,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return eH("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await aA({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await ax({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:d})})}async function aD(e){let t=await F("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function aP(e){let{device:t,shutdownRequested:r}=e;if(r&&(r7(t)||"android"===t.platform&&"emulator"===t.kind))try{return r7(t)?await es(t):await aD(t)}catch(t){let e=$(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aL(e){if(await el(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eA("dismiss",t).catch(t=>{P({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aR(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");n.appLog&&await rm(n.appLog),t.positionals&&t.positionals.length>0&&(e3(n.device.platform)&&await aL(n),await er(n.device,"close",t.positionals,t.flags?.out,{...eR(a,t.flags,n.appBundleId,n.trace?.outPath)}),await ae(n.device,r4)),e3(n.device.platform)&&await aL(n),Z(i.getRuntimeHints(r))&&n.appBundleId&&await J({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...tr(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rQ(r).catch(()=>{}),i.delete(r);let o=await aP({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:te({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...tr(`Closed: ${r}`)}}}let aO=["platform","target","device","udid","serial","verbose","out"];function aC(e,t){let r=e??{};for(let e of aO)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aE={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./3918.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./3918.js");return await a(e,t,r)}},a$={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./3918.js"),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await import("./3918.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aT(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},d=r9(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return eH("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,a=f?rS(f,t.meta?.tenantId):tU.expandHome(c);if(!i.existsSync(a))return eH("INVALID_ARGS",`App binary not found: ${a}`);let d=await at({session:s,flags:l,ensureReady:!1});if(!e2(r,d))return eH("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=te(e,(p=e,`Installed: ${p.appName??M(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&rI(f)}}async function aU(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return eH("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??eS;if(!Number.isInteger(i)||i<1||i>1e3)return eH("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=ea(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await aF(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=E(t);return eH(e.code,e.message,e.details)}}async function aF(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aC(e,n)}(e.flags,r.flags);void 0===o.session&&(o.session=t);let s=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:o,runtime:void 0===r.runtime?e.runtime:r.runtime,meta:e.meta}),l=Date.now()-n;return s.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:i,error:s.error}}async function aG(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new T("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await aV({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aj({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aq(t,u),a=!0)}else t=(await aj({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aq(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function aV(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await F("xcrun",q(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:eQ});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let[a,i]of Object.entries(e.devices??{}))if(!r||aH(a).includes(aH(r))){for(let e of i)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function aj(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await F("xcrun",q(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new T("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(n.stdout??"").trim();if(!o)throw new T("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aq(e,t){let r=await F("xcrun",q(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:eQ});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,a]of Object.entries(t.devices??{}))if(a.some(t=>t.udid===e))return r;return""}catch{return""}}function aH(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aB(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,i=j(e.iosSimulatorDeviceSet);if(!r)return eH("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await aG({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:ez});return{ok:!0,data:{udid:n.udid,device:n.device,runtime:n.runtime,ios_simulator_device_set:i??null,created:n.created,booted:n.booted}}}catch(t){let e=E(t);return eH(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=W(t.flags?.androidDeviceAllowlist),a=e4(t.flags?.platform),i=et({simulatorSetPath:j(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./3918.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./3918.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./3918.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./3918.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=E(t);return eH(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r9(t.command,e,i);if(n)return n;let o=await at({session:e,flags:i,ensureReady:!0});if(!e2("apps",o))return eH("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(e3(o.platform)){let{listIosApps:e}=await import("./3918.js");return{ok:!0,data:{apps:(await e(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await import("./3918.js");return{ok:!0,data:{apps:(await l(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function aK(e){let{ensureAndroidEmulatorBooted:t}=await import("./3918.js");return await t(e)}let az='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',aW='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function aJ(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=e4(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return eH("SESSION_NOT_FOUND","ios"===o?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`);let s=r9("appstate",i,n);if(s)return s;let l=e3(i?.device.platform)&&function(e,t){if(!t)return!1;if(!r6(e))return!0;let r=e4(e?.platform);return!(r&&!e1(t.device.platform,r)||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(n,i);if("ios"===o&&!l)return eH("SESSION_NOT_FOUND",az);if("macos"===o&&!l)return eH("SESSION_NOT_FOUND",aW);if(l&&i){let e=i.appName??i.appBundleId;if(!i.appName&&!i.appBundleId){if("macos"===i.device.platform&&i.surface&&"app"!==i.surface&&"frontmost-app"!==i.surface)return{ok:!0,data:{platform:i.device.platform,appName:i.surface,appBundleId:i.appBundleId,source:"session",surface:i.surface}};let e="macos"===i.device.platform?"macOS":"iOS";return eH("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:i.device.platform,appName:e??"unknown",appBundleId:i.appBundleId,source:"session",surface:i.surface??"app",..."ios"===i.device.platform?{device_udid:i.device.id,ios_simulator_device_set:i.device.simulatorSetPath??null}:{}}}}let d=await at({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return eH("SESSION_NOT_FOUND",az);if("macos"===d.platform)return eH("SESSION_NOT_FOUND",aW);let{getAndroidAppState:u}=await import("./3918.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function aZ(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r9(t.command,i,n);if(o)return o;let s="android"===(e4(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=aa({flags:n,sessionDevice:i?.device}),u=s&&!!d,c=!1;try{e=await at({session:i,flags:n,ensureReady:!1})}catch(r){let t=E(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return eH("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await aK({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return eH("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=aa({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return eH("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aK({avdName:t,serial:n.serial,headless:!0})}await ez(e)}else("android"!==e.platform||!0!==e.booted)&&await ez(e);return e2("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:eH("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await aJ({req:t,sessionName:r,sessionStore:a}):null}function aX(e){return Math.round(10*e)/10}let aY="adb-shell-dumpsys-cpuinfo",aQ="adb-shell-dumpsys-meminfo";async function a0(e,t){try{let r=await F("adb",K(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,o;let e=r.trim();if(0===e.length)continue;let s=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!s)continue;let l=Number(s[1]),d=s[2];Number.isFinite(l)&&(n=d,o=t,n===o||n.startsWith(`${o}:`))&&(i+=l,a.add(d))}return{usagePercent:aX(i),measuredAt:r,method:aY,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw a2("cpu",t,e)}}async function a1(e,t){try{let r=await F("adb",K(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new T("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let a=a3(e,"TOTAL PSS")??function(e){for(let t of e.split("\n")){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let r=e.split(/\s+/).slice(1).find(e=>null!==a8(e));if(!r)break;return a8(r)??void 0}}(e);if(void 0===a)throw new T("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:a,totalRssKb:a3(e,"TOTAL RSS"),measuredAt:r,method:aQ}}(r.stdout,t,new Date().toISOString())}catch(e){throw a2("memory",t,e)}}function a2(e,t,r){return r instanceof T&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new T(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof T?r:new T("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a3(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a8(a[1])??void 0}function a8(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a4="ps-process-snapshot",a5="ps-process-snapshot",a9="xctrace-activity-monitor",a6="xctrace-activity-monitor";async function a7(e,t){if("ios"===e.platform&&"device"===e.kind)return await ir(e,t);let r=await it(e,t),a=await id(e,r);if(0===a.length)throw new T("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let i=new Date().toISOString(),n=ty(a.map(e=>o.basename(iu(e.command))));return ic({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:n,cpuMethod:a4,memoryMethod:a5})}async function ie(e){let t=eX(e),r=ip(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new T("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}),i=a.indexOf("pid"),n=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(i<0||n<0||o<0||s<0)throw new T("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let i of t)r(i)&&a.push(i),a.push(...e(i.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,f;let t=e.children;if(0===t.length)continue;for(let e of t){let t=ip(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);u.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&u.set(e.attributes.id,{numberValue:im(e),processName:ig(e)})}let r=ih(t[i],u),a=(c=t[n],f=u,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:ig(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:ih(t[o],u),residentMemoryBytes:ih(t[s],u)})}return d}async function it(e,t){let r="macos"===e.platform?await is(t):await il(e,t),a="macos"===e.platform?o.join(r,"Contents","Info.plist"):o.join(r,"Info.plist"),i=await eW(a,"CFBundleExecutable");if(!i)throw new T("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?o.join(r,"Contents","MacOS",i):void 0}}async function ir(e,t){let r=await ia(e,t),a=await ii(e,t),i=await ii(e,t),n=io(await ie(a.xml),r,t,e),o=io(await ie(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new T("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new T("COMMAND_FAILED",`Incomplete Activity Monitor sample for ${t}`,{appBundleId:t,deviceId:e.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});return ic({usagePercent:Math.max(0,o.cpuTimeNs-n.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(i.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:a9,memoryMethod:a6})}async function ia(e,t){let r=(await e0(e,"all")).find(e=>e.bundleId===t);if(!r)throw new T("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new T("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await e7(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new T("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function ii(e,t){let r=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-ios-perf-")),a=o.join(r,"sample.trace"),i=o.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",a,"--quiet","--no-prompt"],o=await F("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==o.exitCode)throw new T("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:iw(o.stdout,o.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",i],d=await F("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new T("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:l,exitCode:d.exitCode,stdout:d.stdout,stderr:d.stderr,appBundleId:t,deviceId:e.id,hint:iw(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function io(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>o.basename(d(e.executable)))),s=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===s.length)throw new T("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:a.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let l=new Map;for(let e of s){let t=l.get(e.pid);if(!t){l.set(e.pid,e);continue}l.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:iy(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iy(t.residentMemoryBytes,e.residentMemoryBytes)})}let u=[...l.values()],c=u.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=u.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:c.length>0?c.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:ty(u.map(e=>e.processName))}}async function is(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await F("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new T("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!a)throw new T("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function il(e,t){let r=X(e,["get_app_container",e.id,t,"app"]),a=await F("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new T("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let i=a.stdout.trim();if(0===i.length)throw new T("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function id(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:X(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let a=e.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!a)continue;let i=Number(a[1]),n=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(o)&&t.push({pid:i,cpuPercent:n,rssKb:o,command:s})}return t})((await F("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=iu(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||o.basename(i)===a.executableName})}function iu(e){let[t=""]=e.trim().split(/\s+/,1);return t}function ic(e){return{cpu:{usagePercent:aX(e.usagePercent),measuredAt:e.measuredAt,method:e.cpuMethod,matchedProcesses:e.matchedProcesses},memory:{residentMemoryKb:Math.round(e.residentMemoryKb),measuredAt:e.measuredAt,method:e.memoryMethod,matchedProcesses:e.matchedProcesses}}}function ip(e,t){for(let r of e){if(t(r))return r;let e=ip(r.children,t);if(e)return e}}function im(e){if(!e||e.children.some(e=>"sentinel"===e.name)||!e.text)return null;let t=Number(e.text);return Number.isFinite(t)?t:null}function ih(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:im(e):null}function ig(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function iw(e,t){let r=ep(e,t);if(r)return r;let a=`${e}
|
|
6
|
-
${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?
|
|
7
|
-
`,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?iR(n,r,a,s):"start"===o?iO(n,r,a):"stop"===o?iC(n,r,a):eH("INVALID_ARGS",ib):eH("INVALID_ARGS",ib)}async function iL(e,t,r){let a=r.resolveAppLogPath(t),i=await rh(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:i.checks,notes:i.notes}}}async function iR(e,t,r,a){if(e.appLog&&!a)return eH("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return eH("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:rg(i)};e.appLog&&await rm(e.appLog);let n=rg(i),o=r.resolveAppLogPidPath(t);try{let a=await rf(e.device,e.appBundleId,i,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:i,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...n,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:$(a)}}}async function iO(e,t,r){if(e.appLog)return eH("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return eH("INVALID_ARGS","logs start requires an app session; run open <app> first");let a=r.resolveAppLogPath(t),i=r.resolveAppLogPidPath(t);try{let n=await rf(e.device,e.appBundleId,a,i);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:$(e)}}}async function iC(e,t,r){if(!e.appLog)return eH("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rm(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iE(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","network requires an active session");if(!e2("network",i.device))return eH("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!i_.includes(n))return eH("INVALID_ARGS",iN);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return eH("INVALID_ARGS","network dump limit must be an integer in range 1..200");let s=function(e){let t=e.positionals?.[2]?.toLowerCase(),r=e.flags?.networkInclude;if(t&&r&&t!==r)return eH("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return ik.includes(a)?{ok:!0,include:a}:eH("INVALID_ARGS",ix)}(t);if(!s.ok)return s;let{include:l}=s,d=await ru({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!i.appLog,state:i.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let i$=new Set(["ios","android","macos","linux"]);function iT(e,t,r){let a=e[t];if(void 0!==a)throw new T("INVALID_ARGS",a===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(a)} vs ${String(r)}.`);e[t]=r}function iU(e){return!!e&&!Number.isNaN(Number(e))}let iF=/[*?[\]{}]/;async function iG(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;ec(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=E(e);return eH(t.code,t.message)}).finally(()=>{eJ(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eV(i),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(n,[...d]))},n)})]):await c}finally{t&&clearTimeout(t),u&&(await iV(c)||P({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){P({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:E(e).message}})}}}async function iV(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function ij(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return eH("INVALID_ARGS","test requires at least one path or glob");try{var s,l,d,u,c,f;let e,p,m,h,g,w=function(e){let{inputs:t,cwd:r,platformFilter:a}=e,n=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tU.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>o.join(n,e));if(t.isFile()){if(".ad"!==o.extname(n))throw new T("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!iF.test(r)&&(a=n,!iF.test(a)))throw new T("INVALID_ARGS",`test input not found: ${e}`);let s=o.isAbsolute(n)?n:e;return i.globSync(s,{cwd:o.isAbsolute(n)?void 0:t}).map(e=>o.isAbsolute(e)?e:o.resolve(t,e)).filter(e=>".ad"===o.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>o.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var d,u;let t=function(e){let t=e.split(/\r?\n/),r={};for(let e of t){let t=e.trim();if(0===t.length||t.startsWith("#"))continue;if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&i$.has(e)&&iT(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&iT(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&iT(r,"retries",Math.floor(e))}}return r}(i.readFileSync(e,"utf8"));if(!a){l.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){l.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${a}`});continue}d=a,u=t.platform,("apple"===d?"apple"===u||"ios"===u||"macos"===u:u===d)&&l.push({kind:"run",path:e,metadata:t})}if(0===l.filter(e=>"run"===e.kind).length){let e=a?` for --platform ${a}`:"";throw new T("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tU.expandHome(t??".agent-device/test-artifacts",r);return o.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),S=[],I=Date.now(),A=0;for(let e of w){if("skip"===e.kind){S.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await iq({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(S.push(i),t.flags?.failFast===!0)break}let b=(u=w.length,c=S,f=Date.now()-I,e=c.filter(e=>"passed"===e.status).length,m=(p=c.filter(e=>"failed"===e.status)).length,h=c.filter(e=>"skipped"===e.status).length,g=e+m,{total:u,executed:g,passed:e,failed:m,skipped:h,notRun:Math.max(0,u-g-h),durationMs:f,failures:p,tests:c});return{ok:!0,data:b}}catch(t){let e=E(t);return eH(e.code,e.message)}}async function iq(e){var t,r;let a,n,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,y=Date.now(),v=o.join(h,(t=s.path,(0===(n=c?o.relative(c,t):o.basename(t)).length||n.startsWith("..")?o.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),S="",I=0;for(let e=0;e<=p;e+=1){I=e+1;let t=function(e,t,r,a,i=0){let n=o.basename(r,o.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),n=o.join(v,`attempt-${I}`);r=s.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,o.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eE(`${t??r}:test:${i+1}:${o.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await iG({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:s,attemptArtifactsDir:l}=e,d=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(t)];t.ok||"string"!=typeof t.error.logPath||d.push(t.error.logPath);let u=function(e,t){let r=[],a=new Map;for(let n of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=o.extname(e),a=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${a}-${i+1}${r}`}(o.basename(n),a),s=o.join(t,e);o.resolve(n)!==o.resolve(s)&&i.copyFileSync(n,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${s}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");u.length>0&&c.push(`copiedArtifacts: ${u.map(e=>o.basename(e)).join(", ")}`);let f=o.join(l,"result.txt"),p=`${c.join("\n")}
|
|
8
|
-
`;i.writeFileSync(f,p),t.ok||i.writeFileSync(o.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:I,maxAttempts:p+1,attemptArtifactsDir:n}),a=h,S=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:s.path,session:S,status:"passed",durationMs:A,attempts:I,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let b=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:S,status:"failed",durationMs:A,attempts:I,artifactsDir:v,error:b}}function iH(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=ta(r?e.slice(0,-1):e.slice());return!a||a.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:a.selectorExpression,selectorTimeout:r?t:null}}async function iB(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(t_(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let n=i.get(r);if(!n)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),t_(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=to(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=iH(e.positionals??[]);r&&t.push(r)}return ty(t).filter(e=>e.trim().length>0)})(t).map(e=>ts(e)).filter(e=>null!==e);if(0===o.length)return null;let s=t_(t.command)||"fill"===t.command,l=t_(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await iK(n,t,a,s,i);for(let e of o){let r=tl(d.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=tu(r.node,n.device.platform,{action:t_(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(t_(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=tw(t);if(!e)continue;return{...t,positionals:[a,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,a]}}if("is"===t.command){let{predicate:e,split:r}=to(t.positionals);if(!e)continue;let i=r?.rest.join(" ").trim()??"",n=[e,a];return"text"===e&&i.length>0&&n.push(i),{...t,positionals:n}}if("wait"===t.command){let{selectorTimeout:e}=iH(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function iK(e,t,r,a,i){let n=await er(e.device,"snapshot",[],t.flags?.out,{...eR(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:tp(t.flags?.snapshotRaw?o:tf(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return e.snapshot=s,i.set(e.name,e),s}async function iz(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o}=e,s=t.positionals?.[0];if(!s)return eH("INVALID_ARGS","replay requires a path");let l="",d=new Set;try{l=tU.expandHome(s,t.meta?.cwd);let e=i.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return eH("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let c=function(e){let t=[];for(let r of e.split(/\r?\n/)){let e=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let r=function(e){let t=[],r=0;for(;r<e.length;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let a=r+1,i=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!i)break;i="\\"===t&&!i,"\\"!==t&&(i=!1),a+=1}if(a>=e.length)throw new T("INVALID_ARGS",`Invalid replay script line: ${e}`);let n=e.slice(r,a+1);t.push(JSON.parse(n)),r=a+1;continue}let a=r;for(;a<e.length&&!/\s/.test(e[a]);)a+=1;t.push(e.slice(r,a)),r=a}return t}(t);if(0===r.length)return null;let[a,...i]=r;if("context"===a)return null;let n={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){n.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){n.flags.snapshotCompact=!0;continue}if("--raw"===t){n.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(n.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){n.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}return n}if("open"===a){let e=function(e){var t;let r=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}r.push(t)}let i=tE(r);return{positionals:i.positionals,flags:a,runtime:(t=i.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?i.flags:void 0}}(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n.runtime=e.runtime,n}if("runtime"===a){let e=tE(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(t_(a)){let e=tC(a,i);if(Object.assign(n.flags,e.flags),0===e.positionals.length)return n;let t=e.positionals[0];if(t.startsWith("@"))return n.positionals=[t],e.positionals[1]&&(n.result={refLabel:e.positionals[1]}),n;let r=e.positionals[0],o=e.positionals[1];return iU(r)&&iU(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tC(a,i);if(Object.assign(n.flags,e.flags),e.positionals.length<2)return n.positionals=e.positionals,n;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(n.positionals=[t,e.positionals.slice(2).join(" ")],n.result={refLabel:e.positionals[1]}):n.positionals=[t,e.positionals[1]],n):(n.positionals=[t,e.positionals.slice(1).join(" ")],n)}if("get"===a){if(i.length<2)return n.positionals=i,n;let e=i[0],t=i[1];return t.startsWith("@")?(n.positionals=[e,t],i[2]&&(n.result={refLabel:i[2]})):n.positionals=[e,i.slice(1).join(" ")],n}if("swipe"===a||"type"===a){let e=tC(a,i);return Object.assign(n.flags,e.flags),n.positionals=e.positionals,n}if("record"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--hide-touches"===r){n.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return n.positionals=e,n}if("screenshot"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--fullscreen"===r){n.flags.screenshotFullscreen=!0;continue}if("--max-size"===r){let e=i[t+1],r=void 0===e?NaN:Number(e);if(!Number.isInteger(r)||r<1)throw new T("INVALID_ARGS","screenshot --max-size requires a positive integer");n.flags.screenshotMaxSize=r,t+=1;continue}e.push(r)}return n.positionals=e,n}return n.positionals=i,n}(r);e&&t.push(e)}return t}(e),f=t.flags?.replayUpdate===!0,p=0;for(let e=0;e<c.length;e+=1){let i=c[e];if(!i||"replay"===i.command)continue;let s=await iW({req:t,sessionName:r,action:i,invoke:o});if(s.ok){iZ(s).forEach(e=>d.add(e));continue}if(!f)return iJ(s,i,e,l,[...d]);let u=await iB({action:i,sessionName:r,logPath:a,sessionStore:n});if(!u)return iJ(s,i,e,l,[...d]);if(c[e]=u,!(s=await iW({req:t,sessionName:r,action:u,invoke:o})).ok)return iJ(s,u,e,l,[...d]);iZ(s).forEach(e=>d.add(e)),p+=1}return f&&p>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${tx(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tT(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tM(r,tP));return tR(t,e.flags),t.join(" ")}if("record"===e.command)return tO(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tk(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),"number"==typeof e.flags?.screenshotMaxSize&&t.push("--max-size",String(e.flags.screenshotMaxSize)),t.join(" ")}for(let r of e.positionals??[])t.push(tk(r));return tL(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
|
|
9
|
-
`,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=E(t);return eH(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function iW(e){var t;let{req:r,sessionName:a,action:i,invoke:n}=e;return await n({token:r.token,session:a,command:i.command,positionals:i.positionals??[],flags:(t=r.flags,aC(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function iJ(e,t,r,a,i=[]){let n;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${n=(t.positionals??[]).map(e=>tk(e)),[t.command,...n].join(" ")}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:a,step:o,action:t.command,positionals:t.positionals??[],artifactPaths:i}}}}function iZ(e){if(!e.ok||!e.data)return[];let t=[];if("string"==typeof e.data.path&&t.push(e.data.path),"string"==typeof e.data.outPath&&t.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let r of e.data.artifacts){if(!r||"object"!=typeof r)continue;let e="string"==typeof r.localPath?r.localPath:void 0,a="string"==typeof r.path?r.path:void 0;e?t.push(e):a&&t.push(a)}return[...new Set(t.filter(e=>(function(e){try{return i.statSync(e).isFile()}catch{return!1}})(e)))]}async function iX(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await iz({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await ij({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await iz({req:{...t,command:"replay",session:r,positionals:[e],flags:void 0===o?t.flags:{...t.flags??{},platform:o},meta:s?{...t.meta??{},requestId:s}:t.meta},sessionName:r,logPath:a,sessionStore:i,invoke:async e=>{var t;return t=await n(e),l&&iZ(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await aR({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let iY=new Set(["session_list","ensure-simulator","devices","apps"]),iQ=new Set(["boot","appstate"]),i0=new Set(["perf","logs","network"]),i1=new Set(["replay","test"]);async function i2(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=i.get(r),u=t.flags??{},c=r9(n,d,u);if(c)return c;let f=await at({session:d,flags:u,ensureReady:!0});if(!e2(n,f))return eH("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await er(f,n,o,t.flags?.out,{...eR(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,p,f):d;i.recordAction(e,{command:n,positionals:s??o,flags:t.flags??{},result:p??{}}),e!==d&&i.set(r,e)}return{ok:!0,data:p??{}}}async function i3(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r9("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return eH("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await at({session:n,flags:o,ensureReady:!0});if(!e2("clipboard",d))return eH("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await er(d,"clipboard",t.positionals??[],t.flags?.out,{...eR(a,t.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function i8(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(iY.has(t.command))return await aB({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await au({req:t,sessionName:r,sessionStore:i});if(iQ.has(t.command))return await aZ({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await i3({req:t,sessionName:r,logPath:a,sessionStore:i});if("keyboard"===t.command){let e=i.get(r),n=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==n||"ios"!==e4((t.flags??{}).platform)?await i2({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):eH("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(i0.has(t.command))return await iM({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aT({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?a$:aE});if("install_source"===t.command)return await r2({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r8({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await i2({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=e$(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tU.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):eH("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await i2({req:t,sessionName:r,logPath:a,sessionStore:i,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await ay(e.device,r,e.appBundleId,aw)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aM({req:t,sessionName:r,logPath:a,sessionStore:i}):i1.has(t.command)?await iX({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await aU(t,r,n):"close"===t.command?await aR({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function i4(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return eH("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=tg(s);if(!d)return eH("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return eH("INVALID_ARGS","find accepts only one of --first or --last");let p=await eK({req:t,sessionName:r,logPath:a,sessionStore:i});if(p)return p;let m=i.get(r);if(!m&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await eh(t.flags??{});m||await ez(h);let g="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,y=0,v=null,S=async()=>{let e=Date.now();if(v&&e-y<750&&!eZ(m))return{nodes:v};let{snapshot:n}=await ek({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return y=e,v=o,m&&(m.snapshot=n,i.set(r,m)),{nodes:o,truncated:n.truncated,backend:n.backend}},I={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:o,locator:l,query:d};if("wait"===u)return i5(I,S,l,d,f);let{nodes:A}=await S(),b=th(A,l,d,{requireRect:w});if(w&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,k;let e;return _=b.matches,N=l,k=d,e=_.slice(0,8).map(e=>{let t=tn(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eH("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${k}". Use a more specific locator or selector.`,{locator:N,query:k,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let x=b.matches[0]??null;if(!x)return eH("COMMAND_FAILED","find did not match any element");let M="click"===u||"focus"===u||"fill"===u||"type"===u?ti(A,x)??x:x,D=`@${M.ref}`,P={node:x,resolvedNode:M,ref:D,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>i9(I),get_text:()=>i6(I,P),get_attrs:()=>i7(I,P),click:()=>ne(I,P),fill:()=>nt(I,P,c),focus:()=>nr(I,P),type:()=>na(I,P,c)}[u];return L?L():null}async function i5(e,t,r,a,i){let{req:n,sessionStore:o,session:s,command:l}=e,d=i??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(th(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:n.positionals??[],flags:n.flags??{},result:{found:!0,waitedMs:Date.now()-u}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-u}};await G(300)}return eH("COMMAND_FAILED","find wait timed out")}async function i9(e){let{req:t,sessionStore:r,session:a,command:i}=e;return a&&r.recordAction(a,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function i6(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await eN({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eR(s,e,t,r)});return i&&a.recordAction(i,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get text",text:l}}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function i7(e,t){let{req:r,sessionStore:a,session:i,command:n}=e;return i&&a.recordAction(i,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function ne(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,invoke:o,command:s,locator:l,query:d}=e,u=await o({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let c=t.resolvedNode.rect?tm(t.resolvedNode.rect):null,f={ref:t.ref,locator:l,query:d};return c&&(f.x=c.x,f.y=c.y),n&&i.recordAction(n,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:f}}async function nt(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return eH("INVALID_ARGS","find fill requires text");let d=await s({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&n.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function nr(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?tm(t.node.rect):null;if(!l)return eH("COMMAND_FAILED","matched element has no bounds");let d=await er(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eR(s,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function na(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return eH("INVALID_ARGS","find type requires text");let d=t.node.rect?tm(t.node.rect):null;if(!d)return eH("COMMAND_FAILED","matched element has no bounds");await er(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eR(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await er(o,"type",[r],a.flags?.out,{...eR(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let ni=`
|
|
4
|
+
`)},flush:()=>{a&&(i(a),a="")}}}function tK(e,t,r){let a=e.stdout,i=e.stderr;return a&&i?(a.setEncoding("utf8"),i.setEncoding("utf8"),a.on("data",r.writer.onChunk),i.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(a=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),a({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}function tz(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new T("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tW(e,t){let r=(await U("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tJ(e,t){var r,a;let i;tz(t);let n=await tW(e,t),o=await U("adb",["-s",e,"logcat","-d","-v","time","-t","4000"],{allowFailure:!0,timeoutMs:3e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=function(e,t,r){let a=new Set;for(let i of(r&&a.add(r),e.split("\n")))if(i.includes(t))for(let e of function(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=[RegExp(`\\bStart proc\\s+(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`\\b(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`${r}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,"i"),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${r}`,"i")],i=[];for(let t of a){let r=t.exec(e),a=r?.[1];a&&/^\d+$/.test(a)&&i.push(a)}return i}(i,t))a.add(e);return[...a]}(o.stdout,t,n);if(0===s.length)return null;let l=(r=o.stdout,a=t,i=new Set(s),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(a))return!0;let n=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!n&&i.has(n)}).join("\n"));return 0===l.trim().length?null:{pid:n,text:l,recoveredPids:s}}async function tZ(e,t,r,a,i){let n,o,l="recovering",u=!1,d=(async()=>{try{for(;!u;){let d=await tW(e,t);if(!d){l="recovering",await G(1e3);continue}let c=s("adb",["-s",e,"logcat","-v","time","--pid",d],{stdio:["ignore","pipe","pipe"]});n=c;let f=tB(r,{redactionPatterns:a});if(o=tK(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&(tj(i,c.pid),l="active"),await o,tq(i),n=void 0,o=void 0,u)break;l="recovering",await G(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tq(i)}})();return{backend:"android",getState:()=>l,startedAt:Date.now(),wait:d,stop:async()=>{u=!0,n&&!n.killed&&n.kill("SIGINT"),o&&await tH(o),n&&!n.killed&&n.kill("SIGKILL"),await tH(d),tq(i)}}}function tX(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function tY(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=q(["spawn",t,"log","show","--style","compact","--info","--predicate",tX(r)],{simulatorSetPath:i});"number"==typeof a&&Number.isFinite(a)&&a>0?n.push("--start",`@${Math.floor(a/1e3)}`):n.push("--last","5m");let o=await U("xcrun",n,{allowFailure:!0,timeoutMs:4e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=o.stdout.split("\n").map(e=>e.trimEnd()).filter(e=>{let t=e.trim();return t.length>0&&!t.startsWith("Timestamp Ty Process[PID:TID]")});return 0===s.length?null:{text:`${s.join("\n")}
|
|
5
|
+
`,recoveredLineCount:s.length}}async function tQ(e,t,r,a,i,n){let o="active",l=s("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return q(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tX(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),u=tB(r,{redactionPatterns:a});"number"==typeof l.pid&&tj(n,l.pid);let d=tK(l,r,{endStreamOnClose:!0,writer:u}).then(e=>(0!==e.exitCode&&(o="failed"),tq(n),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:d,stop:async()=>{l.killed||l.kill("SIGINT"),await tH(d),l.killed||l.kill("SIGKILL"),await tH(d),tq(n)}}}async function t0(e,t,r,a){let i="active",n=s("log",["stream","--style","compact","--predicate",tX(e)],{stdio:["ignore","pipe","pipe"]}),o=tB(t,{redactionPatterns:r});"number"==typeof n.pid&&tj(a,n.pid);let l=tK(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tq(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tH(l),n.killed||n.kill("SIGKILL"),await tH(l),tq(a)}}}async function t1(e,t,r,a){let i="active",n=s("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tB(t,{redactionPatterns:r});"number"==typeof n.pid&&tj(a,n.pid);let l=tK(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tq(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tH(l),n.killed||n.kill("SIGKILL"),await tH(l),tq(a)}}}let t2=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),t3=/https?:\/\/[^\s"'<>\])]+/i,t8=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function t4(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t9(e)));for(let e of t.entries){let t=t9(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t5(e,t){let r=rs(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=rs(t?.maxPayloadChars,2048,64,16384),o=rs(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),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,a,i,n){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=ra(s,["method","httpMethod"]),u=ra(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=t2.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=t3.exec(o),h=u??m?.[0];if(!h)return null;let g=d??t7(o)??void 0;if(!(l||f?.[1]||c?.[1]||void 0!==g||/\bURL["'=: ]+https?:\/\//i.test(o)||/\bheaders?["'=: ]+/i.test(o)||/\b(?:requestBody|responseBody|payload|request|response)["'=: ]+/i.test(o)))return null;let w={method:p,url:h,status:g,timestamp:re(o),packetId:rt(o)??void 0,durationMs:rr(o)??void 0,raw:ro(o,n),line:r};if("android"===a&&function(e,t,r){let a=t6(t,r,5),i=e.packetId??a.map(e=>rt(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t6(t,r,12).filter(e=>rt(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>re(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>t7(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>rr(e)).find(e=>"number"==typeof e))}(w,e,t),"headers"===i||"all"===i){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return rn(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=ro(e,n))}if("body"===i||"all"===i){let e=ri(o,s,["requestBody","body","payload","request"]),t=ri(o,s,["responseBody","response"]);e&&(w.requestBody=ro(e,n)),t&&(w.responseBody=ro(t,n))}return w}(u,e,l+e+1,a,i,n);r&&d.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:u.length,matchedLines:d.length,entries:d,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:o}}}function t9(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function t6(e,t,r){let a=[],i=Math.max(0,t-r),n=Math.min(e.length-1,t+r);for(let t=i;t<=n;t+=1){let r=e[t]?.trim();r&&a.push(r)}return a}function t7(e){for(let t of t8){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function re(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);if(t)return t[0];let r=/\b\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\b/.exec(e);return r?.[0]}function rt(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function rr(e){let t=/\b(?:duration|elapsed request\/response time, ms)[:= ]+(\d+)\b/i.exec(e);if(!t)return null;let r=Number.parseInt(t[1]??"",10);return Number.isInteger(r)?r:null}function ra(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function ri(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return rn(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(a?.[1])return a[1].trim()}}function rn(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ro(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function rs(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function rl(e,t){let r=process.env[e];if(!r)return t;let a=Number.parseInt(r,10);return Number.isInteger(a)&&a>0?a:t}function ru(e){let t=o.dirname(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),function(e,t){if(i.existsSync(e)&&!(i.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;i.existsSync(t)&&(i.existsSync(a)&&i.unlinkSync(a),i.renameSync(t,a))}}(e,{maxBytes:rl("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:rl("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function rd(e){var t,r,a,n;let o,s,l,u,{device:d,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,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:g,maxPayloadChars:w,maxScanLines:y},o=rs(t?.maxEntries,25,1,200),s=t?.include??"summary",l=rs(t?.maxPayloadChars,2048,64,16384),u=rs(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?t5(i.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:u}}),S=[],A=await rc({device:d,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tJ(d.id,c);if(e){let t=t5(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(I=t4(t,I,h),S.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===d.platform&&"simulator"===d.kind&&c&&0===I.entries.length){let e=await rp({deviceId:d.id,appBundleId:c,startedAt:p,simulatorSetPath:d.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});e&&(e.dump.entries.length>0?(I=t4(e.dump,I,h),S.push(`Recovered ${e.dump.entries.length} iOS simulator HTTP entr${1===e.dump.entries.length?"y":"ies"} from simctl log show (${e.recoveredLineCount} app log lines scanned).`)):e.recoveredLineCount>0&&S.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===f?S.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===S.length&&("ios"===d.platform&&"simulator"===d.kind?S.push("Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop."):S.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&S.push("ios"===(n=d).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:I,notes:S}}async function rc(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tV(i.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(o.join(o.dirname(a),tG));if(!s)return null;let l=await tW(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function rf(e,t,r,a){ru(r);let n=i.createWriteStream(r,{flags:"a"}),o=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await t1(e.id,n,o,a):await tQ(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return tz(t),await tZ(e.id,t,n,o,a);if("macos"===e.platform)return await t0(t,n,o,a);throw n.end(),new T("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rp(e){let t=await tY({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t5(t.text,{path:`${e.appLogPath} (simctl log show recovery)`,backend:"ios-simulator",maxEntries:e.maxEntries,include:e.include,maxPayloadChars:e.maxPayloadChars,maxScanLines:e.maxScanLines}),recoveredLineCount:t.recoveredLineCount}:null}async function rm(e){await e.stop(),await tH(e.wait)}async function rh(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await U("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await U("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await U("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 U("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await U("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rg(e){let t=o.dirname(e),r=o.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let a=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{i.unlinkSync(o.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rw=new Map;function ry(e){let t=rw.get(e);if(t&&(clearTimeout(t.timer),rw.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rv=new Map;function rI(e,t){let r=rv.get(e);if(!r)throw new T("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rS(e){let t=rv.get(e);t&&(clearTimeout(t.timer),rv.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rA(e){let t=await rb(e);await U("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=o.join(e.tempDir,t);if(!i.existsSync(r))throw new T("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rb(e){let t=await U("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new T("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new T("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(r_),i=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new T("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new T("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new T("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===i||e.startsWith(`${i}/`)))throw new T("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,o=i;if(n!==o&&!n.startsWith(`${o}/`))throw new T("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await U("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new T("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function r_(e){if(e.includes("\0"))throw new T("INVALID_ARGS",`Invalid archive entry: ${e}`);if(o.posix.isAbsolute(e))throw new T("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=o.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new T("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rN=V(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function rk(e,t){return new Promise((r,a)=>{let n,o=i.createWriteStream(t),s=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},l=!1,u=0,d=e=>{if(!l){if(l=!0,n&&clearTimeout(n),e){o.destroy(),i.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new T("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rN});s(e),o.destroy(e),d(e)},rN)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((u+=t)>0x80000000){let e=new T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");s(e),o.destroy(e),d(e)}}),e.on("error",d),e.on("aborted",()=>{d(new T("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",d),o.on("finish",()=>d()),c(),e.pipe(o)})}async function rx(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new T("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new T("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=o.basename(t);if(!r||"."===r||".."===r)throw new T("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),s=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),i.mkdtempSync(o.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=o.join(s,n);return await rk(e,t),{artifactPath:t,tempDir:s}}let t=o.join(s,"artifact.tar");await rk(e,t);let a=await rA({archivePath:t,tempDir:s,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:s}}catch(e){throw i.rmSync(s,{recursive:!0,force:!0}),e}}let rD=new Set(["agent_device.command","agent-device.command"]),rM=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rP=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rL={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},rR=new Set([...rD,...rM,...rP,...Object.keys(rL)]);function rO(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rE(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rC(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function r$(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function rT(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rF(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function rU(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=$(new T("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rO(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=$(new T(E(r.code,"UNAUTHORIZED"),r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rO(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=S(r.tenantId);if(!e){let e=$(new T("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rO(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rG(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=o.isAbsolute(t)?t:o.resolve(t);try{e=await import(d(a).href)}catch(e){throw new T("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let i=e[r];if("function"!=typeof i)throw new T("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rV(e){let t=await rG(),{handleRequest:r,token:a}=e;return l.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void rj(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/artifacts/"))return void rq(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||rE(i,rO(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rE(i,rO(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rE(i,rO(a.id??null,-32600,"Invalid Request"),400);if(!rR.has(a.method))return void rE(i,rO(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rE(i,rO(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(rD.has(e))return{token:r$(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(rM.has(e)){let e,a=rT(t,"platform");if("ios"!==a&&"android"!==a)throw new T("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:r$(t,r),session:rT(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rT(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new T("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new T("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new T("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new T("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rF(t,"retentionMs")}}}if(rP.has(e)){let e=rT(t,"materializationId")?.trim();if(!e)throw new T("INVALID_ARGS","Invalid params: materializationId is required");return{token:r$(t,r),session:rT(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rT(t,"requestId"),materializationId:e}}}let a=rL[e];if(a)return{token:r$(t,r),session:rT(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rT(t,"tenantId")??rT(t,"tenant"),runId:rT(t,"runId"),leaseId:rT(t,"leaseId"),leaseTtlMs:rF(t,"ttlMs"),leaseBackend:rT(t,"backend")}};throw new T("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rD.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rE(i,rO(a.id??null,-32602,"Invalid params: command is required"),400);o=eC(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},ec(o);let u=()=>{i.writableFinished||eV(o)};e.on("aborted",u),i.on("close",u);let d=await rU(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!d.ok)return void rE(i,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 rE(i,{jsonrpc:"2.0",id:a.id??null,result:c});rE(i,rO(a.id??null,-32e3,c.error.message,c.error),rC(c.error.code))}catch(t){let e=$(t);rE(i,rO(a.id??null,-32e3,e.message,e),rC(e.code))}finally{eJ(o)}})})}async function rj(e,t,r,i){try{var n;let o,s,l=r$({},e.headers),u=rH(l,i);if(u){t.statusCode=rC(u.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.message,code:u.code}));return}let d=await rU(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 rx(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:d.tenantId},o=a.randomUUID(),(s=setTimeout(()=>{rS(o)},3e5)).unref(),rv.set(o,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:f}))}catch(r){let e=$(r);t.statusCode=rC(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rq(e,t,r,a){let n=e.url?.slice("/artifacts/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=r$({},e.headers),s=rH(o,a);if(s){t.statusCode=rC(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await rU(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:o,session:"default",command:"download_artifact",positionals:[n]}});if(!l.ok){t.statusCode=l.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.response.error?.data?.message??l.response.error?.message??"Unauthorized"}));return}let u=function(e,t){let r=rw.get(e);if(!r)throw new T("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw ry(e),new T("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),d=i.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=$(e);t.statusCode=rC(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&ry(n)}),d.pipe(t)}catch(r){let e=$(r);t.statusCode=rC(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rH(e,t){return t&&e!==t?$(new T("UNAUTHORIZED","Invalid token")):null}function rB(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rK(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rz(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";if("ios-instance"===t||"android-instance"===t)return t;throw new T("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rW{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=rz(e.backend),r=S(e.tenantId);if(!r)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rB(e.runId);if(!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,i,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),u={leaseId:a.randomBytes(16).toString("hex"),tenantId:r,runId:i,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(u.leaseId,u),this.runBindings.set(o,u.leaseId),{...u}}heartbeatLease(e){let t=rK(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=rK(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=rz(e.backend),r=S(e.tenantId);if(!r)throw new T("INVALID_ARGS","tenant isolation requires tenant id.");let a=rB(e.runId);if(!a)throw new T("INVALID_ARGS","tenant isolation requires run id.");let i=rK(e.leaseId);if(!i)throw new T("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new T("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new T("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=S(t),i=rB(r);if(t&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rJ=V(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rZ=new Map;async function rX(e){let t=await f.mkdtemp(o.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await r0(e.installablePath,o.join(t,"installable")),i=e.archivePath?await r0(e.archivePath,o.join(t,"archive")):void 0,n=a.randomUUID(),s=e.ttlMs??rJ,l=Date.now()+s,u=setTimeout(()=>{rY(n)},s);return rZ.set(n,{rootPath:t,installablePath:r,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:u}),{materializationId:n,installablePath:r,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await f.rm(t,{recursive:!0,force:!0}),e}}async function rY(e,t){let r=rZ.get(e);if(!r)throw new T("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rZ.delete(e),await f.rm(r.rootPath,{recursive:!0,force:!0})}async function rQ(e){let t=Array.from(rZ.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await rY(e)}))}async function r0(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=o.join(t,o.basename(e));return r.isDirectory()?await f.cp(e,a,{recursive:!0}):await f.copyFile(e,a),a}async function r1(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new T("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await ez(e.session.device),e.session.device}if(!r)throw new T("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await eh(e.flags??{});return await ez(a),a}async function r2(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,o,s=(n=function(e){let t=e.meta?.installSource;if(!t)throw new T("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new T("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new T("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:rI(o,t.meta?.tenantId)},cleanup:()=>{rS(o)}}:{source:n,cleanup:()=>{}}),l=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new T("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),u=await r1({session:i,flags:t.flags});if(!e2("install",u))return eH("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let d=e5(t.meta?.requestId);if("ios"===u.platform){let e,{installIosInstallablePath:n}=await import("./3918.js"),{prepareIosInstallArtifact:o}=await import("./3918.js"),c=await o(s.source,{signal:d});try{if(l.enabled&&(e=await rX({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs})),await n(u,c.installablePath),!c.bundleId)throw new T("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let o={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},s=te(o,r3(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await rY(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./3918.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./3918.js"),p=await c(s.source,{signal:d});try{l.enabled&&(e=await rX({archivePath:p.archivePath,installablePath:p.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs}));let n=await f(u,p.installablePath,p.packageName);if(!n)throw new T("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./3918.js"),s=o(n),d={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...s?{appName:s}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=te(d,r3(d));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await rY(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:$(e)}}}function r3(e){return`Installed: ${M(e)}`}async function r8(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new T("INVALID_ARGS","release_materialized_paths requires a materializationId");return await rY(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:$(e)}}}let r4=V(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r5=V(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r9(e,t,r){return t||r6(r)?null:eH("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function r6(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function r7(e){return"ios"===e.platform&&"simulator"===e.kind}async function ae(e,t){r7(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function at(e){let t=r6(e.flags)||!e.session?await eh(e.flags??{}):await ar(e.session.device);return!1!==e.ensureReady&&await ez(t),t}async function ar(e){if("ios"!==e.platform||"simulator"!==e.kind||"darwin"!==process.platform)return e;let t={platform:"ios",target:e.target,udid:e.id,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}};try{return await eh(t)}catch(e){if(!(e instanceof T)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await eh({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function aa(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let ai=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function an(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ao(e,t){if(void 0!==e){if("string"!=typeof e)throw new T("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return z(e)}}function as(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new T("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function al(e){if("ios"===e||"android"===e)return e}async function au(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!Z(r)||Z(a)||await J({device:i.device,appId:i.appBundleId})}async function ad(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(o))return eH("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){Z(l)&&s?.appBundleId&&await J({device:s.device,appId:s.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===o)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let u=al(e4(a.flags?.platform)??l?.platform??s?.device.platform);if(!u)return eH("INVALID_ARGS","runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first.");if(s&&s.device.platform!==u)return eH("INVALID_ARGS",`runtime set targets ${u}, but session "${i}" is already bound to ${s.device.platform}.`);let d={platform:(t=a.flags,r={platform:u,metroHost:z(t?.metroHost),metroPort:as(t?.metroPort),bundleUrl:z(t?.bundleUrl),launchUrl:z(t?.launchUrl)}).platform??l?.platform,metroHost:r.metroHost??l?.metroHost,metroPort:r.metroPort??l?.metroPort,bundleUrl:r.bundleUrl??l?.bundleUrl,launchUrl:r.launchUrl??l?.launchUrl};return 0===an(d)?eH("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(n.setRuntimeHints(i,d),{ok:!0,data:{session:i,configured:!0,runtime:d}})}let ac="open-command-roundtrip",af="Not implemented for this platform in this release.",ap=new Set(["app","desktop","frontmost-app"]);async function am(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eY();return{appBundleId:t.bundleId,appName:t.appName}}async function ah(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return e_(t)?"macos"===e.platform?void 0:"device"===e.kind?ej(r,t):void 0:await ag(e,t)}async function ag(e,t){try{let{resolveIosApp:r}=await import("./3918.js");return await r(e,t)}catch{return}}async function aw(e,t){if(!("android"!==e.platform||!t||e_(t)))try{let{resolveAndroidApp:r}=await import("./3918.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function ay(e,t,r,a){return await ah(e,t,r)??await a(e,t)??("android"===e.platform&&t&&e_(t)?r:void 0)}function av(e){return eH("INVALID_ARGS",e)}function aI(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:i}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return i??"app";if("linux"===t.platform){if(!r)return"app";let e=e8(r);if(!ap.has(e))throw new T("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new T("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new T("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?e8(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new T("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return eH(e instanceof T?e.code:"INVALID_ARGS",String(e.message))}}function aS(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&e_(r)?av("open --relaunch does not support URL targets."):"app"!==a?av("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===H(r)?av(Y(r)):null:null}async function aA(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await ez(i);let{appBundleId:l,appName:u}=await ab({device:i,surface:n,openTarget:o,existingAppBundleId:s?.appBundleId}),d=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new T("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ai.includes(e));if(i)throw new T("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ai.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new T("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new T("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:ao(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new T("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return as(e)}}(t.metroPort),bundleUrl:ao(t.bundleUrl,"bundleUrl"),launchUrl:ao(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:al(i.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let i=r?.platform,n=al(i);if(a.platform&&r&&!n)throw new T("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${i}.`);if(a.platform&&n&&a.platform!==n)throw new T("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${i}. Clear the runtime hints or use a different session.`);return n&&a.platform!==n?{...a,platform:n}:a}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&an(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=C(t);return eH(e.code,e.message,e.details)}}({req:t,sessionStore:a,sessionName:r,device:i});if(!d.ok)return{type:"response",response:d};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=d.data;await au({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:u,runtime:d.data.runtime}}}async function ab(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await am(r);return{appBundleId:n.appBundleId??await ay(t,a,i,aw),appName:n.appName??a}}let a_=new Map;async function aN(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await el(t.id),await er(t,"close",[r],a,i),await ae(t,r4)}async function ak(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let u=s[0]?.trim();!u||e_(u)||await er(r,"open",[l],a.flags?.out,{...eR(i,a.flags,n,o)})}async function ax(e){var t,r,a;let{req:i,sessionName:n,sessionStore:o,logPath:s,device:l,openTarget:u,openPositionals:d,appName:c,surface:f,appBundleId:p,runtime:m,existingSession:h}=e,g=i.flags?.relaunch===!0,w=h?.trace?.outPath;if(g&&u){let e=p??u;await aN({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eR(s,i.flags,p??h?.appBundleId,w)}})}await Q({device:l,appId:p,runtime:m});let y=Date.now();await er(l,"open",d,i.flags?.out,{...eR(s,i.flags,p)}),await ak({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:d});let v=u?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:ac,appTarget:u,appBundleId:p}:void 0;if(await ae(l,r5),eE(i.meta?.requestId)){let e=ed();return eH(e.code,e.message,e.details)}h&&e9(h,"open",h.snapshot);let I=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:n,device:l,surface:f,appBundleId:p,appName:c,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(t=o,r=n,(a=m)&&(0===an(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let S=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:o,runtime:s,runtimeHintCount:l}=e,u={session:t,surface:i};return r&&(u.appName=r),a&&(u.appBundleId=a),n&&(u.startup=n),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,...tr(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:v,device:l,runtime:m,runtimeHintCount:an});return o.recordAction(I,{command:"open",positionals:d,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:S}),o.set(n,I),{ok:!0,data:S}}async function aD(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return eH("SESSION_NOT_FOUND",`Session "${r}" not found.`);let n=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(n?e.appName:void 0),l=aI(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?av("open --relaunch requires an app name or an active session app."):av("Session already active. Close it first or pass a new --session name.");let u=aS({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(u)return u;let d=await ar(e.device),c=await aA({req:t,sessionName:r,sessionStore:i,device:d,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await ax({req:t,sessionName:r,sessionStore:i,logPath:a,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 n=t.flags?.relaunch===!0,o=t.positionals?.[0];if(n&&!o)return av("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&e_(r)?av("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===H(r)?av(Y(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await eh(t.flags??{}),u=aI(l,t.flags?.surface,o);if("string"!=typeof u)return u;let d=aS({shouldRelaunch:n,openTarget:o,surface:u,device:l});return d||await ey(a_,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return eH("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await aA({req:t,sessionName:r,sessionStore:i,device:l,surface:u,openTarget:o});return"response"===n.type?n.response:await ax({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:u})})}async function aM(e){let t=await U("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function aP(e){let{device:t,shutdownRequested:r}=e;if(r&&(r7(t)||"android"===t.platform&&"emulator"===t.kind))try{return r7(t)?await es(t):await aM(t)}catch(t){let e=$(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aL(e){if(await el(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eA("dismiss",t).catch(t=>{P({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aR(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");n.appLog&&await rm(n.appLog),t.positionals&&t.positionals.length>0&&(e3(n.device.platform)&&await aL(n),await er(n.device,"close",t.positionals,t.flags?.out,{...eR(a,t.flags,n.appBundleId,n.trace?.outPath)}),await ae(n.device,r4)),e3(n.device.platform)&&await aL(n),Z(i.getRuntimeHints(r))&&n.appBundleId&&await J({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...tr(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rQ(r).catch(()=>{}),i.delete(r);let o=await aP({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:te({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...tr(`Closed: ${r}`)}}}let aO=["platform","target","device","udid","serial","verbose","out"];function aE(e,t){let r=e??{};for(let e of aO)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aC={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./3918.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./3918.js");return await a(e,t,r)}},a$={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./3918.js"),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await import("./3918.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aT(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},u=r9(r,s,l);if(u)return u;let d=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!d||!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?rI(f,t.meta?.tenantId):tF.expandHome(c);if(!i.existsSync(a))return eH("INVALID_ARGS",`App binary not found: ${a}`);let u=await at({session:s,flags:l,ensureReady:!1});if(!e2(r,u))return eH("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===u.platform){let t=await o.ios(u,d,a),r=t.bundleId;e=r?{app:d,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:d,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(u,d,a),r=t.package;e=r?{app:d,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:d,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=te(e,(p=e,`Installed: ${p.appName??D(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&rS(f)}}async function aF(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return eH("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??eI;if(!Number.isInteger(i)||i<1||i>1e3)return eH("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=ea(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await aU(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=C(t);return eH(e.code,e.message,e.details)}}async function aU(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aE(e,n)}(e.flags,r.flags);void 0===o.session&&(o.session=t);let s=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:o,runtime:void 0===r.runtime?e.runtime:r.runtime,meta:e.meta}),l=Date.now()-n;return s.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:i,error:s.error}}async function aG(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:u}=e;if("darwin"!==process.platform)throw new T("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let d={simulatorSetPath:o??void 0};if(s){let e=await aV({deviceName:i,runtime:n,simctlOpts:d});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aj({deviceName:i,runtime:n,simctlOpts:d})).udid,r=await aq(t,d),a=!0)}else t=(await aj({deviceName:i,runtime:n,simctlOpts:d})).udid,r=await aq(t,d),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await u(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function aV(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await U("xcrun",q(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:eQ});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let[a,i]of Object.entries(e.devices??{}))if(!r||aH(a).includes(aH(r))){for(let e of i)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function aj(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await U("xcrun",q(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new T("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(n.stdout??"").trim();if(!o)throw new T("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aq(e,t){let r=await U("xcrun",q(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:eQ});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,a]of Object.entries(t.devices??{}))if(a.some(t=>t.udid===e))return r;return""}catch{return""}}function aH(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aB(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,i=j(e.iosSimulatorDeviceSet);if(!r)return eH("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await aG({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:ez});return{ok:!0,data:{udid:n.udid,device:n.device,runtime:n.runtime,ios_simulator_device_set:i??null,created:n.created,booted:n.booted}}}catch(t){let e=C(t);return eH(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=W(t.flags?.androidDeviceAllowlist),a=e4(t.flags?.platform),i=et({simulatorSetPath:j(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./3918.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./3918.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./3918.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./3918.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=C(t);return eH(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r9(t.command,e,i);if(n)return n;let o=await at({session:e,flags:i,ensureReady:!0});if(!e2("apps",o))return eH("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(e3(o.platform)){let{listIosApps:e}=await import("./3918.js");return{ok:!0,data:{apps:(await e(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await import("./3918.js");return{ok:!0,data:{apps:(await l(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function aK(e){let{ensureAndroidEmulatorBooted:t}=await import("./3918.js");return await t(e)}let az='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',aW='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function aJ(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=e4(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return eH("SESSION_NOT_FOUND","ios"===o?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`);let s=r9("appstate",i,n);if(s)return s;let l=e3(i?.device.platform)&&function(e,t){if(!t)return!1;if(!r6(e))return!0;let r=e4(e?.platform);return!(r&&!e1(t.device.platform,r)||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(n,i);if("ios"===o&&!l)return eH("SESSION_NOT_FOUND",az);if("macos"===o&&!l)return eH("SESSION_NOT_FOUND",aW);if(l&&i){let e=i.appName??i.appBundleId;if(!i.appName&&!i.appBundleId){if("macos"===i.device.platform&&i.surface&&"app"!==i.surface&&"frontmost-app"!==i.surface)return{ok:!0,data:{platform:i.device.platform,appName:i.surface,appBundleId:i.appBundleId,source:"session",surface:i.surface}};let e="macos"===i.device.platform?"macOS":"iOS";return eH("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:i.device.platform,appName:e??"unknown",appBundleId:i.appBundleId,source:"session",surface:i.surface??"app",..."ios"===i.device.platform?{device_udid:i.device.id,ios_simulator_device_set:i.device.simulatorSetPath??null}:{}}}}let u=await at({session:i,flags:n,ensureReady:!0});if("ios"===u.platform)return eH("SESSION_NOT_FOUND",az);if("macos"===u.platform)return eH("SESSION_NOT_FOUND",aW);let{getAndroidAppState:d}=await import("./3918.js"),c=await d(u);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function aZ(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r9(t.command,i,n);if(o)return o;let s="android"===(e4(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");let u=aa({flags:n,sessionDevice:i?.device}),d=s&&!!u,c=!1;try{e=await at({session:i,flags:n,ensureReady:!1})}catch(r){let t=C(r);if(s&&l&&!u&&"DEVICE_NOT_FOUND"===t.code)return eH("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 aK({avdName:u,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return eH("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=aa({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return eH("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aK({avdName:t,serial:n.serial,headless:!0})}await ez(e)}else("android"!==e.platform||!0!==e.booted)&&await ez(e);return e2("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:eH("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await aJ({req:t,sessionName:r,sessionStore:a}):null}function aX(e){return Math.round(10*e)/10}let aY="adb-shell-dumpsys-cpuinfo",aQ="adb-shell-dumpsys-meminfo";async function a0(e,t){try{let r=await U("adb",K(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,o;let e=r.trim();if(0===e.length)continue;let s=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!s)continue;let l=Number(s[1]),u=s[2];Number.isFinite(l)&&(n=u,o=t,n===o||n.startsWith(`${o}:`))&&(i+=l,a.add(u))}return{usagePercent:aX(i),measuredAt:r,method:aY,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw a2("cpu",t,e)}}async function a1(e,t){try{let r=await U("adb",K(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new T("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let a=a3(e,"TOTAL PSS")??function(e){for(let t of e.split("\n")){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let r=e.split(/\s+/).slice(1).find(e=>null!==a8(e));if(!r)break;return a8(r)??void 0}}(e);if(void 0===a)throw new T("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:a,totalRssKb:a3(e,"TOTAL RSS"),measuredAt:r,method:aQ}}(r.stdout,t,new Date().toISOString())}catch(e){throw a2("memory",t,e)}}function a2(e,t,r){return r instanceof T&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new T(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof T?r:new T("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a3(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a8(a[1])??void 0}function a8(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a4="ps-process-snapshot",a5="ps-process-snapshot",a9="xctrace-activity-monitor",a6="xctrace-activity-monitor";async function a7(e,t){if("ios"===e.platform&&"device"===e.kind)return await ir(e,t);let r=await it(e,t),a=await iu(e,r);if(0===a.length)throw new T("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let i=new Date().toISOString(),n=ty(a.map(e=>o.basename(id(e.command))));return ic({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:n,cpuMethod:a4,memoryMethod:a5})}async function ie(e){let t=eX(e),r=ip(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new T("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}),i=a.indexOf("pid"),n=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(i<0||n<0||o<0||s<0)throw new T("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let i of t)r(i)&&a.push(i),a.push(...e(i.children,r));return a}(t,e=>"row"===e.name),u=[],d=new Map;for(let e of l){var c,f;let t=e.children;if(0===t.length)continue;for(let e of t){let t=ip(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);d.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&d.set(e.attributes.id,{numberValue:im(e),processName:ig(e)})}let r=ih(t[i],d),a=(c=t[n],f=d,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:ig(c):null);null!==r&&Number.isFinite(r)&&a&&u.push({pid:r,processName:a,cpuTimeNs:ih(t[o],d),residentMemoryBytes:ih(t[s],d)})}return u}async function it(e,t){let r="macos"===e.platform?await is(t):await il(e,t),a="macos"===e.platform?o.join(r,"Contents","Info.plist"):o.join(r,"Info.plist"),i=await eW(a,"CFBundleExecutable");if(!i)throw new T("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?o.join(r,"Contents","MacOS",i):void 0}}async function ir(e,t){let r=await ia(e,t),a=await ii(e,t),i=await ii(e,t),n=io(await ie(a.xml),r,t,e),o=io(await ie(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new T("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new T("COMMAND_FAILED",`Incomplete Activity Monitor sample for ${t}`,{appBundleId:t,deviceId:e.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});return ic({usagePercent:Math.max(0,o.cpuTimeNs-n.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(i.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:a9,memoryMethod:a6})}async function ia(e,t){let r=(await e0(e,"all")).find(e=>e.bundleId===t);if(!r)throw new T("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new T("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=u(a),n=(await e7(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new T("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function ii(e,t){let r=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-ios-perf-")),a=o.join(r,"sample.trace"),i=o.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",a,"--quiet","--no-prompt"],o=await U("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==o.exitCode)throw new T("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:iw(o.stdout,o.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",i],u=await U("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==u.exitCode)throw new T("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:l,exitCode:u.exitCode,stdout:u.stdout,stderr:u.stderr,appBundleId:t,deviceId:e.id,hint:iw(u.stdout,u.stderr)});return{capturedAtMs:s,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function io(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>o.basename(u(e.executable)))),s=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===s.length)throw new T("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:a.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let l=new Map;for(let e of s){let t=l.get(e.pid);if(!t){l.set(e.pid,e);continue}l.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:iy(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iy(t.residentMemoryBytes,e.residentMemoryBytes)})}let d=[...l.values()],c=d.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=d.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:c.length>0?c.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:ty(d.map(e=>e.processName))}}async function is(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await U("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new T("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!a)throw new T("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function il(e,t){let r=X(e,["get_app_container",e.id,t,"app"]),a=await U("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new T("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let i=a.stdout.trim();if(0===i.length)throw new T("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function iu(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:X(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let a=e.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!a)continue;let i=Number(a[1]),n=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(o)&&t.push({pid:i,cpuPercent:n,rssKb:o,command:s})}return t})((await U("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=id(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||o.basename(i)===a.executableName})}function id(e){let[t=""]=e.trim().split(/\s+/,1);return t}function ic(e){return{cpu:{usagePercent:aX(e.usagePercent),measuredAt:e.measuredAt,method:e.cpuMethod,matchedProcesses:e.matchedProcesses},memory:{residentMemoryKb:Math.round(e.residentMemoryKb),measuredAt:e.measuredAt,method:e.memoryMethod,matchedProcesses:e.matchedProcesses}}}function ip(e,t){for(let r of e){if(t(r))return r;let e=ip(r.children,t);if(e)return e}}function im(e){if(!e||e.children.some(e=>"sentinel"===e.name)||!e.text)return null;let t=Number(e.text);return Number.isFinite(t)?t:null}function ih(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:im(e):null}function ig(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function iw(e,t){let r=ep(e,t);if(r)return r;let a=`${e}
|
|
6
|
+
${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?eM:a.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function iy(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function iv(e){var t;let r=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===ac&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:ac,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}(e.actions),a=r.at(-1),i=a?{available:!0,lastDurationMs:a.durationMs,lastMeasuredAt:a.measuredAt,method:ac,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:ac},n={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:i,fps:{available:!1,reason:af},memory:{available:!1,reason:af},cpu:{available:!1,reason:af}},sampling:{startup:{method:ac,description:"Elapsed wall-clock time around dispatching the open command for the active session app target.",unit:"ms"},...function(e){if("android"===e.device.platform)return{memory:{method:aQ,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:aY,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"}};var t=e.device;if("ios"===t.platform&&"device"===t.kind)return{memory:{method:a6,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:a9,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let r="macos"===t.platform?"host ps for the running macOS app executable resolved from the bundle ID.":"xcrun simctl spawn ps for the running iOS simulator app executable resolved from the bundle ID.";return{memory:{method:a5,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:a4,description:`Recent CPU usage snapshot from ${r}`,unit:"percent"}}}(e)}};if("android"!==(t=e).device.platform&&"ios"!==t.device.platform&&"macos"!==t.device.platform)return n;if(!e.appBundleId){let t="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.";return n.metrics.memory={available:!1,reason:t},n.metrics.cpu={available:!1,reason:t},n}let[o,s]=await iI(e);return n.metrics.memory=iS(o),n.metrics.cpu=iS(s),n}async function iI(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([a1(e.device,t),a0(e.device,t)]);return[r,a]}try{let r=await a7(e.device,t);return[{status:"fulfilled",value:r.memory},{status:"fulfilled",value:r.cpu}]}catch(e){return[{status:"rejected",reason:e},{status:"rejected",reason:e}]}}function iS(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=$(e.reason);return{available:!1,reason:t.message,error:t}}let iA=["path","start","stop","doctor","mark","clear"],ib=`logs requires ${iA.slice(0,-1).join(", ")}, or ${iA.at(-1)}`,i_=["dump","log"],iN=`network requires ${i_.join(" or ")}`,ik=["summary","headers","body","all"],ix=`network include mode must be one of: ${ik.join(", ")}`;async function iD(e){let{req:t}=e;return"perf"===t.command?iM(e):"logs"===t.command?iP(e):"network"===t.command?iC(e):null}async function iM(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return eH("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await iv(a)}}catch(e){return{ok:!1,error:$(e)}}}async function iP(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return eH("SESSION_NOT_FOUND","logs requires an active session");if(!e2("logs",n.device))return eH("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return iA.includes(o)?s&&"clear"!==o?eH("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===o?function(e,t,r){let a=r.resolveAppLogPath(t),n=function(e){if(!i.existsSync(e))return{exists:!1,sizeBytes:0};let t=i.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(a);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:n.sizeBytes,modifiedAt:n.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(n,r,a):"doctor"===o?iL(n,r,a):"mark"===o?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return ru(o),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
|
|
7
|
+
`,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?iR(n,r,a,s):"start"===o?iO(n,r,a):"stop"===o?iE(n,r,a):eH("INVALID_ARGS",ib):eH("INVALID_ARGS",ib)}async function iL(e,t,r){let a=r.resolveAppLogPath(t),i=await rh(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:i.checks,notes:i.notes}}}async function iR(e,t,r,a){if(e.appLog&&!a)return eH("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return eH("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:rg(i)};e.appLog&&await rm(e.appLog);let n=rg(i),o=r.resolveAppLogPidPath(t);try{let a=await rf(e.device,e.appBundleId,i,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:i,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...n,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:$(a)}}}async function iO(e,t,r){if(e.appLog)return eH("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return eH("INVALID_ARGS","logs start requires an app session; run open <app> first");let a=r.resolveAppLogPath(t),i=r.resolveAppLogPidPath(t);try{let n=await rf(e.device,e.appBundleId,a,i);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:$(e)}}}async function iE(e,t,r){if(!e.appLog)return eH("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rm(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iC(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","network requires an active session");if(!e2("network",i.device))return eH("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!i_.includes(n))return eH("INVALID_ARGS",iN);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return eH("INVALID_ARGS","network dump limit must be an integer in range 1..200");let s=function(e){let t=e.positionals?.[2]?.toLowerCase(),r=e.flags?.networkInclude;if(t&&r&&t!==r)return eH("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return ik.includes(a)?{ok:!0,include:a}:eH("INVALID_ARGS",ix)}(t);if(!s.ok)return s;let{include:l}=s,u=await rd({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...u.dump,active:!!i.appLog,state:i.appLog?.getState()??"inactive",backend:u.backend,notes:u.notes}}}let i$=/^[A-Z_][A-Z0-9_]*$/,iT=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-((?:[^}\\]|\\.)*))?\}/g,iF="AD_VAR_";function iU(e){return e.startsWith("AD_")}function iG(e){return new T("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function iV(e,t,r){return e.replace(iT,(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 T("INVALID_ARGS",`Unresolved variable \${${i}} at ${r.file}:${r.line}.`)})}function ij(e,t,r){if(!e)return e;let a={...e};for(let[e,i]of Object.entries(a))"string"==typeof i&&(a[e]=iV(i,t,r));return a}let iq=new Set(["ios","android","macos","linux"]);function iH(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(iB(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 T("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let i=r.slice(0,a);if(!i$.test(i))throw new T("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 T("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 T("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 T("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&&iq.has(e)&&iK(r,"platform",e)}let n=a.match(/(?:^|\s)timeout=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=1&&iK(r,"timeoutMs",Math.floor(e))}let o=a.match(/(?:^|\s)retries=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=0&&iK(r,"retries",Math.floor(e))}}return r}function iB(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function iK(e,t,r){let a=e[t];if(void 0!==a)throw new T("INVALID_ARGS",a===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(a)} vs ${String(r)}.`);e[t]=r}function iz(e){return!!e&&!Number.isNaN(Number(e))}let iW=/[*?[\]{}]/;async function iJ(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,artifactsDir:s,runReplay:l,cleanupSession:u}=e;ec(i);let d=new Set,c=!1,f=l({filePath:r,sessionName:a,platform:o,requestId:i,artifactsDir:s,artifactPaths:d}).catch(e=>{let t=C(e);return eH(t.code,t.message)}).finally(()=>{eJ(i)});try{return"number"==typeof n?await Promise.race([f,new Promise(e=>{t=setTimeout(()=>{c=!0,eV(i),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(n,[...d]))},n)})]):await f}finally{t&&clearTimeout(t),c&&(await iZ(f)||P({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await u(a)}catch(e){P({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:C(e).message}})}}}async function iZ(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function iX(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return eH("INVALID_ARGS","test requires at least one path or glob");try{var s,l,u,d,c,f;let e,p,m,h,g,w=function(e){let{inputs:t,cwd:r,platformFilter:a}=e,n=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tF.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>o.join(n,e));if(t.isFile()){if(".ad"!==o.extname(n))throw new T("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!iW.test(r)&&(a=n,!iW.test(a)))throw new T("INVALID_ARGS",`test input not found: ${e}`);let s=o.isAbsolute(n)?n:e;return i.globSync(s,{cwd:o.isAbsolute(n)?void 0:t}).map(e=>o.isAbsolute(e)?e:o.resolve(t,e)).filter(e=>".ad"===o.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>o.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var u,d;let t=iH(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}u=a,d=t.platform,("apple"===u?"apple"===d||"ios"===d||"macos"===d:d===u)&&l.push({kind:"run",path:e,metadata:t})}if(0===l.filter(e=>"run"===e.kind).length){let e=a?` for --platform ${a}`:"";throw new T("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tF.expandHome(t??".agent-device/test-artifacts",r);return o.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),I=[],S=Date.now(),A=0;for(let e of w){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await iY({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,u=e.metadata.timeoutMs,"number"==typeof l?l:u),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(I.push(i),t.flags?.failFast===!0)break}let b=(d=w.length,c=I,f=Date.now()-S,e=c.filter(e=>"passed"===e.status).length,m=(p=c.filter(e=>"failed"===e.status)).length,h=c.filter(e=>"skipped"===e.status).length,g=e+m,{total:d,executed:g,passed:e,failed:m,skipped:h,notRun:Math.max(0,d-g-h),durationMs:f,failures:p,tests:c});return{ok:!0,data:b}}catch(t){let e=C(t);return eH(e.code,e.message)}}async function iY(e){var t,r;let a,n,{entry:s,sessionName:l,suiteInvocationId:u,caseIndex:d,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,y=Date.now(),v=o.join(h,(t=s.path,(0===(n=c?o.relative(c,t):o.basename(t)).length||n.startsWith("..")?o.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",S=0;for(let e=0;e<=p;e+=1){S=e+1;let t=function(e,t,r,a,i=0){let n=o.basename(r,o.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,u,s.path,d,e),n=o.join(v,`attempt-${S}`);r=s.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,o.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eC(`${t??r}:test:${i+1}:${o.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:u,filePath:s.path,caseIndex:d,attemptIndex:e}),h=await iJ({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,artifactsDir:n,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:s,attemptArtifactsDir:l}=e,u=[...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||u.push(t.error.logPath);let d=function(e,t){let r=[],a=new Map;for(let n of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=o.extname(e),a=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${a}-${i+1}${r}`}(o.basename(n),a),s=o.join(t,e);o.resolve(n)!==o.resolve(s)&&i.copyFileSync(n,s),r.push(s)}return r}(u,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${s}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");d.length>0&&c.push(`copiedArtifacts: ${d.map(e=>o.basename(e)).join(", ")}`);let f=o.join(l,"result.txt"),p=`${c.join("\n")}
|
|
8
|
+
`;i.writeFileSync(f,p),t.ok||i.writeFileSync(o.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:S,maxAttempts:p+1,attemptArtifactsDir:n}),a=h,I=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:s.path,session:I,status:"passed",durationMs:A,attempts:S,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let b=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:I,status:"failed",durationMs:A,attempts:S,artifactsDir:v,error:b}}function iQ(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=ta(r?e.slice(0,-1):e.slice());return!a||a.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:a.selectorExpression,selectorTimeout:r?t:null}}async function i0(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(t_(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let n=i.get(r);if(!n)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),t_(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=to(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=iQ(e.positionals??[]);r&&t.push(r)}return ty(t).filter(e=>e.trim().length>0)})(t).map(e=>ts(e)).filter(e=>null!==e);if(0===o.length)return null;let s=t_(t.command)||"fill"===t.command,l=t_(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await i1(n,t,a,s,i);for(let e of o){let r=tl(u.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=td(r.node,n.device.platform,{action:t_(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(t_(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=tw(t);if(!e)continue;return{...t,positionals:[a,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,a]}}if("is"===t.command){let{predicate:e,split:r}=to(t.positionals);if(!e)continue;let i=r?.rest.join(" ").trim()??"",n=[e,a];return"text"===e&&i.length>0&&n.push(i),{...t,positionals:n}}if("wait"===t.command){let{selectorTimeout:e}=iQ(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function i1(e,t,r,a,i){let n=await er(e.device,"snapshot",[],t.flags?.out,{...eR(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:tp(t.flags?.snapshotRaw?o:tf(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return e.snapshot=s,i.set(e.name,e),s}async function i2(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:s}=e,l=t.positionals?.[0];if(!l)return eH("INVALID_ARGS","replay requires a path");let u="",d=new Set;try{var c;let e;u=tF.expandHome(l,t.meta?.cwd);let f=i.readFileSync(u,"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=iH(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],o=n.trim();if(0===o.length||o.startsWith("#"))continue;if(iB(o)){if(i)throw new T("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;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let a=r+1,i=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!i)break;i="\\"===t&&!i,"\\"!==t&&(i=!1),a+=1}if(a>=e.length)throw new T("INVALID_ARGS",`Invalid replay script line: ${e}`);let n=e.slice(r,a+1);t.push(JSON.parse(n)),r=a+1;continue}let a=r;for(;a<e.length&&!/\s/.test(e[a]);)a+=1;t.push(e.slice(r,a)),r=a}return t}(t);if(0===r.length)return null;let[a,...i]=r;if("context"===a)return null;let n={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){n.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){n.flags.snapshotCompact=!0;continue}if("--raw"===t){n.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(n.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){n.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}return n}if("open"===a){let e=function(e){var t;let r=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}r.push(t)}let i=tC(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=tC(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(t_(a)){let e=tE(a,i);if(Object.assign(n.flags,e.flags),0===e.positionals.length)return n;let t=e.positionals[0];if(t.startsWith("@"))return n.positionals=[t],e.positionals[1]&&(n.result={refLabel:e.positionals[1]}),n;let r=e.positionals[0],o=e.positionals[1];return iz(r)&&iz(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tE(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=tE(a,i);return Object.assign(n.flags,e.flags),n.positionals=e.positionals,n}if("record"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--hide-touches"===r){n.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return n.positionals=e,n}if("screenshot"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--fullscreen"===r){n.flags.screenshotFullscreen=!0;continue}if("--max-size"===r){let e=i[t+1],r=void 0===e?NaN:Number(e);if(!Number.isInteger(r)||r<1)throw new T("INVALID_ARGS","screenshot --max-size requires a positive integer");n.flags.screenshotMaxSize=r,t+=1;continue}e.push(r)}return n.positionals=e,n}return n.positionals=i,n}(n);s&&(t.push(s),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(iU(e))throw iG(e);t[e]=a}return{values:t}}({builtins:function(e){let{req:t,sessionName:r,metadata:a,resolvedPath:i}=e,n=t.flags??{},s=t.meta?.cwd??process.cwd(),l={AD_SESSION:r,AD_FILENAME:o.relative(s,i)||i},u=n.platform??a.platform;u&&(l.AD_PLATFORM=u);let d=n.device;"string"==typeof d&&d.length>0&&(l.AD_DEVICE=d);let c=n.artifactsDir;return"string"==typeof c&&c.length>0&&(l.AD_ARTIFACTS=c),l}({req:t,sessionName:r,metadata:m,resolvedPath:u}),fileEnv:m.env,shellEnv:function(e){let t={};for(let[r,a]of Object.entries(e)){if("string"!=typeof a||!r.startsWith(iF))continue;let e=r.slice(iF.length);0!==e.length&&i$.test(e)&&(iU(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 T("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let a=r.slice(0,e);if(!i$.test(a))throw new T("INVALID_ARGS",`Invalid -e key "${a}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(iU(a))throw iG(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,I=0;for(let e=0;e<g.length;e+=1){let i=g[e];if(!i||"replay"===i.command)continue;let o=await i3({req:t,sessionName:r,action:i,scope:y,filePath:u,line:w[e]??0,invoke:s});if(o.ok){i4(o).forEach(e=>d.add(e));continue}if(!v)return i8(o,i,e,u,[...d]);let l=await i0({action:i,sessionName:r,logPath:a,sessionStore:n});if(!l)return i8(o,i,e,u,[...d]);if(g[e]=l,!(o=await i3({req:t,sessionName:r,action:l,scope:y,filePath:u,line:w[e]??0,invoke:s})).ok)return i8(o,l,e,u,[...d]);i4(o).forEach(e=>d.add(e)),I+=1}return v&&I>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${tx(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tk(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tT(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tD(r,tP));return tR(t,e.flags),t.join(" ")}if("record"===e.command)return tO(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tk(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),"number"==typeof e.flags?.screenshotMaxSize&&t.push("--max-size",String(e.flags.screenshotMaxSize)),t.join(" ")}for(let r of e.positionals??[])t.push(tk(r));return tL(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
|
|
9
|
+
`,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(u,g,n.get(r)),{ok:!0,data:{replayed:g.length,healed:I,session:r,artifactPaths:[...d]}}}catch(t){let e=C(t);return eH(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function i3(e){var t,r;let{req:a,sessionName:i,action:n,scope:o,filePath:s,line:l,invoke:u}=e,d=(t={file:s,line:l},{...n,positionals:(n.positionals??[]).map(e=>iV(e,o,t)),flags:ij(n.flags,o,t)??{},runtime:ij(n.runtime,o,t)});return await u({token:a.token,session:i,command:d.command,positionals:d.positionals??[],flags:(r=a.flags,aE(r,{...d.flags??{}})),runtime:d.runtime,meta:a.meta})}function i8(e,t,r,a,i=[]){let n;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${n=(t.positionals??[]).map(e=>tk(e)),[t.command,...n].join(" ")}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:a,step:o,action:t.command,positionals:t.positionals??[],artifactPaths:i}}}}function i4(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 i5(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await i2({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await iX({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactsDir:l,artifactPaths:u})=>{let d=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:o,artifactsDir:l});return await i2({req:{...t,command:"replay",session:r,positionals:[e],flags:d,meta:s?{...t.meta??{},requestId:s}:t.meta},sessionName:r,logPath:a,sessionStore:i,invoke:async e=>{var t;return t=await n(e),u&&i4(t).forEach(e=>u.add(e)),t}})},cleanupSession:async e=>{i.get(e)&&await aR({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let i9=new Set(["session_list","ensure-simulator","devices","apps"]),i6=new Set(["boot","appstate"]),i7=new Set(["perf","logs","network"]),ne=new Set(["replay","test"]);async function nt(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:o,recordPositionals:s,deriveNextSession:l}=e,u=i.get(r),d=t.flags??{},c=r9(n,u,d);if(c)return c;let f=await at({session:u,flags:d,ensureReady:!0});if(!e2(n,f))return eH("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await er(f,n,o,t.flags?.out,{...eR(a,t.flags,u?.appBundleId,u?.trace?.outPath)});if(u){let e=l?await l(u,p,f):u;i.recordAction(e,{command:n,positionals:s??o,flags:t.flags??{},result:p??{}}),e!==u&&i.set(r,e)}return{ok:!0,data:p??{}}}async function nr(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r9("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return eH("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await at({session:n,flags:o,ensureReady:!0});if(!e2("clipboard",u))return eH("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let d=await er(u,"clipboard",t.positionals??[],t.flags?.out,{...eR(a,t.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:d??{}}),{ok:!0,data:{platform:u.platform,...d??{}}}}async function na(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(i9.has(t.command))return await aB({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await ad({req:t,sessionName:r,sessionStore:i});if(i6.has(t.command))return await aZ({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await nr({req:t,sessionName:r,logPath:a,sessionStore:i});if("keyboard"===t.command){let e=i.get(r),n=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==n||"ios"!==e4((t.flags??{}).platform)?await nt({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(i7.has(t.command))return await iD({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aT({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?a$:aC});if("install_source"===t.command)return await r2({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r8({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await nt({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=e$(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tF.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):eH("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await nt({req:t,sessionName:r,logPath:a,sessionStore:i,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await ay(e.device,r,e.appBundleId,aw)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aD({req:t,sessionName:r,logPath:a,sessionStore:i}):ne.has(t.command)?await i5({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await aF(t,r,n):"close"===t.command?await aR({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function ni(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return eH("INVALID_ARGS","find requires a locator or text");let{locator:l,query:u,action:d,value:c,timeoutMs:f}=tg(s);if(!u)return eH("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return eH("INVALID_ARGS","find accepts only one of --first or --last");let p=await eK({req:t,sessionName:r,logPath:a,sessionStore:i});if(p)return p;let m=i.get(r);if(!m&&"exists"!==d&&"wait"!==d&&"get_text"!==d&&"get_attrs"!==d)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await eh(t.flags??{});m||await ez(h);let g="role"!==l?u:void 0,w="click"===d||"focus"===d||"fill"===d||"type"===d,y=0,v=null,I=async()=>{let e=Date.now();if(v&&e-y<750&&!eZ(m))return{nodes:v};let{snapshot:n}=await ek({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return y=e,v=o,m&&(m.snapshot=n,i.set(r,m)),{nodes:o,truncated:n.truncated,backend:n.backend}},S={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:o,locator:l,query:u};if("wait"===d)return nn(S,I,l,u,f);let{nodes:A}=await I(),b=th(A,l,u,{requireRect:w});if(w&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,k;let e;return _=b.matches,N=l,k=u,e=_.slice(0,8).map(e=>{let t=tn(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eH("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${k}". Use a more specific locator or selector.`,{locator:N,query:k,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let x=b.matches[0]??null;if(!x)return eH("COMMAND_FAILED","find did not match any element");let D="click"===d||"focus"===d||"fill"===d||"type"===d?ti(A,x)??x:x,M=`@${D.ref}`,P={node:x,resolvedNode:D,ref:M,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>no(S),get_text:()=>ns(S,P),get_attrs:()=>nl(S,P),click:()=>nu(S,P),fill:()=>nd(S,P,c),focus:()=>nc(S,P),type:()=>nf(S,P,c)}[d];return L?L():null}async function nn(e,t,r,a,i){let{req:n,sessionStore:o,session:s,command:l}=e,u=i??1e4,d=Date.now();for(;Date.now()-d<u;){let{nodes:e}=await t();if(th(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:n.positionals??[],flags:n.flags??{},result:{found:!0,waitedMs:Date.now()-d}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-d}};await G(300)}return eH("COMMAND_FAILED","find wait timed out")}async function no(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 ns(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await eN({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eR(s,e,t,r)});return i&&a.recordAction(i,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get text",text:l}}),{ok:!0,data:{ref:t.ref,text:l,node:t.node}}}async function nl(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 nu(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,invoke:o,command:s,locator:l,query:u}=e,d=await o({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let c=t.resolvedNode.rect?tm(t.resolvedNode.rect):null,f={ref:t.ref,locator:l,query:u};return c&&(f.x=c.x,f.y=c.y),n&&i.recordAction(n,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:u}}),{ok:!0,data:f}}async function nd(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return eH("INVALID_ARGS","find fill requires text");let u=await s({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return u.ok&&o&&n.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),u}async function nc(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?tm(t.node.rect):null;if(!l)return eH("COMMAND_FAILED","matched element has no bounds");let u=await er(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eR(s,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:u??{ref:t.ref}}}async function nf(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return eH("INVALID_ARGS","find type requires text");let u=t.node.rect?tm(t.node.rect):null;if(!u)return eH("COMMAND_FAILED","matched element has no bounds");await er(o,"focus",[String(u.x),String(u.y)],a.flags?.out,{...eR(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let d=await er(o,"type",[r],a.flags?.out,{...eR(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:d??{ref:t.ref}}}let np=`
|
|
10
10
|
import Foundation
|
|
11
11
|
import AVFoundation
|
|
12
12
|
|
|
@@ -30,11 +30,11 @@ Task {
|
|
|
30
30
|
|
|
31
31
|
semaphore.wait()
|
|
32
32
|
exit(exitCode)
|
|
33
|
-
`.trim();async function
|
|
34
|
-
${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return nl(e);return!1}catch(t){if(t instanceof T&&"TOOL_MISSING"===t.code)return nl(e);throw t}}async function ns(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await no(e))return;await G(r)}}function nl(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(a.push(o),1===n){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nd(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nu(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nc(e){let t=o.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new T("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure ios-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}async function nf(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await nn(t),await ns(t);let s=i.mkdtempSync(o.join(c.tmpdir(),"agent-device-record-overlay-")),l=o.join(s,`input${o.extname(t)||".mp4"}`),d=o.join(s,o.basename(t)),u=o.join(s,"home"),f=o.join(s,"module-cache");i.copyFileSync(t,l),i.mkdirSync(u,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await F("xcrun",["swift",r,"--input",l,"--output",d,...a],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await ns(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof T?a:new T("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new T("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function np(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nf({videoPath:r,scriptPath:t??=nc("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function nm(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nf({videoPath:r,scriptPath:e??=nc("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function nh(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await nf({videoPath:t,scriptPath:r??=nc("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function ng(e){return e instanceof Error?e.message:String(e)}function nw(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function ny(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:n}=e,o=function(e){var t,r,a;let n,o,{recording:s,trimStartMs:l}=e,d=(n=nd((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?nu(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):nu(r))},i.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:a});if(t.showTouches){let e=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(e)t.overlayWarning??=e;else try{await r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,targetLabel:n})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${ng(e)}`}}}async function nv(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","ps","-o","pid=","-p",r],{allowFailure:!0});return 0===a.exitCode&&a.stdout.split(/\s+/).map(e=>e.trim()).includes(r)}async function nS(e,t,r){for(let a=0;a<40;a+=1){if(!await nv(e,t,r))return!0;await G(250)}return!await nv(e,t,r)}async function nI(e,t,r){let a,i=0;for(let n=0;n<20;n+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?n.stdout.trim():"";if(o.length>0&&o===a){if((i+=1)>=4)return}else i=0;a=o,await G(250)}}async function nA(e,t,r,a){for(let i=0;i<8;i+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?Number(n.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await nv(e,t,a))break;if(i+1>=2)return!0;await G(250)}return!1}async function nb(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{i.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",a,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=nw(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(P({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return i.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;P({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1}})}e<1&&await G(750)}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function n_(e){let{deps:t,deviceId:r,quality:a}=e;if(void 0===a||a>=10)return;let i=await t.runCmd("adb",["-s",r,"shell","wm","size"],{allowFailure:!0}),n=i.stdout.match(/Override size:\s*(\d+)x(\d+)/)??i.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==i.exitCode||!n)throw Error(`failed to resolve Android screen size for recording quality: ${nw(i,"adb shell wm size")}`);return{width:nN(Number(n[1]),a),height:nN(Number(n[2]),a)}}function nN(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nk(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function nx(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return P({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:t,remotePid:r,exitCode:a.exitCode,stdout:a.stdout.trim(),stderr:a.stderr.trim()}}),!(0!==a.exitCode&&await nv(e,t,r))&&await nS(e,t,r)}async function nM(e){var t;let r,a,{deps:i,device:n,recordingBase:o}=e,s="failed to start recording: Android screenrecord did not begin producing frames";try{r=await n_({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return eH("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),a=`agent-device-recording-${t}.mp4`,[`/sdcard/${a}`,`/data/local/tmp/${a}`])){let t=await i.runCmd("adb",["-s",n.id,"shell",function(e,t){let r=["screenrecord"];return t&&r.push("--size",`${t.width}x${t.height}`),r.push(e),`${r.join(" ")} >/dev/null 2>&1 & echo $!`}(e,r)],{allowFailure:!0});if(0!==t.exitCode){s=`failed to start recording: ${nw(t,"adb shell screenrecord")}`;continue}let a=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!a){s="failed to start recording: adb did not return a valid Android screenrecord pid",await nk(i,n.id,e);continue}if(P({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nA(i,n.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...o,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await nx(i,n.id,a),await nk(i,n.id,e)}return eH("COMMAND_FAILED",s)}async function nD(e){let t,r,{deps:a,device:i,recording:n}=e;P({level:"debug",phase:"record_stop_android_enter",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid}});let o=await a.runCmd("adb",["-s",i.id,"shell","kill","-2",n.remotePid],{allowFailure:!0});if(P({level:"debug",phase:"record_stop_android_signal",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await nv(a,i.id,n.remotePid)&&!await nx(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nw(o,"adb shell kill")}`):await nS(a,i.id,n.remotePid)||await nx(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nI(a,i.id,n.remotePath);let e=await nb({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),eH("COMMAND_FAILED",e);await ny({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return eH("COMMAND_FAILED",t);if(r)return eH("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});P({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:i.id,remotePath:n.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${nw(e,"adb shell rm")}`)}}function nP(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nL(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nR(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nP(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nL(t,i,r))}catch(e){P({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:ng(e)}})}}async function nO(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=nL(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,fps:d,quality:u.quality,appBundleId:c},m);try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(a){var g,w;if(!ng(a).toLowerCase().includes("recording already in progress"))return eH("COMMAND_FAILED",`failed to start recording: ${ng(a)}`);P({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:ng(a)}});let e=(g=o.id,w=i.name,n.toArray().find(e=>e.name!==w&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return eH("COMMAND_FAILED",`failed to start recording: recording already in progress in session '${e.name}'`);try{await l.runIosRunnerCommand(o,{command:"recordStop",appBundleId:c},m)}catch{}try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${ng(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function nC(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await n.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,quality:s.quality,appBundleId:l},nL(t,i,r))}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${ng(e)}`)}return{platform:"macos-runner",...s}}async function nE(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nP(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nL(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:ng(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of ee)if(0===(l=await n.runCmd("xcrun",["devicectl","device","copy","from","--device",a.id,"--source",o.remotePath,"--destination",o.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==l.exitCode){let e=l.stderr.trim()||l.stdout.trim()||`devicectl exited with code ${l.exitCode}`;return eH("COMMAND_FAILED",`failed to copy recording from device: ${e}`)}let d="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);return d>0&&await n.trimRecordingStart({videoPath:o.outPath,trimStartMs:d}),await ny({recording:o,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function n$(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nP(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nL(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:ng(e)}})}return await ny({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nT(e){for(let t=0;t<2;t+=1){try{if(i.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await G(250)}return Date.now()}async function nU(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await nR({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",X(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await nT(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nP(i)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:i.trace?.outPath}),d=Date.now();t=Math.round((e+d)/2),r="number"==typeof l.currentUptimeMs?l.currentUptimeMs:void 0}catch{}return{platform:"ios",child:u,wait:c,...l,startedAt:f,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function nF(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return eH("INVALID_ARGS","recording already in progress");let c=r.flags?.fps,f=r.flags?.quality;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return eH("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return eH("INVALID_ARGS","quality must be an integer between 5 and 10");if(!e2("record",l))return eH("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tU.expandHome(p,r.meta?.cwd),h={outPath:m,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),quality:r.flags?.quality,showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(i.mkdirSync(o.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nP(s);if(!e)return eH("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nO({req:r,activeSession:s,sessionStore:n,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nP(s);if(!e)return eH("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nC({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await nU({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:h,resolvedOut:m}):await nM({deps:u,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,n.set(a,s),n.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??p,showTouches:t.showTouches}})}async function nG(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nD({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;if(0!==i.exitCode)return eH("COMMAND_FAILED",`failed to stop recording: ${nw(i,"simctl recordVideo")}`);if(void 0!==a.quality&&a.quality<10)try{await t.resizeRecording({videoPath:a.outPath,quality:a.quality,targetLabel:"iOS recording"})}catch(e){a.overlayWarning=`failed to resize recording: ${ng(e)}`}return await ny({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nV(e){var t;let r,{req:a,activeSession:i,device:n,logPath:s,deps:l}=e;if(!i.recording)return eH("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await nE({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await n$({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):await nG({deps:l,device:n,recording:d});return c||(u?eH("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nd(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nj(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:F,runCmdBackground:U,runIosRunnerCommand:eB,waitForStableFile:nn,isPlayableVideo:no,trimRecordingStart:np,resizeRecording:nh,overlayRecordingTouches:nm},o=a.get(r),s=o?.device??await eh(t.flags??{});o||await ez(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return eH("INVALID_ARGS","record requires start|stop");if("start"===d)return nF({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await nV({req:t,activeSession:l,device:s,logPath:i,deps:n});return u.ok&&a.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:u.data?.outPath,showTouches:u.data?.showTouches}}),u}async function nq(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,s=t.command;if("record"===s)return nj({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return eH("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return eH("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=tU.expandHome(e);return i.mkdirSync(o.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return eH("INVALID_ARGS","no active trace");let l=n.trace.outPath;if(t.positionals?.[1]){let e=tU.expandHome(t.positionals[1]);i.mkdirSync(o.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nH(e){return"number"==typeof e.gestureClockOriginAtMs&&"number"==typeof e.gestureClockOriginUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureClockOriginAtMs+(e.gestureStartUptimeMs-e.gestureClockOriginUptimeMs)-e.recordingStartedAt):"number"==typeof e.runnerStartedAtUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureStartUptimeMs-e.runnerStartedAtUptimeMs):"number"==typeof e.gestureStartUptimeMs&&"number"==typeof e.gestureEndUptimeMs?Math.max(0,e.fallbackFinishedAtMs-(e.gestureEndUptimeMs-e.gestureStartUptimeMs)-e.recordingStartedAt):Math.max(0,e.fallbackStartedAtMs-e.recordingStartedAt)}let nB=new WeakMap;function nK(e){if(!e)return;let t=nB.get(e);if(t)return t;let r=function(e){let t=function(e){let t=e.filter(e=>(function(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("application")||t.includes("window")})(e.type)&&nz(e.rect)).map(e=>e.rect).sort((e,t)=>(t?.width??0)*(t?.height??0)-(e?.width??0)*(e?.height??0))[0];if(t)return t;let r=e.map(e=>e.rect).filter(nz);if(0===r.length)return;let a=Math.max(...r.map(e=>e.x+e.width)),i=Math.max(...r.map(e=>e.y+e.height));if(!(a<=0)&&!(i<=0))return{x:0,y:0,width:a,height:i}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return nB.set(e,r),r}function nz(e){return!!e&&e.width>0&&e.height>0}let nW={referenceWidth:1e3,referenceHeight:1e3};function nJ(e,t,r,a,i={},n=Date.now(),o=Date.now()){var s,l,d;let u,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=nQ(p.effectiveDurationMs)??nQ(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:nQ(p.gestureStartUptimeMs),gestureEndUptimeMs:nQ(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:nQ(p.gestureStartUptimeMs),gestureEndUptimeMs:nQ(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),w="ios"===e.device.platform&&void 0===nQ(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=n0(nQ(t.count),1)??1,r=!0===t.doubleTap,a=n0(nQ(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,p)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return nH(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nH(h),y=(l=e.snapshot,u=nQ((d=p).referenceWidth),c=nQ(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:nK(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=n1(t,e);if(!i)return[];let{x:n,y:o}=i,s=n0(nQ(t.count),1)??1,l=n0(nQ(t.intervalMs),0)??0,d=!0===t.doubleTap,u=n0(nQ(t.holdMs),1),c=[];for(let e=0;e<s;e+=1){let t=r+e*l;if(void 0!==u&&u>0){c.push(nX(t,n,o,u,a));continue}c.push(nZ(t,n,o,a)),d&&c.push(nZ(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=n1(t,e);if(!i)return[];let{x:n,y:o}=i;return[nZ(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=n1(t,e);if(!n)return[];let{x:o,y:s}=n;return[nX(r,o,s,n3(a,[nQ(t.durationMs),nQ(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=n2(t,e),o=nY(t.contentDirection)??nY(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=n3(a,[],250),f=nQ(t.amount)??nQ(e[1]),p=nQ(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...i,durationMs:c,contentDirection:o,...void 0!==f?{amount:f}:{},...void 0!==p?{pixels:p}:{}}]}(t,r,a,i,n);case"swipe":return function(e,t,r,a,i){let n=n2(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=n3(a,[nQ(t.effectiveDurationMs),nQ(t.durationMs),nQ(e[4])],250),c=n0(nQ(t.count),1)??1,f=n0(nQ(t.pauseMs),0)??0,p="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===p&&e%2==1,a=t?l:o,n=t?d:s,c=t?o:l,h=t?s:d,g=r+e*(u+f);if("back-swipe"===function(e,t,r,a,i){if(!i||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let n=.08*i.referenceWidth;return e<=n&&r>e||e>=i.referenceWidth-n&&r<e?"back-swipe":"swipe"}(a,n,c,h,i)){m.push({kind:"back-swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u,edge:function(e,t,r){if(r){let t=.08*r.referenceWidth;if(e<=t)return"left";if(e>=r.referenceWidth-t)return"right"}return t>=e?"left":"right"}(a,c,i)});continue}m.push({kind:"swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u})}return m}(t,r,a,i,n);case"pinch":return function(e,t,r,a,i){let n=n1(t,e,1),o=nQ(t.scale)??nQ(e[0]);if(!n||void 0===o||o<=0)return[];let{x:s,y:l}=n;return[{kind:"pinch",tMs:r,x:s,y:l,...i,scale:o,durationMs:n3(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),P({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:w,gestureDurationMs:g,kinds:v.map(e=>e.kind)}}))}function nZ(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function nX(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function nY(e){if("string"!=typeof e)return;let t=e.trim().toLowerCase();switch(t){case"up":case"down":case"left":case"right":return t;default:return}}function nQ(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"!=typeof e||0===e.trim().length)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function n0(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function n1(e,t,r=0){let a=nQ(e.x)??nQ(t[r]),i=nQ(e.y)??nQ(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function n2(e,t){let r=nQ(e.x1)??nQ(t[0]),a=nQ(e.y1)??nQ(t[1]),i=nQ(e.x2)??nQ(t[2]),n=nQ(e.y2)??nQ(t[3]);if(void 0!==r&&void 0!==a&&void 0!==i&&void 0!==n)return{x1:r,y1:a,x2:i,y2:n}}function n3(e,t,r){return n0(e,1)??t.map(e=>n0(e,1)).find(e=>void 0!==e)??r}function n8(e){var t,r,a;let i,n,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,i="string"==typeof t?.ref?t.ref:void 0,n="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:i?n&&"primary"!==n?`Clicked ${n} @${i} (${r}, ${a})`:`Tapped @${i} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...tr(c)}}function n4(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:o}),ef(a)&&e9(t,a),nJ(t,a,i,o,n??{},l,d),{ok:!0,data:s}}async function n5(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await eb(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=nK(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=nK(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function n9(e){try{return await n5(e)}catch(t){P({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function n6(e){return nK({nodes:e,createdAt:0})}function n7(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:eH("UNSUPPORTED_OPERATION",`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function oe(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new T("SESSION_NOT_FOUND","No active session. Run open first.");return y({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,i)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0})}),tap:async(a,i)=>ot(await er(r.device,"press",[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(a,i,n)=>ot(await er(r.device,"fill",[String(i.x),String(i.y),n],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(a,i)=>ot(await er(r.device,"type",[i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),artifacts:eF("interaction commands",{plural:!0}),sessions:{get:r=>r===e.sessionName?{name:e.sessionName,appBundleId:t.appBundleId,appName:t.appName,snapshot:t.snapshot,metadata:{surface:t.surface}}:void 0,set:r=>{r.snapshot&&(t.snapshot=r.snapshot,e.sessionStore.set(e.sessionName,t))}},policy:w()})}function ot(e){return e&&"object"==typeof e?e:void 0}function or(e){return"ref"===e.kind?{ref:oa(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function oa(e){return e?.startsWith("@")?e.slice(1):e}async function oi(e){switch(e.req.command){case"press":case"click":return await on(e);case"fill":return await oo(e);default:return null}}async function on(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n="click"===t.command?"click":"press";if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let o=n7(i,n);if(o)return o;if(!e2("press",i.device))return eH("UNSUPPORTED_OPERATION","press is not supported on this device");let s=eM(t.flags),l=en(s);if("primary"!==s){let e=ed({commandLabel:n,platform:i.device.platform,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return eH(e.code,e.message,e.details)}let d=function(e,t){let r=eq(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.length>1?e.slice(1).join(" ").trim():""}};let i=e.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:i}}:{ok:!1,response:eH("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(t.positionals??[],n);if(!d.ok)return d.response;if("ref"===d.target.kind){let r=e.refSnapshotFlagGuardResponse("press",t.flags);if(r)return r}return await os(e,{run:async e=>{let a={session:r,requestId:t.meta?.requestId,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap};return"click"===n?await e.interactions.click(d.target,a):await e.interactions.press(d.target,a)},afterRun:async e=>{var t;await eg(i,(t=d.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{let n="point"===r.kind?await n9({session:i,flags:t.flags,sessionStore:a,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):n6(i.snapshot?.nodes??[]),o=n8({data:r.backendResult,fallbackX:r.point.x,fallbackY:r.point.y,referenceFrame:n,extra:{...or(r),...l}});return{result:o,responseData:o}}})}async function oo(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=n7(i,"fill");if(e)return e}if(i&&!e2("fill",i.device))return eH("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let n=function(e){let t=e[0]??"";if(t.startsWith("@")){let r=e.length>=3?e[1]:"",a=e.length>=3?e.slice(2).join(" "):e.slice(1).join(" ");return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:r},text:a}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after ref")}}let r=eq(e);if(r){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:r.x,y:r.y},text:t}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after coordinates")}}let a=ta(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:eH("INVALID_ARGS","fill requires x y text, @ref text, or selector text")};let i=a.rest.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:a.selectorExpression},text:i}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!n.ok)return n.response;if("ref"===n.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r}return await os(e,{run:async e=>await e.interactions.fill(n.target,n.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:n6(i.snapshot?.nodes??[]),r=n8({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...or(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:oa(e.target?.kind==="ref"?e.target.ref:void 0),x:e.point.x,y:e.point.y}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function os(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let a=oe(e),i=Date.now();try{let n=await t.run(a);await t.afterRun?.(n);let o=Date.now(),{result:s,responseData:l}=await t.buildPayloads(n);return n4({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:i,actionFinishedAt:o})}catch(t){let e=E(t);if(eG(e))throw e;return{ok:!1,error:$(t)}}}async function ol(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},o=a(n,e.appBundleId,e.trace?.outPath),{snapshot:s}=await ek({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}let od=/\bis(?:n't| not)\s+responding\b/i,ou=/^close app$/i;async function oc(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await of(t),r=function(e){if(og(e))return e.find(e=>{let t=oh(e);return t.length>0&&ou.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=tm(r.rect),n=await F("adb",K(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return P({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),"failed";if(!await op(t))return P({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eL(t.device,t.appBundleId),!await om(t,t.appBundleId)))return P({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return P({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:i}}),"recovered"}catch(e){return P({level:"warn",phase:"android_blocking_dialog_recovery_failed",data:{session:t.name,deviceId:t.device.id,error:e instanceof Error?e.message:String(e)}}),"failed"}}async function of(e){return tp(tf((await em(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function op(e){for(let t=0;t<12;t+=1){if(!og(await of(e)))return!0;await G(500)}return!og(await of(e))}async function om(e,t){for(let r=0;r<12;r+=1){if((await eI(e.device)).package===t)return!0;await G(500)}return(await eI(e.device)).package===t}function oh(e){let t=[e.label,e.identifier];return"string"==typeof e.value&&e.value.trim().length>0&&t.push(e.value),t.filter(e=>"string"==typeof e&&e.trim().length>0).join(" ").trim()}function og(e){return e.some(e=>{let t=oh(e);return t.length>0&&od.test(t)})}async function ow(e){let t=await oi({...e,captureSnapshotForSession:ol,refSnapshotFlagGuardResponse:ei});if(t)return t;switch(e.req.command){case"type":return await oy({...e,captureSnapshotForSession:ol});case"get":return await ev(e);case"is":return await ex(e);default:return null}}async function oy(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");if(!e2("type",i.device))return eH("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await oc({session:i}))return eH("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=oe(e),s=Date.now();try{let e=await o.interactions.typeText(n,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),d={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...tr(e.message??`Typed ${Array.from(e.text).length} chars`)};return n4({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:d,responseData:d,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:$(e)}}}function ov(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function oS(e){let{req:t,leaseRegistry:r}=e,a=ov(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}function oI(e,t){if(!t)return[];let r=[],a=e.device,i=e4(t.platform);if(i&&!e1(a.platform,i)&&r.push({key:"platform",value:t.platform}),t.target&&t.target!==(a.target??"mobile")&&r.push({key:"target",value:t.target}),t.udid&&("ios"!==a.platform||t.udid!==a.id)&&r.push({key:"udid",value:t.udid}),t.serial&&("android"!==a.platform||t.serial!==a.id)&&r.push({key:"serial",value:t.serial}),t.device&&t.device.trim().toLowerCase()!==a.name.trim().toLowerCase()&&r.push({key:"device",value:t.device}),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),i=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==i)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=B(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oA(e){return`${function(e){switch(e){case"iosSimulatorDeviceSet":return"--ios-simulator-device-set";case"androidDeviceAllowlist":return"--android-device-allowlist";default:return`--${e}`}}(e.key)}=${e.value}`}let ob=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function o_(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:s}=e,l=y({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let o={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?oN(await er(t.device,"screenshot",[],i,o)):oN(await er(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:i,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new T("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-screenshot-")),r=o.join(t,"screenshot.png")),await n.mkdir(o.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await n.mkdtemp(o.join(c.tmpdir(),`${e.prefix}-`));return{path:o.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}}},sessions:{get:e=>e===r?{name:r,appBundleId:t.appBundleId,metadata:{surface:t.surface}}:void 0,set:()=>{}},policy:w()});return await l.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,maxSize:s.screenshotMaxSize,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function oN(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let ok=[255,59,48,255],ox=[255,214,10,255],oM=[0,0,0,255],oD={e:["01110","10000","11110","10000","10000","10001","01110"],0:["01110","10001","10011","10101","11001","10001","01110"],1:["00100","01100","00100","00100","00100","00100","01110"],2:["01110","10001","00001","00010","00100","01000","11111"],3:["11110","00001","00001","01110","00001","00001","11110"],4:["00010","00110","01010","10010","11111","00010","00010"],5:["11111","10000","10000","11110","00001","00001","11110"],6:["01110","10000","10000","11110","10001","10001","01110"],7:["11111","00001","00010","00100","01000","01000","01000"],8:["01110","10001","10001","01110","10001","10001","01110"],9:["01110","10001","10001","01111","00001","00001","01110"]};async function oP(e){let t=tt(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oR(r)&&oT(r.rect)&&(!t||oU(r.rect)>oU(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,i=-1/0;for(let n of e)n.rect&&oT(n.rect)&&(t=Math.min(t,n.rect.x),r=Math.min(r,n.rect.y),a=Math.max(a,n.rect.x+n.rect.width),i=Math.max(i,n.rect.y+n.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||i<=r?null:{x:t,y:r,width:a-t,height:i-r}}(e.filter(e=>{var t;return oT(e.rect)&&!("image"===tc((t=e).type??"")&&!oO(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oC)||oE(e.identifier);return oL(e)?t:t&&function(e){let t=tc(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let o=function(e,t){if(function(e){return oL(e)&&!oR(e)}(t)&&oT(t.rect))return t;let r=function(e,t){let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){;a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(oL(t)&&!oR(t)&&oT(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oT(r.rect))return r;if(t.hittable&&oT(t.rect)&&!oR(t))return t;let a=ti(e,t);return a?.rect&&oT(a.rect)&&!oR(a)?a:null}(e.nodes,a);if(!o?.rect||!oT(o.rect))continue;let s=function(e,t,r){let a=o$(e);if(e.ref!==t.ref&&a)return a;let i=function(e,t){let r=null;for(let a of t){if(a.ref===e.ref||!function(e,t,r){let a=e;for(;void 0!==a.parentIndex;){let e=r[a.parentIndex];if(!e)break;if(e.ref===t.ref)return!0;a=e}return!1}(a,e,t))continue;let i=o$(a);if(!i)continue;let n=function(e){let t=0;return tc(e.type??"").includes("text")&&(t+=2),oC(e.label)&&(t+=2),oC(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(o$(t)??td(t,r))}(a,o,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),oL(t)&&(a+=3),oL(e)&&(a+=2),r&&(a+=2),oE(t.identifier)&&(a+=1),oO(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return oV({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,a);let i=r/e.width,n=a/e.height;return oV({x:Math.round((t.x-e.x)*i),y:Math.round((t.y-e.y)*n),width:Math.max(1,Math.round(t.width*i)),height:Math.max(1,Math.round(t.height*n))},r,a)}(i,o.rect,t,r);if(!oT(d))continue;let u=n.get(o.ref);(!u||l>u.score)&&n.set(o.ref,{ref:o.ref,label:s,rect:o.rect,overlayRect:d,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>oU(e.overlayRect)-oU(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oF(e.overlayRect,r.overlayRect)||oF(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oU(r.overlayRect)<oU(t[e].overlayRect)&&(t[e]=r)}return t})([...n.values()]).sort((e,t)=>{if(t.score!==e.score)return t.score-e.score;let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:oG(e.ref,t.ref)}).slice(0,a.maxRefs??24).sort((e,t)=>{let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:oG(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:tm(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,i;(function(e,t,r){for(let a=0;a<2;a+=1)oq(e,t.x,t.x+t.width-1,t.y+a,r),oq(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),oH(e,t.x+a,t.y,t.y+t.height-1,r),oH(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,ok),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oj(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:oj(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)oB(e,t+o,r+n,i)})(e,i,o,a,ox),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oD[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&oB(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,oM)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,m.sync.write(t)),r}function oL(e){let t=[e.type,e.role,e.subrole].map(e=>tc(e??"")).join(" ");return t.includes("button")||t.includes("link")||t.includes("menu")||t.includes("tab")||t.includes("textfield")||t.includes("searchfield")||t.includes("securetextfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("cell")}function oR(e){let t=[e.type,e.role,e.subrole].map(e=>tc(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oO(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oC(e){var t;let r;return!!oO(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oE(e){var t;return"string"==typeof e&&!!oC(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function o$(e){let t=[e.label,e.value].find(oC);return t?t.trim():oE(e.identifier)?e.identifier.trim():void 0}function oT(e){return!!(e&&e.width>0&&e.height>0)}function oU(e){return e.width*e.height}function oF(e,t){return t.x>=e.x&&t.y>=e.y&&t.x+t.width<=e.x+e.width&&t.y+t.height<=e.y+e.height}function oG(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oV(e,t,r){let a=oj(e.x,0,Math.max(0,t-1)),i=oj(e.y,0,Math.max(0,r-1)),n=Math.max(1,t-a),o=Math.max(1,r-i);return{x:a,y:i,width:oj(e.width,1,n),height:oj(e.height,1,o)}}function oj(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oq(e,t,r,a,i){for(let n=t;n<=r;n+=1)oB(e,n,a,i)}function oH(e,t,r,a,i){for(let n=r;n<=a;n+=1)oB(e,t,n,i)}function oB(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let i=(e.width*r+t)*4;e.data[i]=a[0],e.data[i+1]=a[1],e.data[i+2]=a[2],e.data[i+3]=a[3]}let oK=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),oz=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),oW=new Set(oz),oJ=new Map;function oZ(e,t,r,a){let i=k().requestId;return{...eR(e,t,r,a,i),requestId:i}}async function oX(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||r6(e.flags))try{let t=await eh(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function oY(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await oS({req:t,leaseRegistry:n});if(l)return l;let d=await i8({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await eo({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await nq({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await i4({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await ow({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:s});return p||null}async function oQ(e){var t,r;let a,i,n,o,s,l,d,{req:u,session:c,logPath:f,sessionStore:p}=e,m=u.command;if(!e2(m,c.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${m} is not supported on this device`}};if("android"===c.device.platform&&c.recording&&"record"!==m&&"failed"===await oc({session:c}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:h,resolvedOut:g,recordedPositionals:w,recordedFlags:y}=(a=(t=u).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tU.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tU.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?o:i,d="screenshot"===a&&s?{...t.flags??{},out:s}:t.flags??{},{resolvedPositionals:o,resolvedOut:s,recordedPositionals:l,recordedFlags:d}),v=Date.now(),S={...oZ(f,u.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},I="screenshot"===m?await o_({session:c,sessionName:e.sessionName,outPath:h[0]??g,outputPlacement:"screenshot"!==(r=u).command?"default":(r.positionals??[])[0]?"positional":r.flags?.out?"out":"default",dispatchContext:S}):await er(c.device,m,h,g,{...S});return"screenshot"===m&&u.flags?.overlayRefs&&"string"==typeof I?.path&&await o0(c,I,f),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=nK(e.snapshot),n={...a??{}},o=nY(n.direction)??nY(r[0]);if(!o)return a;let s=nQ(n.amount)??nQ(r[1]),l=nQ(n.pixels),d=n2(n,[]),u=nQ(n.referenceWidth),c=nQ(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??nW;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...n,x1:d.x1,y1:d.y1,x2:d.x2,y2:d.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==l?{pixels:l}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=e6({direction:o,amount:s,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,s);nJ(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:I,actionStartedAt:v,actionFinishedAt:Date.now(),flags:u.flags??{}}),ef(m)&&e9(c,m),{ok:!0,data:I??{}}}async function o0(e,t,r){let a=eP(await eO({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oP({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function o1(e){i.existsSync(e)&&i.unlinkSync(e)}function o2(e){if(!i.existsSync(e))return null;try{let t=JSON.parse(i.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function o3(e){let t=o2(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function o8(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:o4,infoPath:o5,lockPath:o9,logPath:o6,sessionsDir:o7}=_(process.env.AGENT_DEVICE_STATE_DIR),se=x(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var st=o7;if(i.existsSync(st))for(let e of i.readdirSync(st,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=o.join(st,e.name,tG);if(i.existsSync(t))try{let e=tV(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=L(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=O(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{tq(t)}}let sr=new tU(o7),sa=new rW({maxActiveSimulatorLeases:o8(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),si=v(),sn=a.randomBytes(24).toString("hex"),so=L(process.pid)??void 0,ss=S(),sl=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:n}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await b({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:$(new T("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=A(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=I(r);if(r&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new T("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let i=e.session||"default";return i.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${i}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);P({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let l=r.command,d=ov(r);oz.has(l)||r.meta?.sessionIsolation!=="tenant"||i.assertLeaseAdmission({tenantId:d.tenantId,runId:d.runId,leaseId:d.leaseId,backend:d.leaseBackend});let u=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,a),c=oW.has(l)?null:await oX(r,u,a),f=async()=>{let e=a.get(u);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=eU(e.device.id);if(!t.runnerSessionId){r?.alive&&(t.runnerSessionId=r.sessionId);return}if(!r?.alive){t.invalidatedReason??="iOS runner session exited during recording";return}r.sessionId!==t.runnerSessionId&&(t.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(u,e));let d=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?oI(t,a):function(e,t,r){var a,i;let n=[],o=e4(t);if(void 0!==e.platform&&o&&(a=e4(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!e3(i):"apple"!==i||!e3(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of ob){let r=e[t];"string"==typeof r&&r.trim().length>0&&n.push({key:t,value:r})}return n}(a,e.meta?.lockPlatform,e.command);if(0===i.length)return!t&&e.meta?.lockPlatform&&void 0===a.platform&&(a.platform=e.meta.lockPlatform),{...e,flags:a};if("strip"===r)return t?(function(e,t){for(let r of t)delete e[r.key]}(a,i),a.platform=t.device.platform):function(e,t){for(let t of ob)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new T("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oA).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=k();if(!t.ok){P({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=N({force:!0})??void 0;return{ok:!1,error:$(new T(C(t.error.code),t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return P({level:"info",phase:"request_success"}),N(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let s=(a=e,i=t,n=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||n.some(e=>e?.field==="path")||"string"!=typeof i.path||n.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:o.basename(a.meta?.clientArtifactPaths?.path??i.path)}),n.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(d,e,n);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||oK.has(l)||function(e,t){let r=oI(e,t);if(0!==r.length){var a;let t,i,n;throw new T("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oA).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await oY({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...oZ(t,e,r,i),surface:a.get(u)?.surface})});if(f)return c(f);let p=a.get(u);if(!p)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await oQ({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await ey(oJ,c,f)}catch(r){P({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=k(),t=N({force:!0})??void 0;return{ok:!1,error:$(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:o6,token:sn,sessionStore:sr,leaseRegistry:sa,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{ry(t)},9e5);return r.unref(),rw.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){i.existsSync(e)||i.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return i.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=o2(t);if(o?.pid&&o.pid!==process.pid&&R(o.pid,o.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(o4,o9,{pid:process.pid,version:si,startedAt:Date.now(),processStartTime:so})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===se||"dual"===se){let t=h.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))eV(e);P({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await eT(),!(r<=0));)await G(200)}catch(e){P({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:r}})}})()}};e.setEncoding("utf8"),e.on("close",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eE(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),ec(o),eC(o))throw eu();i=await sl(e)}catch(e){i={ok:!1,error:$(e)}}finally{r-=1,o&&(a.delete(o),eJ(o))}e.destroyed||e.write(`${JSON.stringify(i)}
|
|
35
|
-
`),n=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new T("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===
|
|
33
|
+
`.trim();async function nm(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,o=0;for(let t=0;t<n;t+=1){let t=0;try{t=i.statSync(e).size}catch{t=0}if(t>0&&t===r){if((o+=1)>=2)return}else o=0;r=t,await G(a)}}async function nh(e){try{var t,r;let a,i=await U("swift",["-",e],{stdin:np,allowFailure:!0,timeoutMs:1e4});if(0===i.exitCode)return!0;if(t=i.stderr,r=i.stdout,a=`${t}
|
|
34
|
+
${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return nw(e);return!1}catch(t){if(t instanceof T&&"TOOL_MISSING"===t.code)return nw(e);throw t}}async function ng(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await nh(e))return;await G(r)}}function nw(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(a.push(o),1===n){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function ny(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nv(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nI(e){let t=o.dirname(u(import.meta.url)),r=[u(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new T("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure ios-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}async function nS(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await nm(t),await ng(t);let s=i.mkdtempSync(o.join(c.tmpdir(),"agent-device-record-overlay-")),l=o.join(s,`input${o.extname(t)||".mp4"}`),u=o.join(s,o.basename(t)),d=o.join(s,"home"),f=o.join(s,"module-cache");i.copyFileSync(t,l),i.mkdirSync(d,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await U("xcrun",["swift",r,"--input",l,"--output",u,...a],{timeoutMs:12e4,env:{...process.env,HOME:d,CLANG_MODULE_CACHE_PATH:f}}),await ng(u),i.copyFileSync(u,t)}catch(a){let e=a instanceof T?a:new T("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new T("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function nA(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nS({videoPath:r,scriptPath:t??=nI("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function nb(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nS({videoPath:r,scriptPath:e??=nI("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function n_(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await nS({videoPath:t,scriptPath:r??=nI("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function nN(e){return e instanceof Error?e.message:String(e)}function nk(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function nx(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:n}=e,o=function(e){var t,r,a;let n,o,{recording:s,trimStartMs:l}=e,u=(n=ny((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?nv(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)}]})):nv(r))},i.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=u,u}({recording:t,trimStartMs:a});if(t.showTouches){let e=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(e)t.overlayWarning??=e;else try{await r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,targetLabel:n})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${nN(e)}`}}}async function nD(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","ps","-o","pid=","-p",r],{allowFailure:!0});return 0===a.exitCode&&a.stdout.split(/\s+/).map(e=>e.trim()).includes(r)}async function nM(e,t,r){for(let a=0;a<40;a+=1){if(!await nD(e,t,r))return!0;await G(250)}return!await nD(e,t,r)}async function nP(e,t,r){let a,i=0;for(let n=0;n<20;n+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?n.stdout.trim():"";if(o.length>0&&o===a){if((i+=1)>=4)return}else i=0;a=o,await G(250)}}async function nL(e,t,r,a){for(let i=0;i<8;i+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?Number(n.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await nD(e,t,a))break;if(i+1>=2)return!0;await G(250)}return!1}async function nR(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{i.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",a,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=nk(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(P({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return i.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;P({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1}})}e<1&&await G(750)}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function nO(e){let{deps:t,deviceId:r,quality:a}=e;if(void 0===a||a>=10)return;let i=await t.runCmd("adb",["-s",r,"shell","wm","size"],{allowFailure:!0}),n=i.stdout.match(/Override size:\s*(\d+)x(\d+)/)??i.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==i.exitCode||!n)throw Error(`failed to resolve Android screen size for recording quality: ${nk(i,"adb shell wm size")}`);return{width:nE(Number(n[1]),a),height:nE(Number(n[2]),a)}}function nE(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nC(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function n$(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return P({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:t,remotePid:r,exitCode:a.exitCode,stdout:a.stdout.trim(),stderr:a.stderr.trim()}}),!(0!==a.exitCode&&await nD(e,t,r))&&await nM(e,t,r)}async function nT(e){var t;let r,a,{deps:i,device:n,recordingBase:o}=e,s="failed to start recording: Android screenrecord did not begin producing frames";try{r=await nO({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return eH("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),a=`agent-device-recording-${t}.mp4`,[`/sdcard/${a}`,`/data/local/tmp/${a}`])){let t=await i.runCmd("adb",["-s",n.id,"shell",function(e,t){let r=["screenrecord"];return t&&r.push("--size",`${t.width}x${t.height}`),r.push(e),`${r.join(" ")} >/dev/null 2>&1 & echo $!`}(e,r)],{allowFailure:!0});if(0!==t.exitCode){s=`failed to start recording: ${nk(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 nC(i,n.id,e);continue}if(P({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nL(i,n.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...o,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await n$(i,n.id,a),await nC(i,n.id,e)}return eH("COMMAND_FAILED",s)}async function nF(e){let t,r,{deps:a,device:i,recording:n}=e;P({level:"debug",phase:"record_stop_android_enter",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid}});let o=await a.runCmd("adb",["-s",i.id,"shell","kill","-2",n.remotePid],{allowFailure:!0});if(P({level:"debug",phase:"record_stop_android_signal",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await nD(a,i.id,n.remotePid)&&!await n$(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nk(o,"adb shell kill")}`):await nM(a,i.id,n.remotePid)||await n$(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nP(a,i.id,n.remotePath);let e=await nR({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),eH("COMMAND_FAILED",e);await nx({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return eH("COMMAND_FAILED",t);if(r)return eH("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});P({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:i.id,remotePath:n.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${nk(e,"adb shell rm")}`)}}function nU(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nG(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nV(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nU(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nG(t,i,r))}catch(e){P({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:nN(e)}})}}async function nj(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:o,logPath:s,deps:l,fpsFlag:u,recordingBase:d,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=nG(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,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(a){var g,w;if(!nN(a).toLowerCase().includes("recording already in progress"))return eH("COMMAND_FAILED",`failed to start recording: ${nN(a)}`);P({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:nN(a)}});let e=(g=o.id,w=i.name,n.toArray().find(e=>e.name!==w&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return eH("COMMAND_FAILED",`failed to start recording: recording already in progress in session '${e.name}'`);try{await l.runIosRunnerCommand(o,{command:"recordStop",appBundleId:c},m)}catch{}try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${nN(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...d}}async function nq(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await n.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,quality:s.quality,appBundleId:l},nG(t,i,r))}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${nN(e)}`)}return{platform:"macos-runner",...s}}async function nH(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nU(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nG(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nN(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of ee)if(0===(l=await n.runCmd("xcrun",["devicectl","device","copy","from","--device",a.id,"--source",o.remotePath,"--destination",o.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==l.exitCode){let e=l.stderr.trim()||l.stdout.trim()||`devicectl exited with code ${l.exitCode}`;return eH("COMMAND_FAILED",`failed to copy recording from device: ${e}`)}let u="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);return u>0&&await n.trimRecordingStart({videoPath:o.outPath,trimStartMs:u}),await nx({recording:o,deps:n,trimStartMs:u,targetLabel:"iOS recording"}),null}async function nB(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nU(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nG(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nN(e)}})}return await nx({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nK(e){for(let t=0;t<2;t+=1){try{if(i.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await G(250)}return Date.now()}async function nz(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:u}=e;await nV({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:d,wait:c}=s.runCmdBackground("xcrun",X(n,["io",n.id,"recordVideo",u]),{allowFailure:!0}),f=await nK(u);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nU(i)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:i.trace?.outPath}),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:f,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function nW(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:l,logPath:u,deps:d}=e;if(s.recording)return eH("INVALID_ARGS","recording already in progress");let c=r.flags?.fps,f=r.flags?.quality;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return eH("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return eH("INVALID_ARGS","quality must be an integer between 5 and 10");if(!e2("record",l))return eH("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tF.expandHome(p,r.meta?.cwd),h={outPath:m,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),quality:r.flags?.quality,showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(i.mkdirSync(o.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nU(s);if(!e)return eH("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nj({req:r,activeSession:s,sessionStore:n,device:l,logPath:u,deps:d,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nU(s);if(!e)return eH("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nq({req:r,activeSession:s,device:l,logPath:u,deps:d,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await nz({req:r,activeSession:s,device:l,logPath:u,deps:d,recordingBase:h,resolvedOut:m}):await nT({deps:d,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,n.set(a,s),n.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??p,showTouches:t.showTouches}})}async function nJ(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nF({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: ${nk(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: ${nN(e)}`}return await nx({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nZ(e){var t;let r,{req:a,activeSession:i,device:n,logPath:s,deps:l}=e;if(!i.recording)return eH("INVALID_ARGS","no active recording");let u=i.recording,d=u.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===u.platform?await nH({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:u}):"macos-runner"===u.platform?await nB({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:u}):await nJ({deps:l,device:n,recording:u});return c||(d?eH("COMMAND_FAILED",d):(r=[{field:"outPath",path:(t=u).outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return ny(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nX(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:U,runCmdBackground:F,runIosRunnerCommand:eB,waitForStableFile:nm,isPlayableVideo:nh,trimRecordingStart:nA,resizeRecording:n_,overlayRecordingTouches:nb},o=a.get(r),s=o?.device??await eh(t.flags??{});o||await ez(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},u=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(u))return eH("INVALID_ARGS","record requires start|stop");if("start"===u)return nW({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let d=await nZ({req:t,activeSession:l,device:s,logPath:i,deps:n});return d.ok&&a.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 nY(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,s=t.command;if("record"===s)return nX({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return eH("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return eH("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=tF.expandHome(e);return i.mkdirSync(o.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return eH("INVALID_ARGS","no active trace");let l=n.trace.outPath;if(t.positionals?.[1]){let e=tF.expandHome(t.positionals[1]);i.mkdirSync(o.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nQ(e){return"number"==typeof e.gestureClockOriginAtMs&&"number"==typeof e.gestureClockOriginUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureClockOriginAtMs+(e.gestureStartUptimeMs-e.gestureClockOriginUptimeMs)-e.recordingStartedAt):"number"==typeof e.runnerStartedAtUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureStartUptimeMs-e.runnerStartedAtUptimeMs):"number"==typeof e.gestureStartUptimeMs&&"number"==typeof e.gestureEndUptimeMs?Math.max(0,e.fallbackFinishedAtMs-(e.gestureEndUptimeMs-e.gestureStartUptimeMs)-e.recordingStartedAt):Math.max(0,e.fallbackStartedAtMs-e.recordingStartedAt)}let n0=new WeakMap;function n1(e){if(!e)return;let t=n0.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)&&n2(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(n2);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 n0.set(e,r),r}function n2(e){return!!e&&e.width>0&&e.height>0}let n3={referenceWidth:1e3,referenceHeight:1e3};function n8(e,t,r,a,i={},n=Date.now(),o=Date.now()){var s,l,u;let d,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=n6(p.effectiveDurationMs)??n6(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:n6(p.gestureStartUptimeMs),gestureEndUptimeMs:n6(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:n6(p.gestureStartUptimeMs),gestureEndUptimeMs:n6(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),w="ios"===e.device.platform&&void 0===n6(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=n7(n6(t.count),1)??1,r=!0===t.doubleTap,a=n7(n6(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,p)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return nQ(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nQ(h),y=(l=e.snapshot,d=n6((u=p).referenceWidth),c=n6(u.referenceHeight),void 0!==d&&d>0&&void 0!==c&&c>0?{referenceWidth:d,referenceHeight:c}:n1(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=oe(t,e);if(!i)return[];let{x:n,y:o}=i,s=n7(n6(t.count),1)??1,l=n7(n6(t.intervalMs),0)??0,u=!0===t.doubleTap,d=n7(n6(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(n5(t,n,o,d,a));continue}c.push(n4(t,n,o,a)),u&&c.push(n4(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=oe(t,e);if(!i)return[];let{x:n,y:o}=i;return[n4(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=oe(t,e);if(!n)return[];let{x:o,y:s}=n;return[n5(r,o,s,or(a,[n6(t.durationMs),n6(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=ot(t,e),o=n9(t.contentDirection)??n9(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:u,y2:d}=n,c=or(a,[],250),f=n6(t.amount)??n6(e[1]),p=n6(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:u,y2:d,...i,durationMs:c,contentDirection:o,...void 0!==f?{amount:f}:{},...void 0!==p?{pixels:p}:{}}]}(t,r,a,i,n);case"swipe":return function(e,t,r,a,i){let n=ot(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:u}=n,d=or(a,[n6(t.effectiveDurationMs),n6(t.durationMs),n6(e[4])],250),c=n7(n6(t.count),1)??1,f=n7(n6(t.pauseMs),0)??0,p="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===p&&e%2==1,a=t?l:o,n=t?u:s,c=t?o:l,h=t?s:u,g=r+e*(d+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: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"}(a,c,i)});continue}m.push({kind:"swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:d})}return m}(t,r,a,i,n);case"pinch":return function(e,t,r,a,i){let n=oe(t,e,1),o=n6(t.scale)??n6(e[0]);if(!n||void 0===o||o<=0)return[];let{x:s,y:l}=n;return[{kind:"pinch",tMs:r,x:s,y:l,...i,scale:o,durationMs:or(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),P({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:w,gestureDurationMs:g,kinds:v.map(e=>e.kind)}}))}function n4(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function n5(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function n9(e){if("string"!=typeof e)return;let t=e.trim().toLowerCase();switch(t){case"up":case"down":case"left":case"right":return t;default:return}}function n6(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"!=typeof e||0===e.trim().length)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function n7(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function oe(e,t,r=0){let a=n6(e.x)??n6(t[r]),i=n6(e.y)??n6(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function ot(e,t){let r=n6(e.x1)??n6(t[0]),a=n6(e.y1)??n6(t[1]),i=n6(e.x2)??n6(t[2]),n=n6(e.y2)??n6(t[3]);if(void 0!==r&&void 0!==a&&void 0!==i&&void 0!==n)return{x1:r,y1:a,x2:i,y2:n}}function or(e,t,r){return n7(e,1)??t.map(e=>n7(e,1)).find(e=>void 0!==e)??r}function oa(e){var t,r,a;let i,n,{data:o,fallbackX:s,fallbackY:l,referenceFrame:u,extra:d}=e,c=(t=d,r=s,a=l,i="string"==typeof t?.ref?t.ref:void 0,n="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:i?n&&"primary"!==n?`Clicked ${n} @${i} (${r}, ${a})`:`Tapped @${i} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...u??{},...d??{},...o??{},...tr(c)}}function oi(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:u,androidFreshnessBaseline:d}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:o}),ef(a)&&e9(t,a,d??t.snapshot),n8(t,a,i,o,n??{},l,u),{ok:!0,data:s}}async function on(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await eb(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=n1(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=n1(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function oo(e){try{return await on(e)}catch(t){P({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function os(e){return n1({nodes:e,createdAt:0})}function ol(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null: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 ou(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new T("SESSION_NOT_FOUND","No active session. Run open first.");return y({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,i)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0})}),tap:async(a,i)=>od(await er(r.device,"press",[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(a,i,n)=>od(await er(r.device,"fill",[String(i.x),String(i.y),n],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(a,i)=>od(await er(r.device,"type",[i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),artifacts:eU("interaction commands",{plural:!0}),sessions:{get:r=>r===e.sessionName?{name:e.sessionName,appBundleId:t.appBundleId,appName:t.appName,snapshot:t.snapshot,metadata:{surface:t.surface}}:void 0,set:r=>{r.snapshot&&(t.snapshot=r.snapshot,e.sessionStore.set(e.sessionName,t))}},policy:w()})}function od(e){return e&&"object"==typeof e?e:void 0}function oc(e){return"ref"===e.kind?{ref:of(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 of(e){return e?.startsWith("@")?e.slice(1):e}async function op(e){switch(e.req.command){case"press":case"click":return await om(e);case"fill":return await oh(e);default:return null}}async function om(e){let t,{req:r,sessionName:a,sessionStore:i}=e,n=i.get(a),o="click"===r.command?"click":"press";if(!n)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let s=ol(n,o);if(s)return s;if(!e2("press",n.device))return eH("UNSUPPORTED_OPERATION","press is not supported on this device");let l=eD(r.flags),u=en(l);if("primary"!==l){let e=eu({commandLabel:o,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 d=function(e,t){let r=eq(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.length>1?e.slice(1).join(" ").trim():""}};let i=e.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:i}}:{ok:!1,response:eH("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(r.positionals??[],o);if(!d.ok)return d.response;if("ref"===d.target.kind){let a=e.refSnapshotFlagGuardResponse("press",r.flags);if(a)return a;t=await ow(e,n)}return await og(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"===o?await e.interactions.click(d.target,t):await e.interactions.press(d.target,t)},afterRun:async e=>{var t;await eg(n,(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 a="point"===t.kind?await oo({session:n,flags:r.flags,sessionStore:i,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):os(n.snapshot?.nodes??[]),o=oa({data:t.backendResult,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:a,extra:{...oc(t),...u}});return{result:o,responseData:o}}})}async function oh(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=ol(i,"fill");if(e)return e}if(i&&!e2("fill",i.device))return eH("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let n=function(e){let t=e[0]??"";if(t.startsWith("@")){let r=e.length>=3?e[1]:"",a=e.length>=3?e.slice(2).join(" "):e.slice(1).join(" ");return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:r},text:a}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after ref")}}let r=eq(e);if(r){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:r.x,y:r.y},text:t}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after coordinates")}}let a=ta(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:eH("INVALID_ARGS","fill requires x y text, @ref text, or selector text")};let i=a.rest.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:a.selectorExpression},text:i}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!n.ok)return n.response;if("ref"===n.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r;await ow(e,i)}return await og(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:os(i.snapshot?.nodes??[]),r=oa({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...oc(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:of(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 og(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let a=ou(e),i=Date.now();try{let n=await t.run(a);await t.afterRun?.(n);let o=Date.now(),{result:s,responseData:l}=await t.buildPayloads(n);return oi({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:i,actionFinishedAt:o,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(t){let e=C(t);if(eG(e))throw e;return{ok:!1,error:$(t)}}}async function ow(e,t){if(!eZ(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){P({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 oy(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},o=a(n,e.appBundleId,e.trace?.outPath),{snapshot:s}=await ek({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??"",androidFreshnessMode:i.androidFreshnessMode});return e.snapshot=s,r.set(e.name,e),e.snapshot}let ov=/\bis(?:n't| not)\s+responding\b/i,oI=/^close app$/i;async function oS(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await oA(t),r=function(e){if(ok(e))return e.find(e=>{let t=oN(e);return t.length>0&&oI.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=tm(r.rect),n=await U("adb",K(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return P({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),"failed";if(!await ob(t))return P({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eL(t.device,t.appBundleId),!await o_(t,t.appBundleId)))return P({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return P({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:i}}),"recovered"}catch(e){return P({level:"warn",phase:"android_blocking_dialog_recovery_failed",data:{session:t.name,deviceId:t.device.id,error:e instanceof Error?e.message:String(e)}}),"failed"}}async function oA(e){return tp(tf((await em(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function ob(e){for(let t=0;t<12;t+=1){if(!ok(await oA(e)))return!0;await G(500)}return!ok(await oA(e))}async function o_(e,t){for(let r=0;r<12;r+=1){if((await eS(e.device)).package===t)return!0;await G(500)}return(await eS(e.device)).package===t}function oN(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 ok(e){return e.some(e=>{let t=oN(e);return t.length>0&&ov.test(t)})}async function ox(e){let t=await op({...e,captureSnapshotForSession:oy,refSnapshotFlagGuardResponse:ei});if(t)return t;switch(e.req.command){case"type":return await oD({...e,captureSnapshotForSession:oy});case"get":return await ev(e);case"is":return await ex(e);default:return null}}async function oD(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");if(!e2("type",i.device))return eH("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await oS({session:i}))return eH("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=ou(e),s=Date.now();try{let e=await o.interactions.typeText(n,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),u={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...tr(e.message??`Typed ${Array.from(e.text).length} chars`)};return oi({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:u,responseData:u,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:$(e)}}}function oM(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function oP(e){let{req:t,leaseRegistry:r}=e,a=oM(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}function oL(e,t){if(!t)return[];let r=[],a=e.device,i=e4(t.platform);if(i&&!e1(a.platform,i)&&r.push({key:"platform",value:t.platform}),t.target&&t.target!==(a.target??"mobile")&&r.push({key:"target",value:t.target}),t.udid&&("ios"!==a.platform||t.udid!==a.id)&&r.push({key:"udid",value:t.udid}),t.serial&&("android"!==a.platform||t.serial!==a.id)&&r.push({key:"serial",value:t.serial}),t.device&&t.device.trim().toLowerCase()!==a.name.trim().toLowerCase()&&r.push({key:"device",value:t.device}),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),i=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==i)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=B(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oR(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 oO=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function oE(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:s}=e,l=y({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let o={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?oC(await er(t.device,"screenshot",[],i,o)):oC(await er(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:i,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new T("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-screenshot-")),r=o.join(t,"screenshot.png")),await n.mkdir(o.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await n.mkdtemp(o.join(c.tmpdir(),`${e.prefix}-`));return{path:o.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}}},sessions:{get:e=>e===r?{name:r,appBundleId:t.appBundleId,metadata:{surface:t.surface}}:void 0,set:()=>{}},policy:w()});return await l.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,maxSize:s.screenshotMaxSize,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function oC(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let o$=[255,59,48,255],oT=[255,214,10,255],oF=[0,0,0,255],oU={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 oG(e){let t=tt(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oj(r)&&oz(r.rect)&&(!t||oW(r.rect)>oW(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&&oz(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 oz(e.rect)&&!("image"===tc((t=e).type??"")&&!oq(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oH)||oB(e.identifier);return oV(e)?t:t&&function(e){let t=tc(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let o=function(e,t){if(function(e){return oV(e)&&!oj(e)}(t)&&oz(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(oV(t)&&!oj(t)&&oz(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oz(r.rect))return r;if(t.hittable&&oz(t.rect)&&!oj(t))return t;let a=ti(e,t);return a?.rect&&oz(a.rect)&&!oj(a)?a:null}(e.nodes,a);if(!o?.rect||!oz(o.rect))continue;let s=function(e,t,r){let a=oK(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=oK(a);if(!i)continue;let n=function(e){let t=0;return tc(e.type??"").includes("text")&&(t+=2),oH(e.label)&&(t+=2),oH(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oK(t)??tu(t,r))}(a,o,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),oV(t)&&(a+=3),oV(e)&&(a+=2),r&&(a+=2),oB(t.identifier)&&(a+=1),oq(t.value)&&(a+=1),a}(a,o,s),u=function(e,t,r,a){if(!e)return oX({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 oX({x:Math.round((t.x-e.x)*i),y:Math.round((t.y-e.y)*n),width:Math.max(1,Math.round(t.width*i)),height:Math.max(1,Math.round(t.height*n))},r,a)}(i,o.rect,t,r);if(!oz(u))continue;let d=n.get(o.ref);(!d||l>d.score)&&n.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)=>oW(e.overlayRect)-oW(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oJ(e.overlayRect,r.overlayRect)||oJ(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oW(r.overlayRect)<oW(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:oZ(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:oZ(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:tm(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,i;(function(e,t,r){for(let a=0;a<2;a+=1)oQ(e,t.x,t.x+t.width-1,t.y+a,r),oQ(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),o0(e,t.x+a,t.y,t.y+t.height-1,r),o0(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,o$),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oY(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:oY(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)o1(e,t+o,r+n,i)})(e,i,o,a,oT),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oU[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&o1(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,oF)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,m.sync.write(t)),r}function oV(e){let t=[e.type,e.role,e.subrole].map(e=>tc(e??"")).join(" ");return t.includes("button")||t.includes("link")||t.includes("menu")||t.includes("tab")||t.includes("textfield")||t.includes("searchfield")||t.includes("securetextfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("cell")}function oj(e){let t=[e.type,e.role,e.subrole].map(e=>tc(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oq(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oH(e){var t;let r;return!!oq(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oB(e){var t;return"string"==typeof e&&!!oH(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oK(e){let t=[e.label,e.value].find(oH);return t?t.trim():oB(e.identifier)?e.identifier.trim():void 0}function oz(e){return!!(e&&e.width>0&&e.height>0)}function oW(e){return e.width*e.height}function oJ(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 oZ(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oX(e,t,r){let a=oY(e.x,0,Math.max(0,t-1)),i=oY(e.y,0,Math.max(0,r-1)),n=Math.max(1,t-a),o=Math.max(1,r-i);return{x:a,y:i,width:oY(e.width,1,n),height:oY(e.height,1,o)}}function oY(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oQ(e,t,r,a,i){for(let n=t;n<=r;n+=1)o1(e,n,a,i)}function o0(e,t,r,a,i){for(let n=r;n<=a;n+=1)o1(e,t,n,i)}function o1(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 o2=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),o3=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),o8=new Set(o3),o4=new Map;function o5(e,t,r,a){let i=k().requestId;return{...eR(e,t,r,a,i),requestId:i}}async function o9(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||r6(e.flags))try{let t=await eh(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function o6(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await oP({req:t,leaseRegistry:n});if(l)return l;let u=await na({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(u)return u;let d=await eo({req:t,sessionName:r,logPath:a,sessionStore:i});if(d)return d;let c=await nY({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await ni({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await ox({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:s});return p||null}async function o7(e){var t,r;let a,i,n,o,s,l,u,{req:d,session:c,logPath:f,sessionStore:p}=e,m=d.command;if(!e2(m,c.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${m} is not supported on this device`}};if("android"===c.device.platform&&c.recording&&"record"!==m&&"failed"===await oS({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=d).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tF.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tF.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?o:i,u="screenshot"===a&&s?{...t.flags??{},out:s}:t.flags??{},{resolvedPositionals:o,resolvedOut:s,recordedPositionals:l,recordedFlags:u}),v=Date.now(),I={...o5(f,d.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},S="screenshot"===m?await oE({session:c,sessionName:e.sessionName,outPath:h[0]??g,outputPlacement:"screenshot"!==(r=d).command?"default":(r.positionals??[])[0]?"positional":r.flags?.out?"out":"default",dispatchContext:I}):await er(c.device,m,h,g,{...I});return"screenshot"===m&&d.flags?.overlayRefs&&"string"==typeof S?.path&&await se(c,S,f),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:u,flags:d}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=n1(e.snapshot),n={...a??{}},o=n9(n.direction)??n9(r[0]);if(!o)return a;let s=n6(n.amount)??n6(r[1]),l=n6(n.pixels),u=ot(n,[]),d=n6(n.referenceWidth),c=n6(n.referenceHeight),f=void 0!==d&&d>0&&void 0!==c&&c>0?{referenceWidth:d,referenceHeight:c}:i??n3;if(u&&(u.x1!==u.x2||u.y1!==u.y2))return{...n,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:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=e6({direction:o,amount:s,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,s);n8(t,a,i,c,d,l,u),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:S,actionStartedAt:v,actionFinishedAt:Date.now(),flags:d.flags??{}}),ef(m)&&e9(c,m),{ok:!0,data:S??{}}}async function se(e,t,r){let a=eP(await eO({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oG({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function st(e){i.existsSync(e)&&i.unlinkSync(e)}function sr(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 sa(e){let t=sr(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function si(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:sn,infoPath:so,lockPath:ss,logPath:sl,sessionsDir:su}=_(process.env.AGENT_DEVICE_STATE_DIR),sd=x(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var sc=su;if(i.existsSync(sc))for(let e of i.readdirSync(sc,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=o.join(sc,e.name,tG);if(i.existsSync(t))try{let e=tV(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=L(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=O(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{tq(t)}}let sf=new tF(su),sp=new rW({maxActiveSimulatorLeases:si(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:si(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:si(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:si(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),sm=v(),sh=a.randomBytes(24).toString("hex"),sg=L(process.pid)??void 0,sw=I(),sy=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:n}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await b({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:$(new T("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=A(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=S(r);if(r&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new T("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let i=e.session||"default";return i.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${i}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);P({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let l=r.command,u=oM(r);o3.has(l)||r.meta?.sessionIsolation!=="tenant"||i.assertLeaseAdmission({tenantId:u.tenantId,runId:u.runId,leaseId:u.leaseId,backend:u.leaseBackend});let d=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,a),c=o8.has(l)?null:await o9(r,d,a),f=async()=>{let e=a.get(d);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=eF(e.device.id);if(!t.runnerSessionId){r?.alive&&(t.runnerSessionId=r.sessionId);return}if(!r?.alive){t.invalidatedReason??="iOS runner session exited during recording";return}r.sessionId!==t.runnerSessionId&&(t.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(d,e));let u=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?oL(t,a):function(e,t,r){var a,i;let n=[],o=e4(t);if(void 0!==e.platform&&o&&(a=e4(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!e3(i):"apple"!==i||!e3(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of oO){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 oO)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new T("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oR).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=k();if(!t.ok){P({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=N({force:!0})??void 0;return{ok:!1,error:$(new T(E(t.error.code),t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return P({level:"info",phase:"request_success"}),N(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let s=(a=e,i=t,n=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||n.some(e=>e?.field==="path")||"string"!=typeof i.path||n.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:o.basename(a.meta?.clientArtifactPaths?.path??i.path)}),n.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(u,e,n);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||u.meta?.lockPolicy||o2.has(l)||function(e,t){let r=oL(e,t);if(0!==r.length){var a;let t,i,n;throw new T("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oR).join(", ")}. Use a different --session name or close this session first.`)}}(e,u.flags);let f=await o6({req:u,sessionName:d,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...o5(t,e,r,i),surface:a.get(d)?.surface})});if(f)return c(f);let p=a.get(d);if(!p)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await o7({req:u,session:p,sessionName:d,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await ey(o4,c,f)}catch(r){P({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=k(),t=N({force:!0})??void 0;return{ok:!1,error:$(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:sl,token:sh,sessionStore:sf,leaseRegistry:sp,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{ry(t)},9e5);return r.unref(),rw.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){i.existsSync(e)||i.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return i.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=sr(t);if(o?.pid&&o.pid!==process.pid&&R(o.pid,o.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(sn,ss,{pid:process.pid,version:sm,startedAt:Date.now(),processStartTime:sg})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===sd||"dual"===sd){let t=h.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))eV(e);P({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await eT(),!(r<=0));)await G(200)}catch(e){P({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:r}})}})()}};e.setEncoding("utf8"),e.on("close",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eC(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),ec(o),eE(o))throw ed();i=await sy(e)}catch(e){i={ok:!1,error:$(e)}}finally{r-=1,o&&(a.delete(o),eJ(o))}e.destroyed||e.write(`${JSON.stringify(i)}
|
|
35
|
+
`),n=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new T("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===sd||"dual"===sd){let e=await rV({handleRequest:sy,token:sh});r.push(e),t=await new Promise((t,r)=>{e.once("error",r),e.listen(0,"127.0.0.1",()=>{e.off("error",r);let a=e.address();"object"==typeof a&&a?.port?t(a.port):r(new T("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:sh,version:sm,codeSignature:sw,processStartTime:sg},i.existsSync(sn)||i.mkdirSync(sn,{recursive:!0}),i.writeFileSync(sl,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",i.writeFileSync(so,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:sn},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
|
|
36
36
|
`),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${t}
|
|
37
|
-
`)}catch(t){let e=
|
|
38
|
-
`),r))try{t.close(()=>{})}catch{}
|
|
39
|
-
`),s()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof T?t:
|
|
37
|
+
`)}catch(t){let e=C(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
|
|
38
|
+
`),r))try{t.close(()=>{})}catch{}st(so),sa(ss),process.exit(1);return}let n=!1,o=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},s=async()=>{if(!n){for(let e of(n=!0,await o(),sf.toArray()))sf.writeSessionLog(e);await ew(),st(so),sa(ss),process.exit(0)}};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof T?e:C(e);process.stderr.write(`Daemon error: ${t.message}
|
|
39
|
+
`),s()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof T?t:C(t);process.stderr.write(`Daemon error: ${r.message}
|
|
40
40
|
`),s()})}();
|