agent-device 0.14.1 → 0.14.3

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.
@@ -0,0 +1 @@
1
+ import t from"node:crypto";import e from"node:fs";import r from"node:path";import{findProjectRoot as n}from"./3675.js";let o=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,l=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,i=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function s(){let t=process.argv[1];return t?u(t):"unknown"}function u(s,c=n()){try{let n=r.resolve(c),u=[r.resolve(s)],m=new Set,p=[];for(;u.length>0;){let t=u.pop();if(!t||m.has(t))continue;m.add(t);let s=e.statSync(t);if(!s.isFile())continue;let c=r.relative(n,t)||t;p.push(`${c}:${s.size}:${Math.trunc(s.mtimeMs)}`);let d=e.readFileSync(t,"utf8");for(let e of function(t){let e=new Set;return f(t,o,e),f(t,l,e),[...e]}(d)){let n=function(t,e){let n=r.resolve(r.dirname(t),e),o=a(n);if(o)return o;for(let t of i){let e=a(`${n}${t}`);if(e)return e}for(let t of i){let e=a(r.join(n,`index${t}`));if(e)return e}return null}(t,e);n&&u.push(n)}}let d=p.sort().join("|"),h=t.createHash("sha1").update(d).digest("hex");return`graph:${p.length}:${h}`}catch{return"unknown"}}function f(t,e,r){e.lastIndex=0;let n=null;for(;null!==(n=e.exec(t));){let t=n[1]?.trim();t?.startsWith(".")&&r.add(t)}}function a(t){try{return e.statSync(t).isFile()?t:null}catch{return null}}export{u as computeDaemonCodeSignature,s as resolveDaemonCodeSignature};
@@ -0,0 +1 @@
1
+ import e from"node:fs";import t from"node:path";import{fileURLToPath as a}from"node:url";import{resolveUserPath as n,expandUserHomePath as i}from"./3267.js";function r(){try{let a=o();return JSON.parse(e.readFileSync(t.join(a,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function o(){let n=t.dirname(a(import.meta.url)),i=n;for(let a=0;a<6;a+=1){let a=t.join(i,"package.json");if(e.existsSync(a))return i;i=t.dirname(i)}return n}function d(e){let a,r=(a=(e??"").trim())?n(a):t.join(i("~"),".agent-device");return{baseDir:r,infoPath:t.join(r,"daemon.json"),lockPath:t.join(r,"daemon.lock"),logPath:t.join(r,"daemon.log"),sessionsDir:t.join(r,"sessions")}}function s(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function l(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function u(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function p(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function c(e){return e?{message:e}:{}}function m(e,t){return t?{...e,message:t}:e}function f(e){return"string"==typeof e?.message&&e.message.length>0?e.message:null}function I(e){let t=e.appId??e.bundleId??e.packageName;return{session:e.session,appId:t,appBundleId:e.bundleId,package:e.packageName}}function g(e,t,a){return{deviceId:t,deviceName:a,..."android"===e?{serial:t}:"ios"===e?{udid:t}:{}}}function h(e,t={}){let a=t.includeAndroidSerial??!0;return{platform:e.platform,target:e.target,device:e.name,id:e.id,..."ios"===e.platform?{device_udid:e.ios?.udid??e.id,ios_simulator_device_set:e.ios?.simulatorSetPath??null}:{},..."android"===e.platform&&a?{serial:e.android?.serial??e.id}:{}}}function v(e){return{name:e.name,...h(e.device,{includeAndroidSerial:!1}),createdAt:e.createdAt}}function b(e){return{platform:e.platform,id:e.id,name:e.name,kind:e.kind,target:e.target,..."boolean"==typeof e.booted?{booted:e.booted}:{}}}function S(e){let t=e.created?"Created":"Reused",a=e.booted?" (booted)":"";return m({udid:e.udid,device:e.device,runtime:e.runtime,ios_simulator_device_set:e.iosSimulatorDeviceSet??null,created:e.created,booted:e.booted},`${t}: ${e.device} ${e.udid}${a}`)}function k(e){return e.bundleId??e.package??e.app}function N(e){return m({app:e.app,appPath:e.appPath,platform:e.platform,...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.package?{package:e.package}:{}},`Installed: ${k(e)}`)}function z(e){return e.appName??e.bundleId??e.packageName??e.launchTarget}function P(e){return m({launchTarget:e.launchTarget,...e.appName?{appName:e.appName}:{},...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.packageName?{package:e.packageName}:{},...e.installablePath?{installablePath:e.installablePath}:{},...e.archivePath?{archivePath:e.archivePath}:{},...e.materializationId?{materializationId:e.materializationId}:{},...e.materializationExpiresAt?{materializationExpiresAt:e.materializationExpiresAt}:{}},`Installed: ${z(e)}`)}function _(e){let t=e.appName??e.appBundleId??e.session;return m({session:e.session,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.startup?{startup:e.startup}:{},...e.runtime?{runtime:e.runtime}:{},...e.device?h(e.device):{}},t?`Opened: ${t}`:"Opened")}function j(e){return{session:e.session,...e.shutdown?{shutdown:e.shutdown}:{},...c(e.session?`Closed: ${e.session}`:"Closed")}}function w(e){return{nodes:e.nodes,truncated:e.truncated,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.visibility?{visibility:e.visibility}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}export{I as buildAppIdentifiers,g as buildDeviceIdentifiers,o as findProjectRoot,p as normalizeTenantId,f as readCommandMessage,r as readVersion,d as resolveDaemonPaths,s as resolveDaemonServerMode,l as resolveDaemonTransportPreference,k as resolveDeployResultTarget,z as resolveInstallFromSourceResultTarget,u as resolveSessionIsolationMode,j as serializeCloseResult,N as serializeDeployResult,b as serializeDevice,S as serializeEnsureSimulatorResult,P as serializeInstallFromSourceResult,_ as serializeOpenResult,v as serializeSessionListEntry,w as serializeSnapshotResult,c as successText,m as withSuccessText};
@@ -0,0 +1,37 @@
1
+ let e,t,r;import a from"node:path";import i,{promises as n}from"node:fs";import o from"node:crypto";import s from"node:fs/promises";import l from"node:os";import{spawn as u}from"node:child_process";import{fileURLToPath as d}from"node:url";import{setTimeout as c}from"node:timers/promises";import{PNG as f}from"pngjs";import{resolveUserPath as p}from"./3267.js";import{withDiagnosticsScope as m,flushDiagnosticsToSessionFile as h,getDiagnosticsMeta as g,emitDiagnostic as w}from"./7599.js";import{toAppErrorCode as v,asAppError as y,normalizeError as S,AppError as I}from"./9152.js";import{sleep as A,resolveTimeoutMs as b}from"./4829.js";import{listIosDeviceProcesses as _,IOS_RUNNER_CONTAINER_BUNDLE_IDS as N,resolveAppleSimulatorSetPathForSelector as M,buildSimctlArgs as x,dispatchCommand as k,refSnapshotFlagGuardResponse as D,buttonTag as P,handleSnapshotCommands as L,withTargetDeviceResolutionScope as R,shutdownSimulator as O,stopIosRunnerSession as C,localCommandPolicy as $,getClickButtonValidationError as E,createRequestCanceledError as F,isNavigationSensitiveAction as T,registerRequestAbort as U,errorResponse as V,resolveIosDevicectlHint as j,snapshotAndroid as G,resolveTargetDevice as q,withKeyedLock as B,setSessionSnapshot as H,dispatchGetViaRuntime as K,assertAndroidPressStayedInApp as z,runMacOsAlertAction as W,createAgentDevice as Z,getAndroidScreenSize as J,readTextForNode as Y,captureSnapshot as X,dispatchIsViaRuntime as Q,resolveClickButton as ee,IOS_DEVICECTL_DEFAULT_HINT as et,buildSnapshotState as er,context_contextFromFlags as ea,captureSnapshotData as ei,isRequestCanceled as en,resolveRequestTrackingId as eo,resolvePayloadInput as es,getRunnerSessionSnapshot as el,createUnsupportedArtifactAdapter as eu,isAndroidEscapeError as ed,markRequestCanceled as ec,dispatchFindReadOnlyViaRuntime as ef,runIosRunnerCommand as ep,ensureDeviceReady as em,readInfoPlistString as eh,clearRequestCanceled as eg,buildSimctlArgsForDevice as ew,getActiveAndroidSnapshotFreshness as ev,parseXmlDocumentSync as ey,resolveFrontmostMacOsApp as eS,IOS_SIMCTL_LIST_TIMEOUT_MS as eI,matchesPlatformSelector as eA,isCommandSupportedOnDevice as eb,listIosDeviceApps as e_,isApplePlatform as eN,parseSessionSurface as eM,normalizePlatformSelector as ex,getRequestSignal as ek,decodePng as eD,buildScrollGesturePlan as eP,markAndroidSnapshotFreshness as eL}from"./2007.js";import{resolveSessionIsolationMode as eR,resolveInstallFromSourceResultTarget as eO,successText as eC,withSuccessText as e$,resolveDeployResultTarget as eE,normalizeTenantId as eF}from"./3675.js";import{runCmdBackground as eT,runCmd as eU}from"./9818.js";import{trimRuntimeValue as eV,readProcessCommand as ej,resolveRuntimeTransportHints as eG,readProcessStartTime as eq}from"./8656.js";import{withAndroidAdbProvider as eB,resolveIosSimulatorDeviceSetPath as eH,classifyAndroidAppTarget as eK,resolveIosDeviceDeepLinkBundleId as ez,spawnAndroidAdbBySerial as eW,parseSerialAllowlist as eZ,getAndroidAppState as eJ,adb_adbArgs as eY,isDeepLinkTarget as eX,resolveAndroidSerialAllowlist as eQ,openAndroidApp as e0,formatAndroidInstalledPackageRequiredMessage as e1,resolveAndroidAdbExecutor as e2}from"./6953.js";import{runBatch as e5,mergeParentFlags as e3}from"./1231.js";import{splitSelectorFromArgs as e8,findNearestHittableAncestor as e4,extractNodeText as e6,splitIsSelectorArgs as e9,tryParseSelectorChain as e7,resolveSelectorChain as te,resolveRefLabel as tt,buildSelectorChainForNode as tr,normalizeType as ta,pruneGroupNodes as ti}from"./940.js";import{attachRefs as tn,centerOfRect as to}from"./4057.js";import{findBestMatchesByLocator as ts,parseFindArgs as tl}from"./7556.js";function tu(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 td(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tc=/^-?\d+(\.\d+)?$/,tf=/^[^\s"\\]+$/,tp=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tm=new Map([["--count","count"],["--pause-ms","pauseMs"]]),th=new Map([["--delay-ms","delayMs"]]);function tg(e){return"click"===e||"press"===e}function tw(e){return"type"===e||"fill"===e}function tv(e){return tS(e,tI)}function ty(e){return JSON.stringify(e)}function tS(e,t){return t(e)?e:ty(e)}function tI(e){return tA(e)&&e.startsWith("@")||tc.test(e)}function tA(e){return tf.test(e)}function tb(e,t){let r=t.flags??{};if(tg(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}tw(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function t_(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",tS(t.metroHost,tA)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tS(t.bundleUrl,tA)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tS(t.launchUrl,tA)))}function tN(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tS(r,tA)),a))e.push(tv(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 tM(e,t){let r=[],a={},i=tg(e)?tp:"swipe"===e?tm:tw(e)?th:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(tg(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(tg(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=tk(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 tx(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=tk(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 tk(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tD(e,t){for(let r of t.positionals??[])e.push(tv(r));t.flags?.relaunch&&e.push("--relaunch"),t_(e,t.runtime)}class tP{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=tP.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 tL)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),w({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=a.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let n=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=${ty(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(tg(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tv(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tv(a)),tb(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tv(r)),tb(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tv(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tv(a)),e.positionals.length>1&&t.push(tv(i)),tb(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tv(r)),t.push(tv(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tv(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",tv(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tv(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 tD(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tS(r,tA)),t_(t,e.flags),t.join(" ")}if("record"===e.command)return tN(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tv(r));return tb(t,e),t.join(" ")}(i));return`${r.join("\n")}
2
+ `}(e,this.buildOptimizedActions(e));i.writeFileSync(t,n)}catch{}}defaultTracePath(e){let t=tP.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return a.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return a.join(this.sessionsDir,tP.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return a.join(this.sessionsDir,tP.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return p(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tP.expandHome(e.saveScriptPath);i.existsSync(this.sessionsDir)||i.mkdirSync(this.sessionsDir,{recursive:!0});let t=tP.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return a.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&&(tg(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(tg(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=tu(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(tg(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 tL=["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"],tR=b(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),tO=new Map;async function tC(e){let t=await s.mkdtemp(a.join(l.tmpdir(),"agent-device-materialized-"));try{let r=await tF(e.installablePath,a.join(t,"installable")),i=e.archivePath?await tF(e.archivePath,a.join(t,"archive")):void 0,n=o.randomUUID(),s=e.ttlMs??tR,l=Date.now()+s,u=setTimeout(()=>{t$(n)},s);return tO.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 s.rm(t,{recursive:!0,force:!0}),e}}async function t$(e,t){let r=tO.get(e);if(!r)throw new I("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new I("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),tO.delete(e),await s.rm(r.rootPath,{recursive:!0,force:!0})}async function tE(e){let t=Array.from(tO.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await t$(e)}))}async function tF(e,t){let r=await s.stat(e);await s.mkdir(t,{recursive:!0});let i=a.join(t,a.basename(e));return r.isDirectory()?await s.cp(e,i,{recursive:!0}):await s.copyFile(e,i),i}let tT=new Map;function tU(e){let t=o.randomUUID(),r=setTimeout(()=>{tj(t)},9e5);return r.unref(),tT.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}function tV(e,t){let r=tT.get(e);if(!r)throw new I("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new I("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw tj(e),new I("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}function tj(e){let t=tT.get(e);if(t&&(clearTimeout(t.timer),tT.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let tG=new Map;function tq(e){let t=o.randomUUID(),r=setTimeout(()=>{tH(t)},3e5);return r.unref(),tG.set(t,{artifactPath:e.artifactPath,tempDir:e.tempDir,tenantId:e.tenantId,timer:r}),t}function tB(e,t){let r=tG.get(e);if(!r)throw new I("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new I("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function tH(e){let t=tG.get(e);t&&(clearTimeout(t.timer),tG.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function tK(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 I("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await em(e.session.device),e.session.device}if(!r)throw new I("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await q(e.flags??{});return await em(a),a}async function tz(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 I("INVALID_ARGS","install_from_source requires a source payload");switch(t.kind){case"url":if(!t.url||0===t.url.trim().length)throw new I("INVALID_ARGS","install_from_source url source requires a non-empty url");return t;case"path":if(!t.path||0===t.path.trim().length)throw new I("INVALID_ARGS","install_from_source path source requires a non-empty path");return t;case"github-actions-artifact":throw new I("UNSUPPORTED_OPERATION","install_from_source github-actions-artifact sources require a compatible remote daemon");default:throw new I("UNSUPPORTED_OPERATION",`install_from_source ${String(t.kind)} sources require a compatible remote daemon`)}}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:tB(o,t.meta?.tenantId)},cleanup:()=>{tH(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 I("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),u=await tK({session:i,flags:t.flags});if(!eb("install",u))return V("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let d=ek(t.meta?.requestId);if("ios"===u.platform){let e,{installIosInstallablePath:n}=await import("./2007.js"),{prepareIosInstallArtifact:o}=await import("./2007.js"),c=await o(s.source,{signal:d});try{if(l.enabled&&(e=await tC({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 I("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=e$(o,tW(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await t$(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./6953.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./2007.js"),p=await c(s.source,{signal:d});try{l.enabled&&(e=await tC({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 I("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./2007.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=e$(d,tW(d));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await t$(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:S(e)}}}function tW(e){return`Installed: ${eO(e)}`}async function tZ(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new I("INVALID_ARGS","release_materialized_paths requires a materializationId");return await t$(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:S(e)}}}let tJ=b(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),tY=b(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function tX(e,t,r){return t||tQ(r)?null:V("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function tQ(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function t0(e){return"ios"===e.platform&&"simulator"===e.kind}async function t1(e,t){t0(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function t2(e){let t=tQ(e.flags)||!e.session?await q(e.flags??{}):await t5(e.session.device);return!1!==e.ensureReady&&await em(t),t}async function t5(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 q(t)}catch(e){if(!(e instanceof I)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await q({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function t3(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 t8="shared_prefs/ReactNativeDevPrefs.xml",t4="debug_http_host",t6="dev_server_https",t9="RCT_jsLocation",t7="RCT_packager_scheme",re="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",rt='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function rr(e){return void 0!==eG(e)}async function ra(e){let{device:t,appId:r,runtime:a}=e;if(!r)return;let i=eG(a);if(i){if("android"===t.platform)return void await rn(t,r,i);"ios"===t.platform&&"simulator"===t.kind&&await ru(t,r,i)}}async function ri(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await ro(t,r);"ios"===t.platform&&"simulator"===t.kind&&await rd(t,r)}}async function rn(e,t,r){var a,i,n,o,s,l;let u,d;rm(t);let c=(a=await rs(e,t),i=t4,n=`${r.host}:${r.port}`,u=` <string name="${rh(i)}">${rh(n)}</string>`,rf(rp(a,i),u));o=c,s=t6,l="https"===r.scheme,d=` <boolean name="${rh(s)}" value="${l?"true":"false"}" />`,c=rf(rp(o,s),d),await rl(e,t,c)}async function ro(e,t){rm(t);let r=await rs(e,t),a=rp(r,t4),i=rp(a,t6);i!==r&&await rl(e,t,i)}async function rs(e,t){let r=await eU("adb",eY(e,["shell","run-as",t,"cat",t8]),{allowFailure:!0});return 0!==r.exitCode?rt:rc(r.stdout)}async function rl(e,t,r){let a=eY(e,["shell","run-as",t,"id"]),i=await eU("adb",a,{allowFailure:!0});if(0!==i.exitCode){let e=rg(i.stdout,i.stderr);throw new I("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:a,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:e?re:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await eU("adb",eY(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await eU("adb",eY(e,["shell","run-as",t,"tee",t8]),{stdin:r.trimEnd()})}catch(a){let e=y(a);if("TOOL_MISSING"===e.code)throw e;let r=rg("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new I("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?re:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function ru(e,t,r){await eU("xcrun",ew(e,["spawn",e.id,"defaults","write",t,t9,"-string",`${r.host}:${r.port}`])),await eU("xcrun",ew(e,["spawn",e.id,"defaults","write",t,t7,"-string",r.scheme]))}async function rd(e,t){await eU("xcrun",ew(e,["spawn",e.id,"defaults","delete",t,t9]),{allowFailure:!0}),await eU("xcrun",ew(e,["spawn",e.id,"defaults","delete",t,t7]),{allowFailure:!0})}function rc(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
3
+ `:rt}function rf(e,t){return rc(e).replace("</map>",`${t}
4
+ </map>`)}function rp(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return rc(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function rm(e){if("binary"!==eK(e))return;let t=e1(e);throw new I("INVALID_ARGS",t,{package:e,hint:t})}function rh(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function rg(e,t){let r=`${e}
5
+ ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}let rw=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function rv(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ry(e,t){if(void 0!==e){if("string"!=typeof e)throw new I("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return eV(e)}}function rS(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new I("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function rI(e){if("ios"===e||"android"===e)return e}async function rA(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!rr(r)||rr(a)||await ri({device:i.device,appId:i.appBundleId})}async function rb(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 V("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){rr(l)&&s?.appBundleId&&await ri({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=rI(ex(a.flags?.platform)??l?.platform??s?.device.platform);if(!u)return V("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 V("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:eV(t?.metroHost),metroPort:rS(t?.metroPort),bundleUrl:eV(t?.bundleUrl),launchUrl:eV(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===rv(d)?V("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 r_="open-command-roundtrip",rN="Not implemented for this platform in this release.",rM=new Set(["app","desktop","frontmost-app"]);async function rx(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eS();return{appBundleId:t.bundleId,appName:t.appName}}function rk(e){return Math.round(10*e)/10}function rD(e){return Math.round(10*e)/10}let rP="adb-shell-dumpsys-gfxinfo-framestats";function rL(e,t,r){let a=t.get(r);if(void 0===a)return null;let i=Number(e[a]);return Number.isFinite(i)?i:null}function rR(e){return 0===e.length?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function rO(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function rC(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`^\\s*${r}:\\s*([0-9][0-9,]*)`,"im"));if(a)return r$(a[1])??void 0}function r$(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}async function rE(e,t,r={}){var a,i,n,o,s,l,u,d;let c=e2(e,r.adb);try{let u,d,f,p,m,h,g,w,v,y,S,A=(a=(await c(["shell","dumpsys","gfxinfo",t,"framestats"],{timeoutMs:15e3})).stdout,i=new Date().toISOString(),function(e,t){if(/no process found for:/i.test(e))throw new I("COMMAND_FAILED",`Android gfxinfo did not find a running process for ${t}`,{metric:"fps",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect."})}(a,t),f=function(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??"",r=rC(t,"Total frames rendered"),a=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(void 0===r||!a)return;let i=r$(a[1])??void 0,n=Number(a[2]);if(void 0===i||!Number.isFinite(n)||r<0)return;let o=rC(t,"Uptime"),s=rC(t,"Stats since");return{droppedFramePercent:rk(n),droppedFrameCount:i,totalFrameCount:r,sampleWindowMs:function(e){let{uptimeMs:t,statsSinceNs:r}=e;if(void 0===t||void 0===r)return;let a=t-Math.round(r/1e6);return a>=0?a:void 0}({uptimeMs:o,statsSinceNs:s}),uptimeMs:o,statsSinceNs:s}}(a),p=function(e){let t=[],r=null;for(let i of e.split("\n")){var a;let e=i.trim();if(0===e.length||"---PROFILEDATA---"===e)continue;let n=e.split(",").map(e=>e.trim());if((a=n).includes("IntendedVsync")&&a.includes("FrameCompleted")){r=new Map(n.map((e,t)=>[e,t]));continue}let o=function(e,t){if(!t||e.length<t.size)return;let r=rL(e,t,"Flags"),a=rL(e,t,"IntendedVsync"),i=rL(e,t,"FrameCompleted");if(0===r&&null!==a&&null!==i&&!(a<=0)&&!(i<=a))return{intendedVsyncNs:a,frameCompletedNs:i,durationNs:i-a}}(n,r);o&&t.push(o)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}(a),m=function(e,t,r){let a=function(e){var t;let r=(t=e.map(e=>e.intendedVsyncNs),[...new Set(t.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)),a=[];for(let e=1;e<r.length;e+=1){let t=r[e]-r[e-1];t>=4e6&&t<=5e7&&a.push(t)}if(0!==a.length){let e,t;return e=[...a].sort((e,t)=>e-t),t=Math.floor(e.length/2),e.length%2==1?e[t]:(e[t-1]+e[t])/2}}(e);if(t||0!==e.length||function(e){throw new I("COMMAND_FAILED",`Failed to parse Android framestats output for ${e}`,{metric:"fps",package:e,hint:"Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging."})}(r),t||void 0!==a)return a;throw new I("COMMAND_FAILED",`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:"fps",package:r,hint:"Retry perf after a longer interaction window so consecutive Android frame timestamps are available."})}(p,f,t),h=Date.parse(i),g=function(e){let{frames:t,measuredAtMs:r,summary:a}=e,i=rR(t),n=a?.statsSinceNs,o=n??i.firstFrameNs,s=rO(o,i.lastFrameNs),l=a?.sampleWindowMs??s;if(!Number.isFinite(r)||a?.uptimeMs===void 0||void 0===o)return{sampleWindowMs:l,windowStartNs:o};let u=r-a.uptimeMs;return{sampleWindowMs:l,windowStartNs:o,windowStartedAt:new Date(u+o/1e6).toISOString(),windowEndedAt:function(e){let{deviceBootWallClockMs:t,measuredAtMs:r,summaryStartNs:a,lastFrameNs:i}=e;return void 0!==a?new Date(r).toISOString():void 0===i?void 0:new Date(t+i/1e6).toISOString()}({deviceBootWallClockMs:u,measuredAtMs:r,summaryStartNs:n,lastFrameNs:i.lastFrameNs}),timestampSource:"estimated-from-device-uptime"}}({frames:p,measuredAtMs:h,summary:f}),w=function(e){let{frames:t,frameDeadlineNs:r,summaryDroppedFrameCount:a}=e;return void 0!==a?a<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,a).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs):void 0===r?[]:t.filter(e=>e.durationNs>r)}({frames:p,frameDeadlineNs:m,summaryDroppedFrameCount:f?.droppedFrameCount}),v=f?.sampleWindowMs??g.sampleWindowMs??function(e){if(0===e.length)return;let t=rR(e);return rO(t.firstFrameNs,t.lastFrameNs)}(p),n=f,o=p,s=w,u=n?.totalFrameCount??o.length,d=n?.droppedFrameCount??s.length,y={totalFrameCount:u,droppedFrameCount:d,droppedFramePercent:n?.droppedFramePercent??(u>0?rk(d/u*100):0)},S=function(e){let{droppedFrames:t,timing:r,measuredAtMs:a,summary:i}=e;if(0===t.length)return;let n=function(e){let{frames:t,windowStartNs:r,measuredAtMs:a,uptimeMs:i}=e;if(0===t.length||void 0===r)return[];let n=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}n.push(o),o=[e]}return o.length>0&&n.push(o),n.map(e=>(function(e){let{frames:t,windowStartNs:r,measuredAtMs:a,uptimeMs:i}=e,n=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((n-r)/1e6)),l=Math.max(s,Math.round((o-r)/1e6)),u=void 0!==i&&Number.isFinite(a)?a-i:void 0;return{startOffsetMs:s,endOffsetMs:l,startAt:void 0===u?void 0:new Date(u+n/1e6).toISOString(),endAt:void 0===u?void 0:new Date(u+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:rD(Math.max(...t.map(e=>e.durationNs))/1e6)}})({frames:e,windowStartNs:r,measuredAtMs:a,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}({frames:t,windowStartNs:r.windowStartNs,measuredAtMs:a,uptimeMs:i?.uptimeMs});return n.length>0?n:void 0}({droppedFrames:w,timing:g,measuredAtMs:h,summary:f}),{...y,sampleWindowMs:v,...(l=m,{frameDeadlineMs:void 0===l?void 0:rD(l/1e6),refreshRateHz:void 0===l?void 0:rD(1e9/l)}),windowStartedAt:g.windowStartedAt,windowEndedAt:g.windowEndedAt,timestampSource:g.timestampSource,measuredAt:i,method:rP,source:f?"android-gfxinfo-summary":"framestats-rows",worstWindows:S&&S.length>0?S:void 0});return await rF(e,t,r),A}catch(e){throw u=t,(d=e)instanceof I?new I(d.code,d.message,{...d.details??{},metric:"fps",package:u},d):new I("COMMAND_FAILED",`Failed to sample Android fps for ${u}`,{metric:"fps",package:u},d)}}async function rF(e,t,r={}){let a=e2(e,r.adb);try{await a(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let rT="adb-shell-dumpsys-cpuinfo",rU="adb-shell-dumpsys-meminfo";async function rV(e,t,r={}){let a=e2(e,r.adb);try{let e=await a(["shell","dumpsys","cpuinfo"],{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,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:rk(i),measuredAt:r,method:rT,matchedProcesses:[...a]}}(e.stdout,t,new Date().toISOString())}catch(e){throw rG("cpu",t,e)}}async function rj(e,t,r={}){let a=e2(e,r.adb);try{let e=await a(["shell","dumpsys","meminfo",t],{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new I("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=rq(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!==rB(e));if(!r)break;return rB(r)??void 0}}(e);if(void 0===a)throw new I("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:rq(e,"TOTAL RSS"),measuredAt:r,method:rU}}(e.stdout,t,new Date().toISOString())}catch(e){throw rG("memory",t,e)}}function rG(e,t,r){return r instanceof I?new I(r.code,r.message,{...r.details??{},metric:e,package:t},r):new I("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function rq(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return rB(a[1])??void 0}function rB(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}async function rH(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return eX(t)?"macos"===e.platform?void 0:"device"===e.kind?ez(r,t):void 0:await rK(e,t)}async function rK(e,t){try{let{resolveIosApp:r}=await import("./2007.js");return await r(e,t)}catch{return}}async function rz(e,t){if(!("android"!==e.platform||!t||eX(t)))try{let{resolveAndroidApp:r}=await import("./2007.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function rW(e,t,r){if(r||"android"!==e.platform||!t||!eX(t))return r;try{let{getAndroidAppState:t}=await import("./2007.js"),a=await t(e);return a.package?.trim()||r}catch{return r}}async function rZ(e,t,r,a){return await rH(e,t,r)??await a(e,t)??("android"===e.platform&&t&&eX(t)?r:void 0)}function rJ(e){return V("INVALID_ARGS",e)}function rY(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=eM(r);if(!rM.has(e))throw new I("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new I("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new I("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?eM(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new I("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return V(e instanceof I?e.code:"INVALID_ARGS",String(e.message))}}function rX(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&eX(r)?rJ("open --relaunch does not support URL targets."):"app"!==a?rJ("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===eK(r)?rJ(e1(r)):null:null}async function rQ(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await em(i);let{appBundleId:l,appName:u}=await r0({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 I("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!rw.includes(e));if(i)throw new I("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${rw.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new I("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new I("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:ry(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new I("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return rS(e)}}(t.metroPort),bundleUrl:ry(t.bundleUrl,"bundleUrl"),launchUrl:ry(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:rI(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=rI(i);if(a.platform&&r&&!n)throw new I("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 I("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&&rv(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=y(t);return V(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 rA({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:u,runtime:d.data.runtime}}}async function r0(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await rx(r);return{appBundleId:n.appBundleId??await rZ(t,a,i,rz),appName:n.appName??a}}let r1=new Map;async function r2(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await C(t.id),await k(t,"close",[r],a,i),await t1(t,tJ)}async function r5(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||eX(u)||await k(r,"open",[l],a.flags?.out,{...ea(i,a.flags,n,o)})}async function r3(e){var t,r,a,i;let{req:n,sessionName:o,sessionStore:s,logPath:l,device:u,openTarget:d,openPositionals:c,appName:f,surface:p,appBundleId:m,runtime:h,existingSession:g}=e,w=n.flags?.relaunch===!0,v=g?.trace?.outPath,y=m;if(w&&d){let e=y??d;await r2({device:u,closeTarget:e,outFlag:n.flags?.out,context:{...ea(l,n.flags,y??g?.appBundleId,v)}})}await ra({device:u,appId:y,runtime:h});let S=Date.now();await k(u,"open",c,n.flags?.out,{...ea(l,n.flags,y)}),await r5({runtime:h,device:u,req:n,logPath:l,appBundleId:y,traceLogPath:v,openPositionals:c}),y=await rW(u,d,y),"android"===u.platform&&y&&await rF(u,y);let I=d?(t=y,{durationMs:Math.max(0,Date.now()-S),measuredAt:new Date().toISOString(),method:r_,appTarget:d,appBundleId:t}):void 0;if(await t1(u,tY),en(n.meta?.requestId)){let e=F();return V(e.code,e.message,e.details)}g&&eL(g,"open",g.snapshot);let A=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:g,sessionName:o,device:u,surface:p,appBundleId:y,appName:f,saveScript:!!n.flags?.saveScript});void 0!==n.runtime&&(r=s,a=o,(i=h)&&(0===rv(i)?r.clearRuntimeHints(a):r.setRuntimeHints(a,i)));let b=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,...eC(`Opened: ${r??a??t}`)}}({sessionName:o,appName:f,appBundleId:y,surface:p,startup:I,device:u,runtime:h,runtimeHintCount:rv});return s.recordAction(A,{command:"open",positionals:c,flags:n.flags??{},runtime:void 0!==n.runtime?h:void 0,result:b}),s.set(o,A),{ok:!0,data:b}}async function r8(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return V("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=rY(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?rJ("open --relaunch requires an app name or an active session app."):rJ("Session already active. Close it first or pass a new --session name.");let u=rX({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(u)return u;let d=await t5(e.device),c=await rQ({req:t,sessionName:r,sessionStore:i,device:d,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await r3({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 rJ("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&eX(r)?rJ("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===eK(r)?rJ(e1(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await q(t.flags??{}),u=rY(l,t.flags?.surface,o);if("string"!=typeof u)return u;let d=rX({shouldRelaunch:n,openTarget:o,surface:u,device:l});return d||await B(r1,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return V("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await rQ({req:t,sessionName:r,sessionStore:i,device:l,surface:u,openTarget:o});return"response"===n.type?n.response:await r3({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})})}let r4="app-log.pid";function r6(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 r9(e,t){if(!e)return;let r=a.dirname(e);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let n={pid:t,startTime:eq(t)??void 0,command:ej(t)??void 0};i.writeFileSync(e,`${JSON.stringify(n)}
6
+ `)}function r7(e){if(e&&i.existsSync(e))try{i.unlinkSync(e)}catch{}}function ae(e){if(i.existsSync(e))for(let t of i.readdirSync(e,{withFileTypes:!0})){if(!t.isDirectory())continue;let r=a.join(e,t.name,r4);if(i.existsSync(r))try{let e=r6(i.readFileSync(r,"utf8"));if(e&&function(e){let t,r=eq(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=ej(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{r7(r)}}}async function at(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}function ar(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}
7
+ `)},flush:()=>{a&&(i(a),a="")}}}function aa(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 ai(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new I("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function an(e,t){let r=(await eU("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function ao(e,t){var r,a;let i;ai(t);let n=await an(e,t),o=await eU("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 as(e,t,r,a,i){let n,o,s="recovering",l=!1,u=(async()=>{try{for(;!l;){let u=await an(e,t);if(!u){s="recovering",await A(1e3);continue}let d=eW(e,["logcat","-v","time","--pid",u],{stdio:["ignore","pipe","pipe"]});n=d;let c=ar(r,{redactionPatterns:a});if(o=aa(d,r,{endStreamOnClose:!1,writer:c}),"number"==typeof d.pid&&(r9(i,d.pid),s="active"),await o,r7(i),n=void 0,o=void 0,l)break;s="recovering",await A(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),r7(i)}})();return{backend:"android",getState:()=>s,startedAt:Date.now(),wait:u,stop:async()=>{l=!0,n&&!n.killed&&n.kill("SIGINT"),o&&await at(o),n&&!n.killed&&n.kill("SIGKILL"),await at(u),r7(i)}}}function al(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function au(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=x(["spawn",t,"log","show","--style","compact","--info","--predicate",al(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 eU("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")}
8
+ `,recoveredLineCount:s.length}}async function ad(e,t,r,a,i,n){let o="active",s=u("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return x(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",al(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),l=ar(r,{redactionPatterns:a});"number"==typeof s.pid&&r9(n,s.pid);let d=aa(s,r,{endStreamOnClose:!0,writer:l}).then(e=>(0!==e.exitCode&&(o="failed"),r7(n),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:d,stop:async()=>{s.killed||s.kill("SIGINT"),await at(d),s.killed||s.kill("SIGKILL"),await at(d),r7(n)}}}async function ac(e,t,r,a){let i="active",n=u("log",["stream","--style","compact","--predicate",al(e)],{stdio:["ignore","pipe","pipe"]}),o=ar(t,{redactionPatterns:r});"number"==typeof n.pid&&r9(a,n.pid);let s=aa(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),r7(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:s,stop:async()=>{n.killed||n.kill("SIGINT"),await at(s),n.killed||n.kill("SIGKILL"),await at(s),r7(a)}}}async function af(e,t,r,a){let i="active",n=u("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=ar(t,{redactionPatterns:r});"number"==typeof n.pid&&r9(a,n.pid);let s=aa(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),r7(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:s,stop:async()=>{n.killed||n.kill("SIGINT"),await at(s),n.killed||n.kill("SIGKILL"),await at(s),r7(a)}}}let ap=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),am=/https?:\/\/[^\s"'<>\])]+/i,ah=[/\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 ag(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>av(e)));for(let e of t.entries){let t=av(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function aw(e,t){let r=ak(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=ak(t?.maxPayloadChars,2048,64,16384),o=ak(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=a_(s,["method","httpMethod"]),u=a_(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=ap.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=am.exec(o),h=u??m?.[0];if(!h)return null;let g=d??aS(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:aI(o),packetId:aA(o)??void 0,durationMs:ab(o)??void 0,raw:ax(o,n),line:r};if("android"===a&&function(e,t,r){let a=ay(t,r,5),i=e.packetId??a.map(e=>aA(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?ay(t,r,12).filter(e=>aA(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>aI(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>aS(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>ab(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 aM(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=ax(e,n))}if("body"===i||"all"===i){let e=aN(o,s,["requestBody","body","payload","request"]),t=aN(o,s,["responseBody","response"]);e&&(w.requestBody=ax(e,n)),t&&(w.responseBody=ax(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 av(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function ay(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 aS(e){for(let t of ah){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function aI(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 aA(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function ab(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 a_(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 aN(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return aM(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 aM(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ax(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function ak(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function aD(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 aP(e){let t=a.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:aD("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:aD("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function aL(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:v}=e,y="macos"===d.platform?"macos":"ios"===d.platform?"device"===d.kind?"ios-device":"ios-simulator":"android",S=(t={backend:y,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v},o=ak(t?.maxEntries,25,1,200),s=t?.include??"summary",l=ak(t?.maxPayloadChars,2048,64,16384),u=ak(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?aw(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}}),I=[],A=await aR({device:d,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await ao(d.id,c);if(e){let t=aw(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v});t.entries.length>0&&(S=ag(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"===d.platform&&"simulator"===d.kind&&c&&0===S.entries.length){let e=await aC({deviceId:d.id,appBundleId:c,startedAt:p,simulatorSetPath:d.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:v});e&&(e.dump.entries.length>0?(S=ag(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"===d.platform&&"simulator"===d.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=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:y,dump:S,notes:I}}async function aR(e){let{device:t,appBundleId:r,appLogPath:n,appLogState:o}=e;if("android"!==t.platform||!r)return null;if(void 0!==o&&"active"!==o)return{reason:"inactive"};if("active"!==o)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return r6(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}(a.join(a.dirname(n),r4));if(!s)return null;let l=await an(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function aO(e,t,r,a){aP(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 af(e.id,n,o,a):await ad(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return ai(t),await as(e.id,t,n,o,a);if("macos"===e.platform)return await ac(t,n,o,a);throw n.end(),new I("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function aC(e){let t=await au({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:aw(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 a$(e){await e.stop(),await at(e.wait)}async function aE(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 eU("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await eU("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 eU("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 eU("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await eU("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function aF(e){let t=a.dirname(e),r=a.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let n=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let o=e.slice(r.length+1);if(/^\d+$/.test(o))try{i.unlinkSync(a.join(t,e)),n+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:n}}async function aT(e){let t=await eU("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 aU(e){let{device:t,shutdownRequested:r}=e;if(r&&(t0(t)||"android"===t.platform&&"emulator"===t.kind))try{return t0(t)?await O(t):await aT(t)}catch(t){let e=S(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aV(e){if(await C(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await W("dismiss",t).catch(t=>{w({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aj(e,t){e.appLog&&await a$(e.appLog),eN(e.device.platform)&&await aV(e),await tE(t).catch(()=>{})}async function aG(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return V("SESSION_NOT_FOUND","No active session");n.appLog&&await a$(n.appLog),t.positionals&&t.positionals.length>0&&(eN(n.device.platform)&&await aV(n),await k(n.device,"close",t.positionals,t.flags?.out,{...ea(a,t.flags,n.appBundleId,n.trace?.outPath)}),await t1(n.device,tJ)),eN(n.device.platform)&&await aV(n),rr(i.getRuntimeHints(r))&&n.appBundleId&&await ri({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...eC(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await tE(r).catch(()=>{}),i.delete(r);let o=await aU({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:e$({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...eC(`Closed: ${r}`)}}}let aq={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./2007.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./2007.js");return await a(e,t,r)}},aB={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./2007.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("./2007.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aH(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},u=tX(r,s,l);if(u)return u;let d=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!d||!c)return V("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,a=f?tB(f,t.meta?.tenantId):tP.expandHome(c);if(!i.existsSync(a))return V("INVALID_ARGS",`App binary not found: ${a}`);let u=await t2({session:s,flags:l,ensureReady:!1});if(!eb(r,u))return V("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=e$(e,(p=e,`Installed: ${p.appName??eE(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&tH(f)}}async function aK(e,t,r){return await e5(e,t,r)}async function az(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:u}=e;if("darwin"!==process.platform)throw new I("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let d={simulatorSetPath:o??void 0};if(s){let e=await aW({deviceName:i,runtime:n,simctlOpts:d});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aZ({deviceName:i,runtime:n,simctlOpts:d})).udid,r=await aJ(t,d),a=!0)}else t=(await aZ({deviceName:i,runtime:n,simctlOpts:d})).udid,r=await aJ(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 aW(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await eU("xcrun",x(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:eI});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||aY(a).includes(aY(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 aZ(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await eU("xcrun",x(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new I("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 I("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aJ(e,t){let r=await eU("xcrun",x(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:eI});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 aY(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aX(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,i=eH(e.iosSimulatorDeviceSet);if(!r)return V("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await az({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:em});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=y(t);return V(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=eQ(t.flags?.androidDeviceAllowlist),a=ex(t.flags?.platform),i=M({simulatorSetPath:eH(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./6953.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./2007.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./6953.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./2007.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=y(t);return V(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=tX(t.command,e,i);if(n)return n;let o=await t2({session:e,flags:i,ensureReady:!0});if(!eb("apps",o))return V("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(eN(o.platform)){let{listIosApps:e}=await import("./2007.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("./2007.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 aQ(e){let{ensureAndroidEmulatorBooted:t}=await import("./6953.js");return await t(e)}let a0='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',a1='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function a2(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=ex(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return V("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=tX("appstate",i,n);if(s)return s;let l=eN(i?.device.platform)&&function(e,t){if(!t)return!1;if(!tQ(e))return!0;let r=ex(e?.platform);return!(r&&!eA(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 V("SESSION_NOT_FOUND",a0);if("macos"===o&&!l)return V("SESSION_NOT_FOUND",a1);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 V("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 t2({session:i,flags:n,ensureReady:!0});if("ios"===u.platform)return V("SESSION_NOT_FOUND",a0);if("macos"===u.platform)return V("SESSION_NOT_FOUND",a1);let{getAndroidAppState:d}=await import("./2007.js"),c=await d(u);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function a5(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=tX(t.command,i,n);if(o)return o;let s="android"===(ex(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return V("INVALID_ARGS","boot --headless is supported only for Android emulators.");let u=t3({flags:n,sessionDevice:i?.device}),d=s&&!!u,c=!1;try{e=await t2({session:i,flags:n,ensureReady:!1})}catch(r){let t=y(r);if(s&&l&&!u&&"DEVICE_NOT_FOUND"===t.code)return V("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 aQ({avdName:u,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return V("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return V("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=t3({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return V("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aQ({avdName:t,serial:n.serial,headless:!0})}await em(e)}else("android"!==e.platform||!0!==e.booted)&&await em(e);return eb("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:V("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await a2({req:t,sessionName:r,sessionStore:a}):null}let a3="ps-process-snapshot",a8="ps-process-snapshot",a4="xctrace-activity-monitor",a6="xctrace-activity-monitor";async function a9(e,t){if("ios"===e.platform&&"device"===e.kind)return await it(e,t);let r=await ie(e,t),i=await il(e,r);if(0===i.length)throw new I("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let n=new Date().toISOString(),o=td(i.map(e=>a.basename(iu(e.command))));return id({usagePercent:i.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:i.reduce((e,t)=>e+t.rssKb,0),measuredAt:n,matchedProcesses:o,cpuMethod:a3,memoryMethod:a8})}async function a7(e){let t=ey(e),r=ic(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new I("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 I("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=ic(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:ip(e),processName:ih(e)})}let r=im(t[i],d),a=(c=t[n],f=d,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:ih(c):null);null!==r&&Number.isFinite(r)&&a&&u.push({pid:r,processName:a,cpuTimeNs:im(t[o],d),residentMemoryBytes:im(t[s],d)})}return u}async function ie(e,t){let r="macos"===e.platform?await io(t):await is(e,t),i="macos"===e.platform?a.join(r,"Contents","Info.plist"):a.join(r,"Info.plist"),n=await eh(i,"CFBundleExecutable");if(!n)throw new I("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:n,executablePath:"macos"===e.platform?a.join(r,"Contents","MacOS",n):void 0}}async function it(e,t){let r=await ir(e,t),a=await ia(e,t),i=await ia(e,t),n=ii(await a7(a.xml),r,t,e),o=ii(await a7(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new I("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 I("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 id({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:a4,memoryMethod:a6})}async function ir(e,t){let r=(await e_(e,"all")).find(e=>e.bundleId===t);if(!r)throw new I("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new I("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await _(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new I("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function ia(e,t){let r=await n.mkdtemp(a.join(l.tmpdir(),"agent-device-ios-perf-")),i=a.join(r,"sample.trace"),o=a.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",i,"--quiet","--no-prompt"],a=await eU("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==a.exitCode)throw new I("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr,appBundleId:t,deviceId:e.id,hint:ig(a.stdout,a.stderr)});let l=["xctrace","export","--input",i,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",o],u=await eU("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==u.exitCode)throw new I("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:ig(u.stdout,u.stderr)});return{capturedAtMs:s,xml:await n.readFile(o,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function ii(e,t,r,i){let n=new Set(t.map(e=>e.pid)),o=new Set(t.map(e=>a.basename(d(e.executable)))),s=e.filter(e=>n.has(e.pid)||o.has(e.processName));if(0===s.length)throw new I("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:i.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let l=new Map;for(let e of s){let t=l.get(e.pid);if(!t){l.set(e.pid,e);continue}l.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:iw(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iw(t.residentMemoryBytes,e.residentMemoryBytes)})}let u=[...l.values()],c=u.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=u.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:c.length>0?c.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:td(u.map(e=>e.processName))}}async function io(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await eU("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new I("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 I("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function is(e,t){let r=ew(e,["get_app_container",e.id,t,"app"]),a=await eU("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new I("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 I("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function il(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:ew(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let a=e.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!a)continue;let i=Number(a[1]),n=Number(a[2]),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 eU("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,i;let n;return r=e.command,i=t,n=iu(r),!!(i.executablePath&&(n===i.executablePath||r.startsWith(`${i.executablePath} `)))||a.basename(n)===i.executableName})}function iu(e){let[t=""]=e.trim().split(/\s+/,1);return t}function id(e){return{cpu:{usagePercent:rk(e.usagePercent),measuredAt:e.measuredAt,method:e.cpuMethod,matchedProcesses:e.matchedProcesses},memory:{residentMemoryKb:Math.round(e.residentMemoryKb),measuredAt:e.measuredAt,method:e.memoryMethod,matchedProcesses:e.matchedProcesses}}}function ic(e,t){for(let r of e){if(t(r))return r;let e=ic(r.children,t);if(e)return e}}function ip(e){if(!e||e.children.some(e=>"sentinel"===e.name)||!e.text)return null;let t=Number(e.text);return Number.isFinite(t)?t:null}function im(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:ip(e):null}function ih(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function ig(e,t){let r=j(e,t);if(r)return r;let a=`${e}
9
+ ${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?et:a.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function iw(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function iv(e,t={}){var r,a,i;let n,o,s,l,u=(s=(o=(n=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===r_&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:r_,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}((r=e).actions)).at(-1))?{available:!0,lastDurationMs:o.durationMs,lastMeasuredAt:o.measuredAt,method:r_,sampleCount:n.length,samples:n}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:r_},{session:r.name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{startup:s,fps:{available:!1,reason:"Dropped-frame sampling is currently available only on Android."},memory:{available:!1,reason:rN},cpu:{available:!1,reason:rN}},sampling:{startup:{method:r_,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:rU,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:rT,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:rP,description:"Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.",unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}};var t=e.device;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:a4,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:a8,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:a3,description:`Recent CPU usage snapshot from ${r}`,unit:"percent"}}}(r)}});return"android"!==(a=e).device.platform&&"ios"!==a.device.platform&&"macos"!==a.device.platform||(e.appBundleId?"android"===e.device.platform?await iy(u,e,t):await iS(u,e):(i=u,l="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.",i.metrics.fps={available:!1,reason:l},i.metrics.memory={available:!1,reason:l},i.metrics.cpu={available:!1,reason:l})),u}async function iy(e,t,r){let a=await iI(t,r);e.metrics.memory=ib(a.memory),e.metrics.cpu=ib(a.cpu),e.metrics.fps=function(e,t){var r,a;let i,n;if(!0!==e.available)return e;let o=(r=t.actions,i=i_((a=e).windowStartedAt),n=i_(a.windowEndedAt)??i_(a.measuredAt),void 0===i||void 0===n?[]:r.filter(e=>e.ts>=i&&e.ts<=n).map(e=>({command:e.command,at:new Date(e.ts).toISOString(),offsetMs:Math.max(0,Math.round(e.ts-i)),target:function(e){let t=e.result;if(t)for(let e of["refLabel","ref","appName","appBundleId"]){let r=t[e];if("string"==typeof r&&r.length>0)return r}}(e)})).slice(-12));return 0===o.length?e:{...e,relatedActions:o}}(ib(a.fps),t)}async function iS(e,t){let r=await iA(t);e.metrics.memory=ib(r.memory),e.metrics.cpu=ib(r.cpu)}async function iI(e,t){let r=e.appBundleId,a={adb:t.androidAdb},[i,n,o]=await Promise.allSettled([rj(e.device,r,a),rV(e.device,r,a),rE(e.device,r,a)]);return{memory:i,cpu:n,fps:o}}async function iA(e){let t=e.appBundleId;try{let r=await a9(e.device,t);return{memory:{status:"fulfilled",value:r.memory},cpu:{status:"fulfilled",value:r.cpu}}}catch(e){return{memory:{status:"rejected",reason:e},cpu:{status:"rejected",reason:e}}}}function ib(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=S(e.reason);return{available:!1,reason:t.message,error:t}}function i_(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let iN=["path","start","stop","doctor","mark","clear"],iM=`logs requires ${iN.slice(0,-1).join(", ")}, or ${iN.at(-1)}`,ix=["dump","log"],ik=`network requires ${ix.join(" or ")}`,iD=["summary","headers","body","all"],iP=`network include mode must be one of: ${iD.join(", ")}`;async function iL(e){let{req:t}=e;return"perf"===t.command?iR(e):"logs"===t.command?iO(e):"network"===t.command?iT(e):null}async function iR(e){let{sessionName:t,sessionStore:r,androidAdbExecutor:a}=e,i=r.get(t);if(!i)return V("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await iv(i,{androidAdb:a})}}catch(e){return{ok:!1,error:S(e)}}}async function iO(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return V("SESSION_NOT_FOUND","logs requires an active session");if(!eb("logs",n.device))return V("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return iN.includes(o)?s&&"clear"!==o?V("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?iC(n,r,a):"mark"===o?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return aP(o),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
10
+ `,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?i$(n,r,a,s):"start"===o?iE(n,r,a):"stop"===o?iF(n,r,a):V("INVALID_ARGS",iM):V("INVALID_ARGS",iM)}async function iC(e,t,r){let a=r.resolveAppLogPath(t),i=await aE(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:i.checks,notes:i.notes}}}async function i$(e,t,r,a){if(e.appLog&&!a)return V("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return V("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:aF(i)};e.appLog&&await a$(e.appLog);let n=aF(i),o=r.resolveAppLogPidPath(t);try{let a=await aO(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:S(a)}}}async function iE(e,t,r){if(e.appLog)return V("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return V("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 aO(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:S(e)}}}async function iF(e,t,r){if(!e.appLog)return V("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await a$(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iT(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return V("SESSION_NOT_FOUND","network requires an active session");if(!eb("network",i.device))return V("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!ix.includes(n))return V("INVALID_ARGS",ik);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return V("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 V("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return iD.includes(a)?{ok:!0,include:a}:V("INVALID_ARGS",iP)}(t);if(!s.ok)return s;let{include:l}=s,u=await aL({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 iU=/^[A-Z_][A-Z0-9_]*$/,iV=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-((?:[^}\\]|\\.)*))?\}/g,ij="AD_VAR_";function iG(e){return e.startsWith("AD_")}function iq(e){return new I("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function iB(e,t,r){return e.replace(iV,(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 I("INVALID_ARGS",`Unresolved variable \${${i}} at ${r.file}:${r.line}.`)})}function iH(e,t,r){if(!e)return e;let a={...e};for(let[e,i]of Object.entries(a))"string"==typeof i&&(a[e]=iB(i,t,r));return a}let iK=new Set(["ios","android","macos","linux"]);function iz(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(iW(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 I("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let i=r.slice(0,a);if(!iU.test(i))throw new I("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 I("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 I("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 I("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&&iK.has(e)&&iZ(r,"platform",e)}let n=a.match(/(?:^|\s)timeout=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=1&&iZ(r,"timeoutMs",Math.floor(e))}let o=a.match(/(?:^|\s)retries=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=0&&iZ(r,"retries",Math.floor(e))}}return r}function iW(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function iZ(e,t,r){let a=e[t];if(void 0!==a)throw new I("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 iJ(e){return!!e&&!Number.isNaN(Number(e))}let iY=/[*?[\]{}]/;async function iX(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,artifactsDir:s,runReplay:l,cleanupSession:u}=e;U(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=y(e);return V(t.code,t.message)}).finally(()=>{eg(i)});try{return"number"==typeof n?await Promise.race([f,new Promise(e=>{t=setTimeout(()=>{c=!0,ec(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 iQ(f)||w({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await u(a)}catch(e){w({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:y(e).message}})}}}async function iQ(e){return await Promise.race([e.then(()=>!0),c(2e3).then(()=>!1)])}async function i0(e){let{req:t,sessionName:r,runReplay:n,cleanupSession:o}=e;if((t.positionals?.length??0)===0)return V("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:n}=e,o=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,n;let o=tP.expandHome(e,t);if(i.existsSync(o)){let t=i.statSync(o);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:o}).map(e=>a.join(o,e));if(t.isFile()){if(".ad"!==a.extname(o))throw new I("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[o]}return[]}if(r=e,!iY.test(r)&&(n=o,!iY.test(n)))throw new I("INVALID_ARGS",`test input not found: ${e}`);let s=a.isAbsolute(o)?o:e;return i.globSync(s,{cwd:a.isAbsolute(o)?void 0:t}).map(e=>a.isAbsolute(e)?e:a.resolve(t,e)).filter(e=>".ad"===a.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,o)))].map(e=>a.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var u,d;let t=iz(i.readFileSync(e,"utf8"));if(!n){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 ${n}`});continue}u=n,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=n?` for --platform ${n}`:"";throw new I("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),v=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),y=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:i}=e,n=tP.expandHome(t??".agent-device/test-artifacts",r);return a.join(n,i)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:v}),S=[],A=Date.now(),b=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}b+=1;let a=await i1({entry:e,sessionName:r,suiteInvocationId:v,caseIndex:b-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:y,runReplay:n,cleanupSession:o});if(S.push(a),t.flags?.failFast===!0)break}let _=(d=w.length,c=S,f=Date.now()-A,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:_}}catch(t){let e=y(t);return V(e.code,e.message)}}async function i1(e){var t,r;let n,o,{entry:s,sessionName:l,suiteInvocationId:u,caseIndex:d,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,v=Date.now(),y=a.join(h,(t=s.path,(0===(o=c?a.relative(c,t):a.basename(t)).length||o.startsWith("..")?a.basename(t):o).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,i,n=0){let o=a.basename(r,a.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${i+1}${o?`-${o}`:""}:attempt-${n+1}`}(l,u,s.path,d,e),o=a.join(y,`attempt-${I}`);r=s.path,i.mkdirSync(o,{recursive:!0}),i.copyFileSync(r,a.join(o,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:i,caseIndex:n,attemptIndex:o}=e;return eo(`${t??r}:test:${n+1}:${a.basename(i)}:attempt:${o+1}`,r)}({requestId:f,suiteInvocationId:u,filePath:s.path,caseIndex:d,attemptIndex:e}),h=await iX({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,artifactsDir:o,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:n,attempts:o,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=[],n=new Map;for(let o of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(o))continue;let e=function(e,t){let r=a.extname(e),i=r?e.slice(0,-r.length):e,n=t.get(e)??0;return(t.set(e,n+1),0===n)?e:`${i}-${n+1}${r}`}(a.basename(o),n),s=a.join(t,e);a.resolve(o)!==a.resolve(s)&&i.copyFileSync(o,s),r.push(s)}return r}(u,l),c=[`file: ${r}`,`session: ${n}`,`attempt: ${o}/${s}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");d.length>0&&c.push(`copiedArtifacts: ${d.map(e=>a.basename(e)).join(", ")}`);let f=a.join(l,"result.txt"),p=`${c.join("\n")}
11
+ `;i.writeFileSync(f,p),t.ok||i.writeFileSync(a.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:I,maxAttempts:p+1,attemptArtifactsDir:o}),n=h,S=t,h.ok)break}let A=Date.now()-v;if(n?.ok)return{file:s.path,session:S,status:"passed",durationMs:A,attempts:I,artifactsDir:y,replayed:"number"==typeof n.data?.replayed?n.data.replayed:0,healed:"number"==typeof n.data?.healed?n.data.healed:0};let b=n?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:n?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:S,status:"failed",durationMs:A,attempts:I,artifactsDir:y,error:b}}function i2(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=e8(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 i5(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(tg(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),tg(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}=e9(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=i2(e.positionals??[]);r&&t.push(r)}return td(t).filter(e=>e.trim().length>0)})(t).map(e=>e7(e)).filter(e=>null!==e);if(0===o.length)return null;let s=tg(t.command)||"fill"===t.command,l=tg(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await i3(n,t,a,s,i);for(let e of o){let r=te(u.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=tr(r.node,n.device.platform,{action:tg(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tg(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=tu(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}=e9(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}=i2(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function i3(e,t,r,a,i){let n=await k(e.device,"snapshot",[],t.flags?.out,{...ea(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:tn(t.flags?.snapshotRaw?o:ti(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return H(e,s),i.set(e.name,e),s}async function i8(e){let{req:t,sessionName:r,logPath:n,sessionStore:o,invoke:s}=e,l=t.positionals?.[0];if(!l)return V("INVALID_ARGS","replay requires a path");let u="",d=new Set;try{var c;let e;u=tP.expandHome(l,t.meta?.cwd);let f=i.readFileSync(u,"utf8"),p=f.trimStart()[0];if("{"===p||"["===p)return V("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let m=iz(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(iW(o)){if(i)throw new I("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 I("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=tx(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=tx(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(tg(a)){let e=tM(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 iJ(r)&&iJ(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tM(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=tM(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 I("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 V("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 V("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let v=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(iG(e))throw iq(e);t[e]=a}return{values:t}}({builtins:function(e){let{req:t,sessionName:r,metadata:i,resolvedPath:n}=e,o=t.flags??{},s=t.meta?.cwd??process.cwd(),l={AD_SESSION:r,AD_FILENAME:a.relative(s,n)||n},u=o.platform??i.platform;u&&(l.AD_PLATFORM=u);let d=o.device;"string"==typeof d&&d.length>0&&(l.AD_DEVICE=d);let c=o.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(ij))continue;let e=r.slice(ij.length);0!==e.length&&iU.test(e)&&(iG(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 I("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let a=r.slice(0,e);if(!iU.test(a))throw new I("INVALID_ARGS",`Invalid -e key "${a}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(iG(a))throw iq(a);t[a]=r.slice(e+1)}return t}((c=t,e=c.flags?.replayEnv,Array.isArray(e)?e.filter(e=>"string"==typeof e):[]))}),y=t.flags?.replayUpdate===!0,S=0;for(let e=0;e<g.length;e+=1){let a=g[e];if(!a||"replay"===a.command)continue;let i=await i4({req:t,sessionName:r,action:a,scope:v,filePath:u,line:w[e]??0,invoke:s});if(i.ok){i9(i).forEach(e=>d.add(e));continue}if(!y)return i6(i,a,e,u,[...d]);let l=await i5({action:a,sessionName:r,logPath:n,sessionStore:o});if(!l)return i6(i,a,e,u,[...d]);if(g[e]=l,!(i=await i4({req:t,sessionName:r,action:l,scope:v,filePath:u,line:w[e]??0,invoke:s})).ok)return i6(i,l,e,u,[...d]);i9(i).forEach(e=>d.add(e)),S+=1}return y&&S>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${ty(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",tv(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tD(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tS(r,tA));return t_(t,e.flags),t.join(" ")}if("record"===e.command)return tN(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tv(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(tv(r));return tb(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
12
+ `,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(u,g,o.get(r)),{ok:!0,data:{replayed:g.length,healed:S,session:r,artifactPaths:[...d]}}}catch(t){let e=y(t);return V(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function i4(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=>iB(e,o,t)),flags:iH(n.flags,o,t)??{},runtime:iH(n.runtime,o,t)});return await u({token:a.token,session:i,command:d.command,positionals:d.positionals??[],flags:(r=a.flags,e3(r,{...d.flags??{}})),runtime:d.runtime,meta:a.meta})}function i6(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=>tv(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 i9(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 i7(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await i8({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await i0({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 i8({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&&i9(t).forEach(e=>u.add(e)),t}})},cleanupSession:async e=>{i.get(e)&&await aG({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let ne=new Set(["session_list","ensure-simulator","devices","apps"]),nt=new Set(["boot","appstate"]),nr=new Set(["perf","logs","network"]),na=new Set(["replay","test"]);async function ni(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=tX(n,u,d);if(c)return c;let f=await t2({session:u,flags:d,ensureReady:!0});if(!eb(n,f))return V("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await k(f,n,o,t.flags?.out,{...ea(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 nn(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=tX("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return V("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await t2({session:n,flags:o,ensureReady:!0});if(!eb("clipboard",u))return V("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let d=await k(u,"clipboard",t.positionals??[],t.flags?.out,{...ea(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 no(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,androidAdbExecutor:o}=e;if(ne.has(t.command))return await aX({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await rb({req:t,sessionName:r,sessionStore:i});if(nt.has(t.command))return await a5({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await nn({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"!==ex((t.flags??{}).platform)?await ni({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):V("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(nr.has(t.command))return await iL({req:t,sessionName:r,sessionStore:i,androidAdbExecutor:o});if("install"===t.command||"reinstall"===t.command)return await aH({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?aB:aq});if("install_source"===t.command)return await tz({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await tZ({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await ni({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=es(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tP.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):V("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await ni({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 rZ(e.device,r,e.appBundleId,rz)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await r8({req:t,sessionName:r,logPath:a,sessionStore:i}):na.has(t.command)?await i7({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await aK(t,r,n):"close"===t.command?await aG({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function ns(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 V("INVALID_ARGS","find requires a locator or text");let{locator:l,query:u,action:d,value:c,timeoutMs:f}=tl(s);if(!u)return V("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return V("INVALID_ARGS","find accepts only one of --first or --last");let p=await ef({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 V("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await q(t.flags??{});m||await em(h);let g="role"!==l?u:void 0,w="click"===d||"focus"===d||"fill"===d||"type"===d,v=0,y=null,S=async()=>{let e=Date.now();if(y&&e-v<750&&!ev(m))return{nodes:y};let{snapshot:n}=await X({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return v=e,y=o,m&&(H(m,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:u};if("wait"===d)return nl(I,S,l,u,f);let{nodes:A}=await S(),b=ts(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,M;let e;return _=b.matches,N=l,M=u,e=_.slice(0,8).map(e=>{let t=e6(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),V("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${M}". Use a more specific locator or selector.`,{locator:N,query:M,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let x=b.matches[0]??null;if(!x)return V("COMMAND_FAILED","find did not match any element");let k="click"===d||"focus"===d||"fill"===d||"type"===d?e4(A,x)??x:x,D=`@${k.ref}`,P={node:x,resolvedNode:k,ref:D,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>nu(I),get_text:()=>nd(I,P),get_attrs:()=>nc(I,P),click:()=>nf(I,P),fill:()=>np(I,P,c),focus:()=>nm(I,P),type:()=>nh(I,P,c)}[d];return L?L():null}async function nl(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(ts(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 A(300)}return V("COMMAND_FAILED","find wait timed out")}async function nu(e){let{req:t,sessionStore:r,session:a,command:i}=e;return a&&r.recordAction(a,{command:i,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}}}async function nd(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await Y({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>ea(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 nc(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 nf(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?to(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 np(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return V("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 nm(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?to(t.node.rect):null;if(!l)return V("COMMAND_FAILED","matched element has no bounds");let u=await k(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...ea(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 nh(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return V("INVALID_ARGS","find type requires text");let u=t.node.rect?to(t.node.rect):null;if(!u)return V("COMMAND_FAILED","matched element has no bounds");await k(o,"focus",[String(u.x),String(u.y)],a.flags?.out,{...ea(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let d=await k(o,"type",[r],a.flags?.out,{...ea(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 ng=`
13
+ import Foundation
14
+ import AVFoundation
15
+
16
+ let url = URL(fileURLWithPath: CommandLine.arguments[1])
17
+ let asset = AVURLAsset(url: url)
18
+ let semaphore = DispatchSemaphore(value: 0)
19
+ var exitCode: Int32 = 1
20
+
21
+ Task {
22
+ defer { semaphore.signal() }
23
+ do {
24
+ let playable = try await asset.load(.isPlayable)
25
+ let duration = try await asset.load(.duration)
26
+ if playable && duration.isValid && !duration.isIndefinite && CMTimeGetSeconds(duration) > 0 {
27
+ exitCode = 0
28
+ }
29
+ } catch {
30
+ exitCode = 1
31
+ }
32
+ }
33
+
34
+ semaphore.wait()
35
+ exit(exitCode)
36
+ `.trim();async function nw(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 A(a)}}async function nv(e){try{var t,r;let a,i=await eU("swift",["-",e],{stdin:ng,allowFailure:!0,timeoutMs:1e4});if(0===i.exitCode)return!0;if(t=i.stderr,r=i.stdout,a=`${t}
37
+ ${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return nS(e);return!1}catch(t){if(t instanceof I&&"TOOL_MISSING"===t.code)return nS(e);throw t}}async function ny(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await nv(e))return;await A(r)}}function nS(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(a.push(o),1===n){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nI(e){let t=a.parse(e);return a.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nA(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nb(e){let t=a.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),a.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),a.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),a.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new I("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 n_(e){let{videoPath:t,scriptPath:r,scriptArgs:n,commandDescription:o}=e;await nw(t),await ny(t);let s=i.mkdtempSync(a.join(l.tmpdir(),"agent-device-record-overlay-")),u=a.join(s,`input${a.extname(t)||".mp4"}`),d=a.join(s,a.basename(t)),c=a.join(s,"home"),f=a.join(s,"module-cache");i.copyFileSync(t,u),i.mkdirSync(c,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await eU("xcrun",["swift",r,"--input",u,"--output",d,...n],{timeoutMs:12e4,env:{...process.env,HOME:c,CLANG_MODULE_CACHE_PATH:f}}),await ny(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof I?a:new I("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new I("COMMAND_FAILED",o,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function nN(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await n_({videoPath:r,scriptPath:t??=nb("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 n_({videoPath:r,scriptPath:e??=nb("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function nx(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await n_({videoPath:t,scriptPath:r??=nb("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function nk(e){return e instanceof Error?e.message:String(e)}function nD(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function nP(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=nI((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?nA(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)}]})):nA(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: ${nk(e)}`}}}async function nL(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 nR(e,t,r){for(let a=0;a<40;a+=1){if(!await nL(e,t,r))return!0;await A(250)}return!await nL(e,t,r)}async function nO(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 A(250)}}async function nC(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 nL(e,t,a))break;if(i+1>=2)return!0;await A(250)}return!1}async function n$(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=nD(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(w({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;w({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1}})}e<1&&await A(750)}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function nE(e){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: ${nD(i,"adb shell wm size")}`);return{width:nF(Number(n[1]),a),height:nF(Number(n[2]),a)}}function nF(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nT(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function nU(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return w({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 nL(e,t,r))&&await nR(e,t,r)}async function nV(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 nE({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return V("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: ${nD(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 nT(i,n.id,e);continue}if(w({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nC(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 nU(i,n.id,a),await nT(i,n.id,e)}return V("COMMAND_FAILED",s)}async function nj(e){let t,r,{deps:a,device:i,recording:n}=e;w({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(w({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 nL(a,i.id,n.remotePid)&&!await nU(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nD(o,"adb shell kill")}`):await nR(a,i.id,n.remotePid)||await nU(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nO(a,i.id,n.remotePath);let e=await n$({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),V("COMMAND_FAILED",e);await nP({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return V("COMMAND_FAILED",t);if(r)return V("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});w({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: ${nD(e,"adb shell rm")}`)}}function nG(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nq(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nB(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nG(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nq(t,i,r))}catch(e){w({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:nk(e)}})}}async function nH(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=nq(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,v;if(!nk(a).toLowerCase().includes("recording already in progress"))return V("COMMAND_FAILED",`failed to start recording: ${nk(a)}`);w({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:nk(a)}});let e=(g=o.id,v=i.name,n.toArray().find(e=>e.name!==v&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return V("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 V("COMMAND_FAILED",`failed to start recording: ${nk(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...d}}async function nK(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},nq(t,i,r))}catch(e){return V("COMMAND_FAILED",`failed to start recording: ${nk(e)}`)}return{platform:"macos-runner",...s}}async function nz(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nG(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nq(t,i,r))}catch(e){w({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nk(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of N)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 V("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 nP({recording:o,deps:n,trimStartMs:u,targetLabel:"iOS recording"}),null}async function nW(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nG(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nq(t,i,r))}catch(e){w({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nk(e)}})}return await nP({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nZ(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 A(250)}return Date.now()}async function nJ(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:u}=e;await nB({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:d,wait:c}=s.runCmdBackground("xcrun",ew(n,["io",n.id,"recordVideo",u]),{allowFailure:!0}),f=await nZ(u);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nG(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 nY(e){let t,{req:r,sessionName:n,sessionStore:o,activeSession:s,device:l,logPath:u,deps:d}=e;if(s.recording)return V("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 V("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return V("INVALID_ARGS","quality must be an integer between 5 and 10");if(!eb("record",l))return V("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tP.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(a.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nG(s);if(!e)return V("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nH({req:r,activeSession:s,sessionStore:o,device:l,logPath:u,deps:d,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nG(s);if(!e)return V("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nK({req:r,activeSession:s,device:l,logPath:u,deps:d,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await nJ({req:r,activeSession:s,device:l,logPath:u,deps:d,recordingBase:h,resolvedOut:m}):await nV({deps:d,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,o.set(n,s),o.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??p,showTouches:t.showTouches}})}async function nX(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nj({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;if(0!==i.exitCode)return V("COMMAND_FAILED",`failed to stop recording: ${nD(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: ${nk(e)}`}return await nP({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nQ(e){var t;let r,{req:i,activeSession:n,device:o,logPath:s,deps:l}=e;if(!n.recording)return V("INVALID_ARGS","no active recording");let u=n.recording,d=u.invalidatedReason;n.recording=void 0;let c="ios-device-runner"===u.platform?await nz({req:i,activeSession:n,device:o,logPath:s,deps:l,recording:u}):"macos-runner"===u.platform?await nW({req:i,activeSession:n,device:o,logPath:s,deps:l,recording:u}):await nX({deps:l,device:o,recording:u});return c||(d?V("COMMAND_FAILED",d):(r=[{field:"outPath",path:(t=u).outPath,localPath:t.clientOutPath,fileName:a.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nI(e.clientOutPath)}(t),fileName:a.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function n0(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:eU,runCmdBackground:eT,runIosRunnerCommand:ep,waitForStableFile:nw,isPlayableVideo:nv,trimRecordingStart:nN,resizeRecording:nx,overlayRecordingTouches:nM},o=a.get(r),s=o?.device??await q(t.flags??{});o||await em(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},u=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(u))return V("INVALID_ARGS","record requires start|stop");if("start"===u)return nY({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let d=await nQ({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 n1(e){let{req:t,sessionName:r,sessionStore:n,logPath:o}=e,s=t.command;if("record"===s)return n0({req:t,sessionName:r,sessionStore:n,logPath:o});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return V("INVALID_ARGS","trace requires start|stop");let o=n.get(r);if(!o)return V("SESSION_NOT_FOUND","No active session");if("start"===e){if(o.trace)return V("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??n.defaultTracePath(o),r=tP.expandHome(e);return i.mkdirSync(a.dirname(r),{recursive:!0}),i.appendFileSync(r,""),o.trace={outPath:r,startedAt:Date.now()},n.recordAction(o,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!o.trace)return V("INVALID_ARGS","no active trace");let l=o.trace.outPath;if(t.positionals?.[1]){let e=tP.expandHome(t.positionals[1]);i.mkdirSync(a.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return o.trace=void 0,n.recordAction(o,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function n2(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 n5=new WeakMap;function n3(e){if(!e)return;let t=n5.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)&&n8(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(n8);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 n5.set(e,r),r}function n8(e){return!!e&&e.width>0&&e.height>0}let n4={referenceWidth:1e3,referenceHeight:1e3};function n6(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=ot(p.effectiveDurationMs)??ot(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:ot(p.gestureStartUptimeMs),gestureEndUptimeMs:ot(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:ot(p.gestureStartUptimeMs),gestureEndUptimeMs:ot(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),v="ios"===e.device.platform&&void 0===ot(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=or(ot(t.count),1)??1,r=!0===t.doubleTap,a=or(ot(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 n2(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):n2(h),y=(l=e.snapshot,d=ot((u=p).referenceWidth),c=ot(u.referenceHeight),void 0!==d&&d>0&&void 0!==c&&c>0?{referenceWidth:d,referenceHeight:c}:n3(l)),S=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=oa(t,e);if(!i)return[];let{x:n,y:o}=i,s=or(ot(t.count),1)??1,l=or(ot(t.intervalMs),0)??0,u=!0===t.doubleTap,d=or(ot(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(n7(t,n,o,d,a));continue}c.push(n9(t,n,o,a)),u&&c.push(n9(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=oa(t,e);if(!i)return[];let{x:n,y:o}=i;return[n9(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=oa(t,e);if(!n)return[];let{x:o,y:s}=n;return[n7(r,o,s,on(a,[ot(t.durationMs),ot(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=oi(t,e),o=oe(t.contentDirection)??oe(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:u,y2:d}=n,c=on(a,[],250),f=ot(t.amount)??ot(e[1]),p=ot(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=oi(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:u}=n,d=on(a,[ot(t.effectiveDurationMs),ot(t.durationMs),ot(e[4])],250),c=or(ot(t.count),1)??1,f=or(ot(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=oa(t,e,1),o=ot(t.scale)??ot(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:on(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,v,g,y);0!==S.length&&(f.gestureEvents.push(...S),w({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:S.length,tMs:v,gestureDurationMs:g,kinds:S.map(e=>e.kind)}}))}function n9(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function n7(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function oe(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 ot(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 or(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function oa(e,t,r=0){let a=ot(e.x)??ot(t[r]),i=ot(e.y)??ot(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function oi(e,t){let r=ot(e.x1)??ot(t[0]),a=ot(e.y1)??ot(t[1]),i=ot(e.x2)??ot(t[2]),n=ot(e.y2)??ot(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 on(e,t,r){return or(e,1)??t.map(e=>or(e,1)).find(e=>void 0!==e)??r}function oo(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??{},...eC(c)}}function os(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}),T(a)&&eL(t,a,d??t.snapshot),n6(t,a,i,o,n??{},l,u),{ok:!0,data:s}}async function ol(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 J(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=n3(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=n3(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function ou(e){try{return await ol(e)}catch(t){w({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function od(e){return n3({nodes:e,createdAt:0})}function oc(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:V("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 of(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new I("SESSION_NOT_FOUND","No active session. Run open first.");return Z({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)=>op(await k(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)=>op(await k(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)=>op(await k(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&&(H(t,r.snapshot),e.sessionStore.set(e.sessionName,t))}},policy:$()})}function op(e){return e&&"object"==typeof e?e:void 0}function om(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}function oh(e){return"ref"===e.kind?{ref:og(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 og(e){return e?.startsWith("@")?e.slice(1):e}async function ow(e){switch(e.req.command){case"press":case"click":return await ov(e);case"fill":return await oy(e);default:return null}}async function ov(e){let t,{req:r,sessionName:a,sessionStore:i}=e,n=i.get(a),o="click"===r.command?"click":"press";if(!n)return V("SESSION_NOT_FOUND","No active session. Run open first.");let s=oc(n,o);if(s)return s;if(!eb("press",n.device))return V("UNSUPPORTED_OPERATION","press is not supported on this device");let l=ee(r.flags),u=P(l);if("primary"!==l){let e=E({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 V(e.code,e.message,e.details)}let d=function(e,t){let r=om(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:V("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 oI(e,n)}return await oS(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 z(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 ou({session:n,flags:r.flags,sessionStore:i,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):od(n.snapshot?.nodes??[]),o=oo({data:t.backendResult,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:a,extra:{...oh(t),...u}});return{result:o,responseData:o}}})}async function oy(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=oc(i,"fill");if(e)return e}if(i&&!eb("fill",i.device))return V("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return V("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:V("INVALID_ARGS","fill requires text after ref")}}let r=om(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:V("INVALID_ARGS","fill requires text after coordinates")}}let a=e8(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:V("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:V("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 oI(e,i)}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:od(i.snapshot?.nodes??[]),r=oo({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...oh(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:og(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 V("SESSION_NOT_FOUND","No active session. Run open first.");let a=of(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 os({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=y(t);if(ed(e))throw e;return{ok:!1,error:S(t)}}}async function oI(e,t){if(!ev(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){w({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 oA(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 X({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??"",androidFreshnessMode:i.androidFreshnessMode});return H(e,s),r.set(e.name,e),s}let ob=/\bis(?:n't| not)\s+responding\b/i,o_=/^close app$/i;async function oN(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await oM(t),r=function(e){if(oP(e))return e.find(e=>{let t=oD(e);return t.length>0&&o_.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=to(r.rect),n=await eU("adb",eY(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return w({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 ox(t))return w({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await e0(t.device,t.appBundleId),!await ok(t,t.appBundleId)))return w({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return w({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 w({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 oM(e){return tn(ti((await G(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function ox(e){for(let t=0;t<12;t+=1){if(!oP(await oM(e)))return!0;await A(500)}return!oP(await oM(e))}async function ok(e,t){for(let r=0;r<12;r+=1){if((await eJ(e.device)).package===t)return!0;await A(500)}return(await eJ(e.device)).package===t}function oD(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 oP(e){return e.some(e=>{let t=oD(e);return t.length>0&&ob.test(t)})}async function oL(e){let t=await ow({...e,captureSnapshotForSession:oA,refSnapshotFlagGuardResponse:D});if(t)return t;switch(e.req.command){case"type":return await oR({...e,captureSnapshotForSession:oA});case"get":return await K(e);case"is":return await Q(e);default:return null}}async function oR(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return V("SESSION_NOT_FOUND","No active session. Run open first.");if(!eb("type",i.device))return V("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await oN({session:i}))return V("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=of(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,...eC(e.message??`Typed ${Array.from(e.text).length} chars`)};return os({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:S(e)}}}function oO(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 oC(e){let{req:t,leaseRegistry:r}=e,a=oO(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 o$(e,t){if(!t)return[];let r=[],a=e.device,i=ex(t.platform);if(i&&!eA(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=eZ(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oE(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 oF=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function oT(e){let{session:t,sessionName:r,outPath:i,outputPlacement:o,dispatchContext:s}=e,u=Z({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?oU(await k(t.device,"screenshot",[],i,o)):oU(await k(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:o,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new I("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(a.join(l.tmpdir(),"agent-device-screenshot-")),r=a.join(t,"screenshot.png")),await n.mkdir(a.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(a.join(l.tmpdir(),`${e.prefix}-`));return{path:a.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:$()});return await u.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,maxSize:s.screenshotMaxSize,surface:t.surface,...i?{out:{kind:"path",path:i}}:{}})}function oU(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let oV=[255,59,48,255],oj=[255,214,10,255],oG=[0,0,0,255],oq={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 oB(e){let t=eD(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oK(r)&&oY(r.rect)&&(!t||oX(r.rect)>oX(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&&oY(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 oY(e.rect)&&!("image"===ta((t=e).type??"")&&!oz(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oW)||oZ(e.identifier);return oH(e)?t:t&&function(e){let t=ta(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 oH(e)&&!oK(e)}(t)&&oY(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(oH(t)&&!oK(t)&&oY(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oY(r.rect))return r;if(t.hittable&&oY(t.rect)&&!oK(t))return t;let a=e4(e,t);return a?.rect&&oY(a.rect)&&!oK(a)?a:null}(e.nodes,a);if(!o?.rect||!oY(o.rect))continue;let s=function(e,t,r){let a=oJ(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=oJ(a);if(!i)continue;let n=function(e){let t=0;return ta(e.type??"").includes("text")&&(t+=2),oW(e.label)&&(t+=2),oW(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oJ(t)??tt(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),oH(t)&&(a+=3),oH(e)&&(a+=2),r&&(a+=2),oZ(t.identifier)&&(a+=1),oz(t.value)&&(a+=1),a}(a,o,s),u=function(e,t,r,a){if(!e)return o1({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 o1({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(!oY(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)=>oX(e.overlayRect)-oX(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oQ(e.overlayRect,r.overlayRect)||oQ(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oX(r.overlayRect)<oX(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:o0(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:o0(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:to(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)o5(e,t.x,t.x+t.width-1,t.y+a,r),o5(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),o3(e,t.x+a,t.y,t.y+t.height-1,r),o3(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,oV),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=o2(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:o2(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)o8(e,t+o,r+n,i)})(e,i,o,a,oj),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oq[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&o8(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,oG)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,f.sync.write(t)),r}function oH(e){let t=[e.type,e.role,e.subrole].map(e=>ta(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 oK(e){let t=[e.type,e.role,e.subrole].map(e=>ta(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oz(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oW(e){var t;let r;return!!oz(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oZ(e){var t;return"string"==typeof e&&!!oW(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oJ(e){let t=[e.label,e.value].find(oW);return t?t.trim():oZ(e.identifier)?e.identifier.trim():void 0}function oY(e){return!!(e&&e.width>0&&e.height>0)}function oX(e){return e.width*e.height}function oQ(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 o0(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function o1(e,t,r){let a=o2(e.x,0,Math.max(0,t-1)),i=o2(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:o2(e.width,1,n),height:o2(e.height,1,o)}}function o2(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function o5(e,t,r,a,i){for(let n=t;n<=r;n+=1)o8(e,n,a,i)}function o3(e,t,r,a,i){for(let n=r;n<=a;n+=1)o8(e,t,n,i)}function o8(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let i=(e.width*r+t)*4;e.data[i]=a[0],e.data[i+1]=a[1],e.data[i+2]=a[2],e.data[i+3]=a[3]}let o4=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),o6=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),o9=new Set(o6),o7=new Map;function se(e){if(en(e.meta?.requestId))throw F()}function st(e,t,r,a){let i=g().requestId;return{...ea(e,t,r,a,i),requestId:i}}async function sr(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||tQ(e.flags))try{let t=await q(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function sa(e,t){if(t)return"android"===t.device.platform?t.device:void 0;if("open"!==e.command&&!tQ(e.flags))return;let r=await q(e.flags??{});return"android"===r.platform?r:void 0}async function si(e){let{req:t,existingSession:r,androidAdbProvider:a}=e;if(!a)return{};let i=await sa(t,r);if(!i)return{};let n=a({req:t,device:i,session:r}),o="function"==typeof n?n:n?.exec;return{provider:n,executor:o}}async function sn(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,androidAdbExecutor:s,contextFromFlags:l}=e,u=await oC({req:t,leaseRegistry:n});if(u)return u;let d=await no({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o,androidAdbExecutor:s});if(d)return d;let c=await L({req:t,sessionName:r,logPath:a,sessionStore:i});if(c)return c;let f=await n1({req:t,sessionName:r,sessionStore:i,logPath:a});if(f)return f;let p=await ns({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(p)return p;let m=await oL({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:l});return m||null}async function so(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(!eb(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 oN({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:v}=(a=(t=d).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tP.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tP.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}),y=Date.now(),S={...st(f,d.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},I="screenshot"===m?await oT({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:S}):await k(c.device,m,h,g,{...S});return"screenshot"===m&&d.flags?.overlayRefs&&"string"==typeof I?.path&&await ss(c,I,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=n3(e.snapshot),n={...a??{}},o=oe(n.direction)??oe(r[0]);if(!o)return a;let s=ot(n.amount)??ot(r[1]),l=ot(n.pixels),u=oi(n,[]),d=ot(n.referenceWidth),c=ot(n.referenceHeight),f=void 0!==d&&d>0&&void 0!==c&&c>0?{referenceWidth:d,referenceHeight:c}:i??n4;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=eP({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);n6(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:v,data:I,actionStartedAt:y,actionFinishedAt:Date.now(),flags:d.flags??{}}),T(m)&&eL(c,m),{ok:!0,data:I??{}}}async function ss(e,t,r){let a=er(await ei({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);H(e,a);let i=await oB({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function sl(e){let{logPath:t,token:r,sessionStore:i,leaseRegistry:n,androidAdbProvider:o,deviceInventoryProvider:s,trackDownloadableArtifact:l}=e;async function u(e){let d=!!(e.meta?.debug||e.flags?.verbose);return await m({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:d,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:S(new I("UNAUTHORIZED","Invalid token"))};try{return await R(s,async()=>{let r=function(e){let t=eR(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=eF(r);if(r&&!a)throw new I("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new I("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);w({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let s=r.command,d=oO(r);o6.has(s)||r.meta?.sessionIsolation!=="tenant"||n.assertLeaseAdmission({tenantId:d.tenantId,runId:d.runId,leaseId:d.leaseId,backend:d.leaseBackend});let c=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,i),f=o9.has(s)?null:await sr(r,c,i),p=async()=>{se(r);let e=i.get(c);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=el(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),i.set(c,e));let d=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?o$(t,a):function(e,t,r){var a,i;let n=[],o=ex(t);if(void 0!==e.platform&&o&&(a=ex(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!eN(i):"apple"!==i||!eN(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of oF){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 oF)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new I("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oE).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),f=e=>(function(e,t,r){let i=g();if(!t.ok){w({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=h({force:!0})??void 0;return{ok:!1,error:S(new I(v(t.error.code),t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:i.diagnosticId,logPath:e})}}return w({level:"info",phase:"request_success"}),h(),{ok:!0,data:function(e,t,r){var i,n;let o;if(!t)return t;let s=(i=e,n=t,o=Array.isArray(n.artifacts)?[...n.artifacts]:[],"screenshot"!==i.command||o.some(e=>e?.field==="path")||"string"!=typeof n.path||o.push({field:"path",path:n.path,localPath:i.meta?.clientArtifactPaths?.path,fileName:a.basename(i.meta?.clientArtifactPaths?.path??n.path)}),o.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(d,e,l);if(e?.recording?.invalidatedReason&&"record"!==s&&"close"!==s)return f({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||o4.has(s)||function(e,t){let r=o$(e,t);if(0!==r.length){var a;let t,i,n;throw new I("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(oE).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let p=await si({req:d,existingSession:e,androidAdbProvider:o});return await eB(p.provider,async()=>{let e=await sn({req:d,sessionName:c,logPath:t,sessionStore:i,leaseRegistry:n,invoke:u,androidAdbExecutor:p.executor,contextFromFlags:(e,r,a)=>({...st(t,e,r,a),surface:i.get(c)?.surface})});if(e)return f(e);let r=i.get(c);if(!r)return f({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let a=await so({req:d,session:r,sessionName:c,logPath:t,sessionStore:i});return f(a)})};return f?(se(r),await B(o7,f,p)):(se(r),await p())})}catch(r){w({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=g(),t=h({force:!0})??void 0;return{ok:!1,error:S(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return u}function su(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function sd(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function sc(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 I("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class sf{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=sc(e.backend),r=eF(e.tenantId);if(!r)throw new I("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let a=su(e.runId);if(!a)throw new I("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let i=this.resolveLeaseTtlMs(e.ttlMs),n=this.bindingKey(r,a,t),s=this.runBindings.get(n);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,i);this.runBindings.delete(n)}this.enforceCapacity(t);let l=this.now(),u={leaseId:o.randomBytes(16).toString("hex"),tenantId:r,runId:a,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+i};return this.leases.set(u.leaseId,u),this.runBindings.set(n,u.leaseId),{...u}}heartbeatLease(e){let t=sd(e.leaseId);if(!t)throw new I("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new I("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=sd(e.leaseId);if(!t)throw new I("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=sc(e.backend),r=eF(e.tenantId);if(!r)throw new I("INVALID_ARGS","tenant isolation requires tenant id.");let a=su(e.runId);if(!a)throw new I("INVALID_ARGS","tenant isolation requires run id.");let i=sd(e.leaseId);if(!i)throw new I("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new I("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new I("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 I("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 I("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=eF(t),i=su(r);if(t&&!a)throw new I("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new I("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 I("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}export{sf as LeaseRegistry,tP as SessionStore,tU as trackDownloadableArtifact,tj as cleanupDownloadableArtifact,ae as cleanupStaleAppLogProcesses,tH as cleanupUploadedArtifact,sl as createRequestHandler,tV as prepareDownloadableArtifact,tB as prepareUploadedArtifact,aj as teardownSessionResources,tq as trackUploadedArtifact};