agent-device 0.12.6 → 0.12.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/113.js +1 -1
- package/dist/src/1974.js +2 -0
- package/dist/src/3883.js +1 -0
- package/dist/src/3918.js +32 -0
- package/dist/src/4057.js +1 -0
- package/dist/src/7556.js +1 -0
- package/dist/src/7651.js +1 -0
- package/dist/src/7847.js +1 -0
- package/dist/src/8164.js +1 -0
- package/dist/src/8564.js +3 -0
- package/dist/src/9076.js +1 -0
- package/dist/src/9323.js +5 -0
- package/dist/src/9366.js +1 -0
- package/dist/src/9542.js +2 -0
- package/dist/src/9818.js +1 -0
- package/dist/src/989.js +1 -0
- package/dist/src/android-apps.js +1 -1
- package/dist/src/artifacts.js +1 -1
- package/dist/src/bin.d.ts +1 -0
- package/dist/src/bin.js +68 -70
- package/dist/src/commands/index.js +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon.d.ts +1 -0
- package/dist/src/daemon.js +15 -15
- package/dist/src/finders.js +1 -1
- package/dist/src/index.js +1 -3
- package/dist/src/install-source.js +1 -1
- package/dist/src/io.js +1 -1
- package/dist/src/metro-companion.d.ts +1 -0
- package/dist/src/metro.js +1 -1
- package/dist/src/remote-config.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/testing/conformance.js +1 -1
- package/dist/src/update-check-entry.d.ts +1 -0
- package/package.json +1 -1
- package/skills/agent-device/references/bootstrap-install.md +5 -3
- package/skills/agent-device/references/remote-tenancy.md +53 -13
- package/dist/src/164.js +0 -1
- package/dist/src/556.js +0 -1
- package/dist/src/57.js +0 -1
- package/dist/src/641.js +0 -38
- package/dist/src/818.js +0 -1
- package/dist/src/974.js +0 -2
- /package/dist/src/{267.js → 3267.js} +0 -0
- /package/dist/src/{152.js → 9152.js} +0 -0
- /package/dist/src/{1~rslib-runtime.js → rslib-runtime.js} +0 -0
package/dist/src/daemon.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import o from"node:path";import{spawn as s}from"node:child_process";import l from"node:http";import{fileURLToPath as d,pathToFileURL as u}from"node:url";import"node:https";import c from"node:os";import f from"node:fs/promises";import{setTimeout as p}from"node:timers/promises";import{PNG as m}from"pngjs";import h from"node:net";import{resolveInstallFromSourceResultTarget as g,normalizePlatformSelector as w,readProcessCommand as y,buildSimctlArgs as v,dispatchCommand as I,resolveAppleSimulatorSetPathForSelector as S,isAgentDeviceDaemonProcess as A,validateAndNormalizeBatchSteps as b,listIosDeviceProcesses as _,attachRefs as N,centerOfRect as k,buildScrollGesturePlan as x,hasRuntimeTransportHints as M,resolveDeployResultTarget as D,listIosDeviceApps as P,device_isApplePlatform as L,buttonTag as R,refSnapshotFlagGuardResponse as O,handleSnapshotCommands as E,runner_client_runIosRunnerCommand as C,normalizeType as T,withSuccessText as $,shutdownSimulator as F,decodePng as U,stopIosRunnerSession as G,splitSelectorFromArgs as V,localCommandPolicy as j,resolveSelectorChain as q,buildSelectorChainForNode as B,IOS_RUNNER_CONTAINER_BUNDLE_IDS as H,createRequestCanceledError as z,isNavigationSensitiveAction as K,registerRequestAbort as W,resolveSessionIsolationMode as J,resolveIosDevicectlHint as Z,getClickButtonValidationError as X,snapshotAndroid as Y,capabilities_isCommandSupportedOnDevice as Q,successText as ee,pruneGroupNodes as et,applyRuntimeHintsToApp as er,withKeyedLock as ea,snapshot_processing_resolveRefLabel as ei,snapshot_capture_captureSnapshot as en,dispatchGetViaRuntime as eo,DEFAULT_BATCH_MAX_STEPS as es,classifyAndroidAppTarget as el,parseSerialAllowlist as ed,runMacOsAlertAction as eu,createAgentDevice as ec,resolveTargetDevice as ef,stopAllIosRunnerSessions as ep,isDeepLinkTarget as em,clearRuntimeHintsFromApp as eh,parseFindArgs as eg,resolveDaemonCodeSignature as ew,getAndroidScreenSize as ey,getAndroidAppState as ev,extractNodeText as eI,readTextForNode as eS,normalizeTenantId as eA,dispatchIsViaRuntime as eb,resolveClickButton as e_,resolveTimeoutMs as eN,IOS_DEVICECTL_DEFAULT_HINT as ek,buildSnapshotState as ex,openAndroidApp as eM,context_contextFromFlags as eD,captureSnapshotData as eP,splitIsSelectorArgs as eL,isRequestCanceled as eR,resolveRequestTrackingId as eO,adbArgs as eE,resolvePayloadInput as eC,abortAllIosRunnerSessions as eT,tryParseSelectorChain as e$,getRunnerSessionSnapshot as eF,formatAndroidInstalledPackageRequiredMessage as eU,createUnsupportedArtifactAdapter as eG,resolveIosSimulatorDeviceSetPath as eV,markRequestCanceled as ej,resolveIosDeviceDeepLinkBundleId as eq,dispatchFindReadOnlyViaRuntime as eB,response_errorResponse as eH,parseCoordinateTarget as ez,resolveUserPath as eK,ensureDeviceReady as eW,getDiagnosticsMeta as eJ,readInfoPlistString as eZ,clearRequestCanceled as eX,buildSimctlArgsForDevice as eY,getActiveAndroidSnapshotFreshness as eQ,emitDiagnostic as e0,parseXmlDocumentSync as e1,findNearestHittableAncestor as e2,resolveFrontmostMacOsApp as e4,IOS_SIMCTL_LIST_TIMEOUT_MS as e3,findBestMatchesByLocator as e5,readVersion as e8,matchesPlatformSelector as e6,readProcessStartTime as e9,withDiagnosticsScope as e7,parseSessionSurface as te,resolveAndroidSerialAllowlist as tt,resolveDaemonPaths as tr,markAndroidSnapshotFreshness as ta,resolveDaemonServerMode as ti,flushDiagnosticsToSessionFile as tn,getRequestSignal as to}from"./641.js";import{runCmdBackground as ts,runCmd as tl,asAppError as td,normalizeError as tu,AppError as tc}from"./818.js";function tf(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 tp(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tm=/^-?\d+(\.\d+)?$/,th=/^[^\s"\\]+$/,tg=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tw=new Map([["--count","count"],["--pause-ms","pauseMs"]]),ty=new Map([["--delay-ms","delayMs"]]);function tv(e){return"click"===e||"press"===e}function tI(e){return"type"===e||"fill"===e}function tS(e){return tb(e,t_)}function tA(e){return JSON.stringify(e)}function tb(e,t){return t(e)?e:tA(e)}function t_(e){return tN(e)&&e.startsWith("@")||tm.test(e)}function tN(e){return th.test(e)}function tk(e,t){let r=t.flags??{};if(tv(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}tI(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tx(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",tb(t.metroHost,tN)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tb(t.bundleUrl,tN)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tb(t.launchUrl,tN)))}function tM(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tb(r,tN)),a))e.push(tS(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 tD(e,t){let r=[],a={},i=tv(e)?tg:"swipe"===e?tw:tI(e)?ty:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(tv(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(tv(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=tL(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 tP(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=tL(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 tL(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tR(e,t){for(let r of t.positionals??[])e.push(tS(r));t.flags?.relaunch&&e.push("--relaunch"),tx(e,t.runtime)}class tO{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=tO.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:function(e){if(!e)return{};let t={};for(let r of tE)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),e0({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=o.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let i of(r.push(`context platform=${e.device.platform} device=${tA(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(tv(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tS(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tS(a)),tk(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tS(r)),tk(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tS(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tS(a)),e.positionals.length>1&&t.push(tS(i)),tk(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tS(r)),t.push(tS(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tS(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",tS(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tS(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return tR(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tb(r,tN)),tx(t,e.flags),t.join(" ")}if("record"===e.command)return tM(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tS(r));return tk(t,e),t.join(" ")}(i));return`${r.join("\n")}
|
|
2
|
-
`}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=
|
|
3
|
-
`)}function
|
|
4
|
-
`)},flush:()=>{a&&(i(a),a="")}}}function
|
|
5
|
-
`,recoveredLineCount:s.length}}async function tJ(e,t,r,a,i,n){let o="active",l=s("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return v(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tK(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tV(r,{redactionPatterns:a});"number"==typeof l.pid&&t$(n,l.pid);let u=tj(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(o="failed"),tF(n),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tU(u),l.killed||l.kill("SIGKILL"),await tU(u),tF(n)}}}async function tZ(e,t,r,a){let i="active",n=s("log",["stream","--style","compact","--predicate",tK(e)],{stdio:["ignore","pipe","pipe"]}),o=tV(t,{redactionPatterns:r});"number"==typeof n.pid&&t$(a,n.pid);let l=tj(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tF(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tU(l),n.killed||n.kill("SIGKILL"),await tU(l),tF(a)}}}async function tX(e,t,r,a){let i="active",n=s("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tV(t,{redactionPatterns:r});"number"==typeof n.pid&&t$(a,n.pid);let l=tj(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tF(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tU(l),n.killed||n.kill("SIGKILL"),await tU(l),tF(a)}}}let tY=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),tQ=/https?:\/\/[^\s"'<>\])]+/i,t0=[/\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 t1(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t4(e)));for(let e of t.entries){let t=t4(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t2(e,t){let r=ra(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=ra(t?.maxPayloadChars,2048,64,16384),o=ra(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),d=s.slice(l),u=[];for(let e=d.length-1;e>=0&&u.length<r;e-=1){let t=d[e];if(!t?.trim())continue;let r=function(e,t,r,a,i,n){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=t7(s,["method","httpMethod"]),d=t7(s,["url","requestUrl"]),u=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(s,["status","statusCode","responseCode"]),c=tY.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=tQ.exec(o),h=d??m?.[0];if(!h)return null;let g=u??t5(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:t8(o),packetId:t6(o)??void 0,durationMs:t9(o)??void 0,raw:rr(o,n),line:r};if("android"===a&&function(e,t,r){let a=t3(t,r,5),i=e.packetId??a.map(e=>t6(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t3(t,r,12).filter(e=>t6(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>t8(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>t5(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>t9(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 rt(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=rr(e,n))}if("body"===i||"all"===i){let e=re(o,s,["requestBody","body","payload","request"]),t=re(o,s,["responseBody","response"]);e&&(w.requestBody=rr(e,n)),t&&(w.responseBody=rr(t,n))}return w}(d,e,l+e+1,a,i,n);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:o}}}function t4(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function t3(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 t5(e){for(let t of t0){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function t8(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 t6(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function t9(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 t7(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 re(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return rt(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 rt(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function rr(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function ra(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function ri(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 rn(e){let t=o.dirname(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),function(e,t){if(i.existsSync(e)&&!(i.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;i.existsSync(t)&&(i.existsSync(a)&&i.unlinkSync(a),i.renameSync(t,a))}}(e,{maxBytes:ri("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:ri("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function ro(e){var t,r,a,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:v,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y},o=ra(t?.maxEntries,25,1,200),s=t?.include??"summary",l=ra(t?.maxPayloadChars,2048,64,16384),d=ra(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?t2(i.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:d}}),S=[],A=await rs({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tH(u.id,c);if(e){let t=t2(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(I=t1(t,I,h),S.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await rd({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});e&&(e.dump.entries.length>0?(I=t1(e.dump,I,h),S.push(`Recovered ${e.dump.entries.length} iOS simulator HTTP entr${1===e.dump.entries.length?"y":"ies"} from simctl log show (${e.recoveredLineCount} app log lines scanned).`)):e.recoveredLineCount>0&&S.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===f?S.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===S.length&&("ios"===u.platform&&"simulator"===u.kind?S.push("Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop."):S.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&S.push("ios"===(n=u).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:I,notes:S}}async function rs(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tT(i.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(o.join(o.dirname(a),tC));if(!s)return null;let l=await tB(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function rl(e,t,r,a){rn(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 tX(e.id,n,o,a):await tJ(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return tq(t),await tz(e.id,t,n,o,a);if("macos"===e.platform)return await tZ(t,n,o,a);throw n.end(),new tc("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rd(e){let t=await tW({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t2(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 ru(e){await e.stop(),await tU(e.wait)}async function rc(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 tl("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await tl("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 tl("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 tl("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await tl("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rf(e){let t=o.dirname(e),r=o.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let a=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{i.unlinkSync(o.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rp=new Map;function rm(e){let t=rp.get(e);if(t&&(clearTimeout(t.timer),rp.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rh=new Map;function rg(e,t){let r=rh.get(e);if(!r)throw new tc("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tc("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rw(e){let t=rh.get(e);t&&(clearTimeout(t.timer),rh.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function ry(e){let t=await rv(e);await tl("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=o.join(e.tempDir,t);if(!i.existsSync(r))throw new tc("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rv(e){let t=await tl("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new tc("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new tc("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(rI),i=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new tc("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new tc("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new tc("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===i||e.startsWith(`${i}/`)))throw new tc("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,o=i;if(n!==o&&!n.startsWith(`${o}/`))throw new tc("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await tl("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new tc("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function rI(e){if(e.includes("\0"))throw new tc("INVALID_ARGS",`Invalid archive entry: ${e}`);if(o.posix.isAbsolute(e))throw new tc("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=o.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new tc("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rS=eN(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function rA(e,t){return new Promise((r,a)=>{let n,o=i.createWriteStream(t),s=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},l=!1,d=0,u=e=>{if(!l){if(l=!0,n&&clearTimeout(n),e){o.destroy(),i.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new tc("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rS});s(e),o.destroy(e),u(e)},rS)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new tc("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");s(e),o.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new tc("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",u),o.on("finish",()=>u()),c(),e.pipe(o)})}async function rb(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new tc("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new tc("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new tc("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=o.basename(t);if(!r||"."===r||".."===r)throw new tc("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),s=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),i.mkdtempSync(o.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=o.join(s,n);return await rA(e,t),{artifactPath:t,tempDir:s}}let t=o.join(s,"artifact.tar");await rA(e,t);let a=await ry({archivePath:t,tempDir:s,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:s}}catch(e){throw i.rmSync(s,{recursive:!0,force:!0}),e}}let r_=new Set(["agent_device.command","agent-device.command"]),rN=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rk=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rx={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},rM=new Set([...r_,...rN,...rk,...Object.keys(rx)]);function rD(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rP(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rL(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function rR(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function rO(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rE(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function rC(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=tu(new tc("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rD(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=tu(new tc(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rD(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=eA(r.tenantId);if(!e){let e=tu(new tc("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rD(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rT(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=o.isAbsolute(t)?t:o.resolve(t);try{e=await import(u(a).href)}catch(e){throw new tc("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let i=e[r];if("function"!=typeof i)throw new tc("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function r$(e){let t=await rT(),{handleRequest:r,token:a}=e;return l.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void rF(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void rU(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||rP(i,rD(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rP(i,rD(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rP(i,rD(a.id??null,-32600,"Invalid Request"),400);if(!rM.has(a.method))return void rP(i,rD(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rP(i,rD(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(r_.has(e))return{token:rR(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(rN.has(e)){let e,a=rO(t,"platform");if("ios"!==a&&"android"!==a)throw new tc("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:rR(t,r),session:rO(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rO(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new tc("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new tc("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new tc("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new tc("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new tc("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new tc("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rE(t,"retentionMs")}}}if(rk.has(e)){let e=rO(t,"materializationId")?.trim();if(!e)throw new tc("INVALID_ARGS","Invalid params: materializationId is required");return{token:rR(t,r),session:rO(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rO(t,"requestId"),materializationId:e}}}let a=rx[e];if(a)return{token:rR(t,r),session:rO(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rO(t,"tenantId")??rO(t,"tenant"),runId:rO(t,"runId"),leaseId:rO(t,"leaseId"),leaseTtlMs:rE(t,"ttlMs"),leaseBackend:rO(t,"backend")}};throw new tc("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,r_.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rP(i,rD(a.id??null,-32602,"Invalid params: command is required"),400);o=eO(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},W(o);let d=()=>{i.writableFinished||ej(o)};e.on("aborted",d),i.on("close",d);let u=await rC(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rP(i,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void rP(i,{jsonrpc:"2.0",id:a.id??null,result:c});rP(i,rD(a.id??null,-32e3,c.error.message,c.error),rL(c.error.code))}catch(t){let e=tu(t);rP(i,rD(a.id??null,-32e3,e.message,e),rL(e.code))}finally{eX(o)}})})}async function rF(e,t,r,i){try{var n;let o,s,l=rR({},e.headers),d=rG(l,i);if(d){t.statusCode=rL(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await rC(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await rb(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=a.randomUUID(),(s=setTimeout(()=>{rw(o)},3e5)).unref(),rh.set(o,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:f}))}catch(r){let e=tu(r);t.statusCode=rL(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rU(e,t,r,a){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=rR({},e.headers),s=rG(o,a);if(s){t.statusCode=rL(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await rC(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:o,session:"default",command:"download_artifact",positionals:[n]}});if(!l.ok){t.statusCode=l.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.response.error?.data?.message??l.response.error?.message??"Unauthorized"}));return}let d=function(e,t){let r=rp.get(e);if(!r)throw new tc("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tc("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw rm(e),new tc("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=i.createReadStream(d.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),d.fileName&&t.setHeader("content-disposition",`attachment; filename="${d.fileName.replace(/"/g,"")}"`),u.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=tu(e);t.statusCode=rL(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&rm(n)}),u.pipe(t)}catch(r){let e=tu(r);t.statusCode=rL(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rG(e,t){return t&&e!==t?tu(new tc("UNAUTHORIZED","Invalid token")):null}function rV(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rj(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rq(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 tc("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rB{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=rq(e.backend),r=eA(e.tenantId);if(!r)throw new tc("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rV(e.runId);if(!i)throw new tc("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,i,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),d={leaseId:a.randomBytes(16).toString("hex"),tenantId:r,runId:i,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(d.leaseId,d),this.runBindings.set(o,d.leaseId),{...d}}heartbeatLease(e){let t=rj(e.leaseId);if(!t)throw new tc("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new tc("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=rj(e.leaseId);if(!t)throw new tc("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=rq(e.backend),r=eA(e.tenantId);if(!r)throw new tc("INVALID_ARGS","tenant isolation requires tenant id.");let a=rV(e.runId);if(!a)throw new tc("INVALID_ARGS","tenant isolation requires run id.");let i=rj(e.leaseId);if(!i)throw new tc("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new tc("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new tc("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new tc("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new tc("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=eA(t),i=rV(r);if(t&&!a)throw new tc("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new tc("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new tc("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rH=eN(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rz=new Map;async function rK(e){let t=await f.mkdtemp(o.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await rZ(e.installablePath,o.join(t,"installable")),i=e.archivePath?await rZ(e.archivePath,o.join(t,"archive")):void 0,n=a.randomUUID(),s=e.ttlMs??rH,l=Date.now()+s,d=setTimeout(()=>{rW(n)},s);return rz.set(n,{rootPath:t,installablePath:r,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:n,installablePath:r,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await f.rm(t,{recursive:!0,force:!0}),e}}async function rW(e,t){let r=rz.get(e);if(!r)throw new tc("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new tc("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rz.delete(e),await f.rm(r.rootPath,{recursive:!0,force:!0})}async function rJ(e){let t=Array.from(rz.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await rW(e)}))}async function rZ(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=o.join(t,o.basename(e));return r.isDirectory()?await f.cp(e,a,{recursive:!0}):await f.copyFile(e,a),a}async function rX(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new tc("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await eW(e.session.device),e.session.device}if(!r)throw new tc("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await ef(e.flags??{});return await eW(a),a}async function rY(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,o,s=(n=function(e){let t=e.meta?.installSource;if(!t)throw new tc("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new tc("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new tc("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:rg(o,t.meta?.tenantId)},cleanup:()=>{rw(o)}}:{source:n,cleanup:()=>{}}),l=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new tc("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await rX({session:i,flags:t.flags});if(!Q("install",d))return eH("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=to(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:n}=await import("./641.js"),{prepareIosInstallArtifact:o}=await import("./641.js"),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await rK({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs})),await n(d,c.installablePath),!c.bundleId)throw new tc("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let o={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},s=$(o,rQ(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await rW(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./641.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./641.js"),p=await c(s.source,{signal:u});try{l.enabled&&(e=await rK({archivePath:p.archivePath,installablePath:p.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs}));let n=await f(d,p.installablePath,p.packageName);if(!n)throw new tc("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./641.js"),s=o(n),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...s?{appName:s}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=$(u,rQ(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await rW(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:tu(e)}}}function rQ(e){return`Installed: ${g(e)}`}async function r0(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new tc("INVALID_ARGS","release_materialized_paths requires a materializationId");return await rW(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:tu(e)}}}let r1=eN(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r2=eN(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r4(e,t,r){return t||r3(r)?null:eH("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function r3(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function r5(e){return"ios"===e.platform&&"simulator"===e.kind}async function r8(e,t){r5(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function r6(e){let t=r3(e.flags)||!e.session?await ef(e.flags??{}):await r9(e.session.device);return!1!==e.ensureReady&&await eW(t),t}async function r9(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 ef(t)}catch(e){if(!(e instanceof tc)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await ef({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function r7(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 ae=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function at(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ar(e){let t=e?.trim();return t&&t.length>0?t:void 0}function aa(e,t){if(void 0!==e){if("string"!=typeof e)throw new tc("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return ar(e)}}function ai(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new tc("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function an(e){if("ios"===e||"android"===e)return e}async function ao(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!M(r)||M(a)||await eh({device:i.device,appId:i.appBundleId})}async function as(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(o))return eH("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){M(l)&&s?.appBundleId&&await eh({device:s.device,appId:s.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===o)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let d=an(w(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return eH("INVALID_ARGS","runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first.");if(s&&s.device.platform!==d)return eH("INVALID_ARGS",`runtime set targets ${d}, but session "${i}" is already bound to ${s.device.platform}.`);let u={platform:(t=a.flags,r={platform:d,metroHost:ar(t?.metroHost),metroPort:ai(t?.metroPort),bundleUrl:ar(t?.bundleUrl),launchUrl:ar(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===at(u)?eH("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(n.setRuntimeHints(i,u),{ok:!0,data:{session:i,configured:!0,runtime:u}})}let al="open-command-roundtrip",ad="Not implemented for this platform in this release.",au=new Set(["app","desktop","frontmost-app"]);async function ac(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await e4();return{appBundleId:t.bundleId,appName:t.appName}}async function af(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return em(t)?"macos"===e.platform?void 0:"device"===e.kind?eq(r,t):void 0:await ap(e,t)}async function ap(e,t){try{let{resolveIosApp:r}=await import("./641.js");return await r(e,t)}catch{return}}async function am(e,t){if(!("android"!==e.platform||!t||em(t)))try{let{resolveAndroidApp:r}=await import("./641.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function ah(e,t,r,a){return await af(e,t,r)??await a(e,t)??("android"===e.platform&&t&&em(t)?r:void 0)}function ag(e){return eH("INVALID_ARGS",e)}function aw(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=te(r);if(!au.has(e))throw new tc("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new tc("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new tc("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?te(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new tc("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return eH(e instanceof tc?e.code:"INVALID_ARGS",String(e.message))}}function ay(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&em(r)?ag("open --relaunch does not support URL targets."):"app"!==a?ag("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===el(r)?ag(eU(r)):null:null}async function av(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await eW(i);let{appBundleId:l,appName:d}=await aI({device:i,surface:n,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new tc("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ae.includes(e));if(i)throw new tc("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ae.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new tc("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new tc("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:aa(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new tc("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return ai(e)}}(t.metroPort),bundleUrl:aa(t.bundleUrl,"bundleUrl"),launchUrl:aa(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:an(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=an(i);if(a.platform&&r&&!n)throw new tc("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${i}.`);if(a.platform&&n&&a.platform!==n)throw new tc("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${i}. Clear the runtime hints or use a different session.`);return n&&a.platform!==n?{...a,platform:n}:a}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&at(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=td(t);return eH(e.code,e.message,e.details)}}({req:t,sessionStore:a,sessionName:r,device:i});if(!u.ok)return{type:"response",response:u};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await ao({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function aI(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await ac(r);return{appBundleId:n.appBundleId??await ah(t,a,i,am),appName:n.appName??a}}let aS=new Map;async function aA(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await G(t.id),await I(t,"close",[r],a,i),await r8(t,r1)}async function ab(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||em(d)||await I(r,"open",[l],a.flags?.out,{...eD(i,a.flags,n,o)})}async function a_(e){var t,r,a;let{req:i,sessionName:n,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:f,appBundleId:p,runtime:m,existingSession:h}=e,g=i.flags?.relaunch===!0,w=h?.trace?.outPath;if(g&&d){let e=p??d;await aA({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eD(s,i.flags,p??h?.appBundleId,w)}})}await er({device:l,appId:p,runtime:m});let y=Date.now();await I(l,"open",u,i.flags?.out,{...eD(s,i.flags,p)}),await ab({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:al,appTarget:d,appBundleId:p}:void 0;if(await r8(l,r2),eR(i.meta?.requestId)){let e=z();return eH(e.code,e.message,e.details)}h&&ta(h,"open",h.snapshot);let S=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:n,device:l,surface:f,appBundleId:p,appName:c,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(t=o,r=n,(a=m)&&(0===at(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let A=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:i};return r&&(d.appName=r),a&&(d.appBundleId=a),n&&(d.startup=n),s&&l(s)>0&&(d.runtime=s),o&&(d.platform=o.platform,d.target=o.target??"mobile",d.device=o.name,d.id=o.id,d.kind=o.kind,"android"===o.platform&&(d.serial=o.id)),o?.platform==="ios"&&(d.device_udid=o.id,d.ios_simulator_device_set=o.simulatorSetPath??null),{...d,...ee(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:v,device:l,runtime:m,runtimeHintCount:at});return o.recordAction(S,{command:"open",positionals:u,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:A}),o.set(n,S),{ok:!0,data:A}}async function aN(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return eH("SESSION_NOT_FOUND",`Session "${r}" not found.`);let n=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(n?e.appName:void 0),l=aw(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?ag("open --relaunch requires an app name or an active session app."):ag("Session already active. Close it first or pass a new --session name.");let d=ay({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await r9(e.device),c=await av({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await a_({req:t,sessionName:r,sessionStore:i,logPath:a,device:u,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let n=t.flags?.relaunch===!0,o=t.positionals?.[0];if(n&&!o)return ag("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&em(r)?ag("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===el(r)?ag(eU(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await ef(t.flags??{}),d=aw(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=ay({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await ea(aS,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return eH("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await av({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await a_({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:d})})}async function ak(e){let t=await tl("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 ax(e){let{device:t,shutdownRequested:r}=e;if(r&&(r5(t)||"android"===t.platform&&"emulator"===t.kind))try{return r5(t)?await F(t):await ak(t)}catch(t){let e=tu(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aM(e){if(await G(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eu("dismiss",t).catch(t=>{e0({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aD(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");n.appLog&&await ru(n.appLog),t.positionals&&t.positionals.length>0&&(("ios"===n.device.platform||"macos"===n.device.platform)&&await aM(n),await I(n.device,"close",t.positionals,t.flags?.out,{...eD(a,t.flags,n.appBundleId,n.trace?.outPath)}),await r8(n.device,r1)),("ios"===n.device.platform||"macos"===n.device.platform)&&await aM(n),M(i.getRuntimeHints(r))&&n.appBundleId&&await eh({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...ee(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rJ(r).catch(()=>{}),i.delete(r);let o=await ax({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:$({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...ee(`Closed: ${r}`)}}}let aP=["platform","target","device","udid","serial","verbose","out"];function aL(e,t){let r=e??{};for(let e of aP)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aR={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./641.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./641.js");return await a(e,t,r)}},aO={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./641.js"),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await import("./641.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aE(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},d=r4(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return eH("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,a=f?rg(f,t.meta?.tenantId):tO.expandHome(c);if(!i.existsSync(a))return eH("INVALID_ARGS",`App binary not found: ${a}`);let d=await r6({session:s,flags:l,ensureReady:!1});if(!Q(r,d))return eH("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=$(e,(p=e,`Installed: ${p.appName??D(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&rw(f)}}async function aC(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return eH("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??es;if(!Number.isInteger(i)||i<1||i>1e3)return eH("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=b(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await aT(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=td(t);return eH(e.code,e.message,e.details)}}async function aT(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aL(e,n)}(e.flags,r.flags);void 0===o.session&&(o.session=t);let s=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:o,runtime:void 0===r.runtime?e.runtime:r.runtime,meta:e.meta}),l=Date.now()-n;return s.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:i,error:s.error}}async function a$(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new tc("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await aF({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aU({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aG(t,u),a=!0)}else t=(await aU({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aG(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function aF(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await tl("xcrun",v(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:e3});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||aV(a).includes(aV(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 aU(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await tl("xcrun",v(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new tc("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(n.stdout??"").trim();if(!o)throw new tc("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aG(e,t){let r=await tl("xcrun",v(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:e3});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 aV(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aj(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,i=eV(e.iosSimulatorDeviceSet);if(!r)return eH("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await a$({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:eW});return{ok:!0,data:{udid:n.udid,device:n.device,runtime:n.runtime,ios_simulator_device_set:i??null,created:n.created,booted:n.booted}}}catch(t){let e=td(t);return eH(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=tt(t.flags?.androidDeviceAllowlist),a=w(t.flags?.platform),i=S({simulatorSetPath:eV(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./641.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./641.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./641.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./641.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=td(t);return eH(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r4(t.command,e,i);if(n)return n;let o=await r6({session:e,flags:i,ensureReady:!0});if(!Q("apps",o))return eH("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(L(o.platform)){let{listIosApps:e}=await import("./641.js");return{ok:!0,data:{apps:(await e(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await import("./641.js");return{ok:!0,data:{apps:(await l(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function aq(e){let{ensureAndroidEmulatorBooted:t}=await import("./641.js");return await t(e)}let aB='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',aH='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function az(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=w(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return eH("SESSION_NOT_FOUND","ios"===o?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`);let s=r4("appstate",i,n);if(s)return s;let l=(i?.device.platform==="ios"||i?.device.platform==="macos")&&function(e,t){if(!t)return!1;if(!r3(e))return!0;let r=w(e?.platform);return!(r&&!e6(t.device.platform,r)||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(n,i);if("ios"===o&&!l)return eH("SESSION_NOT_FOUND",aB);if("macos"===o&&!l)return eH("SESSION_NOT_FOUND",aH);if(l&&i){let e=i.appName??i.appBundleId;if(!i.appName&&!i.appBundleId){if("macos"===i.device.platform&&i.surface&&"app"!==i.surface&&"frontmost-app"!==i.surface)return{ok:!0,data:{platform:i.device.platform,appName:i.surface,appBundleId:i.appBundleId,source:"session",surface:i.surface}};let e="macos"===i.device.platform?"macOS":"iOS";return eH("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:i.device.platform,appName:e??"unknown",appBundleId:i.appBundleId,source:"session",surface:i.surface??"app",..."ios"===i.device.platform?{device_udid:i.device.id,ios_simulator_device_set:i.device.simulatorSetPath??null}:{}}}}let d=await r6({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return eH("SESSION_NOT_FOUND",aB);if("macos"===d.platform)return eH("SESSION_NOT_FOUND",aH);let{getAndroidAppState:u}=await import("./641.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function aK(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r4(t.command,i,n);if(o)return o;let s="android"===(w(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=r7({flags:n,sessionDevice:i?.device}),u=s&&!!d,c=!1;try{e=await r6({session:i,flags:n,ensureReady:!1})}catch(r){let t=td(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return eH("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await aq({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return eH("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return eH("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=r7({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return eH("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aq({avdName:t,serial:n.serial,headless:!0})}await eW(e)}else("android"!==e.platform||!0!==e.booted)&&await eW(e);return Q("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:eH("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await az({req:t,sessionName:r,sessionStore:a}):null}function aW(e){return Math.round(10*e)/10}let aJ="adb-shell-dumpsys-cpuinfo",aZ="adb-shell-dumpsys-meminfo";async function aX(e,t){try{let r=await tl("adb",eE(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,o;let e=r.trim();if(0===e.length)continue;let s=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!s)continue;let l=Number(s[1]),d=s[2];Number.isFinite(l)&&(n=d,o=t,n===o||n.startsWith(`${o}:`))&&(i+=l,a.add(d))}return{usagePercent:aW(i),measuredAt:r,method:aJ,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw aQ("cpu",t,e)}}async function aY(e,t){try{let r=await tl("adb",eE(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new tc("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let a=a0(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!==a1(e));if(!r)break;return a1(r)??void 0}}(e);if(void 0===a)throw new tc("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:a,totalRssKb:a0(e,"TOTAL RSS"),measuredAt:r,method:aZ}}(r.stdout,t,new Date().toISOString())}catch(e){throw aQ("memory",t,e)}}function aQ(e,t,r){return r instanceof tc&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new tc(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof tc?r:new tc("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a0(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a1(a[1])??void 0}function a1(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a2="ps-process-snapshot",a4="ps-process-snapshot",a3="xctrace-activity-monitor",a5="xctrace-activity-monitor";async function a8(e,t){if("ios"===e.platform&&"device"===e.kind)return await a7(e,t);let r=await a9(e,t),a=await io(e,r);if(0===a.length)throw new tc("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let i=new Date().toISOString(),n=tp(a.map(e=>o.basename(is(e.command))));return il({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:n,cpuMethod:a2,memoryMethod:a4})}async function a6(e){let t=e1(e),r=id(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new tc("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}),i=a.indexOf("pid"),n=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(i<0||n<0||o<0||s<0)throw new tc("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let i of t)r(i)&&a.push(i),a.push(...e(i.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,f;let t=e.children;if(0===t.length)continue;for(let e of t){let t=id(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);u.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&u.set(e.attributes.id,{numberValue:iu(e),processName:ip(e)})}let r=ic(t[i],u),a=(c=t[n],f=u,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:ip(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:ic(t[o],u),residentMemoryBytes:ic(t[s],u)})}return d}async function a9(e,t){let r="macos"===e.platform?await ia(t):await ii(e,t),a="macos"===e.platform?o.join(r,"Contents","Info.plist"):o.join(r,"Info.plist"),i=await eZ(a,"CFBundleExecutable");if(!i)throw new tc("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?o.join(r,"Contents","MacOS",i):void 0}}async function a7(e,t){let r=await ie(e,t),a=await it(e,t),i=await it(e,t),n=ir(await a6(a.xml),r,t,e),o=ir(await a6(i.xml),r,t,e),s=i.capturedAtMs-a.capturedAtMs;if(s<=0)throw new tc("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new tc("COMMAND_FAILED",`Incomplete Activity Monitor sample for ${t}`,{appBundleId:t,deviceId:e.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});return il({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:a3,memoryMethod:a5})}async function ie(e,t){let r=(await P(e,"all")).find(e=>e.bundleId===t);if(!r)throw new tc("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new tc("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await _(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new tc("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function it(e,t){let r=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-ios-perf-")),a=o.join(r,"sample.trace"),i=o.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",a,"--quiet","--no-prompt"],o=await tl("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==o.exitCode)throw new tc("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:im(o.stdout,o.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",i],d=await tl("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new tc("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:l,exitCode:d.exitCode,stdout:d.stdout,stderr:d.stderr,appBundleId:t,deviceId:e.id,hint:im(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function ir(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>o.basename(d(e.executable)))),s=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===s.length)throw new tc("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:a.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let l=new Map;for(let e of s){let t=l.get(e.pid);if(!t){l.set(e.pid,e);continue}l.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:ih(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:ih(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:tp(u.map(e=>e.processName))}}async function ia(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await tl("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new tc("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!a)throw new tc("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function ii(e,t){let r=eY(e,["get_app_container",e.id,t,"app"]),a=await tl("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new tc("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let i=a.stdout.trim();if(0===i.length)throw new tc("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function io(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:eY(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 tl("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=is(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||o.basename(i)===a.executableName})}function is(e){let[t=""]=e.trim().split(/\s+/,1);return t}function il(e){return{cpu:{usagePercent:aW(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 id(e,t){for(let r of e){if(t(r))return r;let e=id(r.children,t);if(e)return e}}function iu(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 ic(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:iu(e):null}function ip(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function im(e,t){let r=Z(e,t);if(r)return r;let a=`${e}
|
|
6
|
-
${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?
|
|
7
|
-
`,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?iD(n,r,a,s):"start"===o?iP(n,r,a):"stop"===o?iL(n,r,a):eH("INVALID_ARGS",iI):eH("INVALID_ARGS",iI)}async function iM(e,t,r){let a=r.resolveAppLogPath(t),i=await rc(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 iD(e,t,r,a){if(e.appLog&&!a)return eH("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return eH("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:rf(i)};e.appLog&&await ru(e.appLog);let n=rf(i),o=r.resolveAppLogPidPath(t);try{let a=await rl(e.device,e.appBundleId,i,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:i,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...n,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:tu(a)}}}async function iP(e,t,r){if(e.appLog)return eH("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return eH("INVALID_ARGS","logs start requires an app session; run open <app> first");let a=r.resolveAppLogPath(t),i=r.resolveAppLogPidPath(t);try{let n=await rl(e.device,e.appBundleId,a,i);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:tu(e)}}}async function iL(e,t,r){if(!e.appLog)return eH("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await ru(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iR(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","network requires an active session");if(!Q("network",i.device))return eH("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!iS.includes(n))return eH("INVALID_ARGS",iA);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return eH("INVALID_ARGS","network dump limit must be an integer in range 1..200");let s=function(e){let t=e.positionals?.[2]?.toLowerCase(),r=e.flags?.networkInclude;if(t&&r&&t!==r)return eH("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return ib.includes(a)?{ok:!0,include:a}:eH("INVALID_ARGS",i_)}(t);if(!s.ok)return s;let{include:l}=s,d=await ro({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!i.appLog,state:i.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let iO=new Set(["ios","android","macos","linux"]);function iE(e,t,r){let a=e[t];if(void 0!==a)throw new tc("INVALID_ARGS",a===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(a)} vs ${String(r)}.`);e[t]=r}function iC(e){return!!e&&!Number.isNaN(Number(e))}let iT=/[*?[\]{}]/;async function i$(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;W(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=td(e);return eH(t.code,t.message)}).finally(()=>{eX(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,ej(i),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(n,[...d]))},n)})]):await c}finally{t&&clearTimeout(t),u&&(await iF(c)||e0({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){e0({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:td(e).message}})}}}async function iF(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function iU(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return eH("INVALID_ARGS","test requires at least one path or glob");try{var s,l,d,u,c,f;let e,p,m,h,g,w=function(e){let{inputs:t,cwd:r,platformFilter:a}=e,n=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tO.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>o.join(n,e));if(t.isFile()){if(".ad"!==o.extname(n))throw new tc("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!iT.test(r)&&(a=n,!iT.test(a)))throw new tc("INVALID_ARGS",`test input not found: ${e}`);let s=o.isAbsolute(n)?n:e;return i.globSync(s,{cwd:o.isAbsolute(n)?void 0:t}).map(e=>o.isAbsolute(e)?e:o.resolve(t,e)).filter(e=>".ad"===o.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>o.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var d,u;let t=function(e){let t=e.split(/\r?\n/),r={};for(let e of t){let t=e.trim();if(0===t.length||t.startsWith("#"))continue;if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&iO.has(e)&&iE(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&iE(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&iE(r,"retries",Math.floor(e))}}return r}(i.readFileSync(e,"utf8"));if(!a){l.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){l.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${a}`});continue}d=a,u=t.platform,("apple"===d?"apple"===u||"ios"===u||"macos"===u:u===d)&&l.push({kind:"run",path:e,metadata:t})}if(0===l.filter(e=>"run"===e.kind).length){let e=a?` for --platform ${a}`:"";throw new tc("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tO.expandHome(t??".agent-device/test-artifacts",r);return o.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),I=[],S=Date.now(),A=0;for(let e of w){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await iG({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(I.push(i),t.flags?.failFast===!0)break}let b=(u=w.length,c=I,f=Date.now()-S,e=c.filter(e=>"passed"===e.status).length,m=(p=c.filter(e=>"failed"===e.status)).length,h=c.filter(e=>"skipped"===e.status).length,g=e+m,{total:u,executed:g,passed:e,failed:m,skipped:h,notRun:Math.max(0,u-g-h),durationMs:f,failures:p,tests:c});return{ok:!0,data:b}}catch(t){let e=td(t);return eH(e.code,e.message)}}async function iG(e){var t,r;let a,n,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,y=Date.now(),v=o.join(h,(t=s.path,(0===(n=c?o.relative(c,t):o.basename(t)).length||n.startsWith("..")?o.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",S=0;for(let e=0;e<=p;e+=1){S=e+1;let t=function(e,t,r,a,i=0){let n=o.basename(r,o.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),n=o.join(v,`attempt-${S}`);r=s.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,o.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eO(`${t??r}:test:${i+1}:${o.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await i$({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:s,attemptArtifactsDir:l}=e,d=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(t)];t.ok||"string"!=typeof t.error.logPath||d.push(t.error.logPath);let u=function(e,t){let r=[],a=new Map;for(let n of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=o.extname(e),a=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${a}-${i+1}${r}`}(o.basename(n),a),s=o.join(t,e);o.resolve(n)!==o.resolve(s)&&i.copyFileSync(n,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${s}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");u.length>0&&c.push(`copiedArtifacts: ${u.map(e=>o.basename(e)).join(", ")}`);let f=o.join(l,"result.txt"),p=`${c.join("\n")}
|
|
8
|
-
`;i.writeFileSync(f,p),t.ok||i.writeFileSync(o.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:S,maxAttempts:p+1,attemptArtifactsDir:n}),a=h,I=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:s.path,session:I,status:"passed",durationMs:A,attempts:S,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let b=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:I,status:"failed",durationMs:A,attempts:S,artifactsDir:v,error:b}}function
|
|
9
|
-
`,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=td(t);return eH(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function iH(e){var t;let{req:r,sessionName:a,action:i,invoke:n}=e;return await n({token:r.token,session:a,command:i.command,positionals:i.positionals??[],flags:(t=r.flags,aL(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function iz(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=>tS(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 iK(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 iW(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await iB({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await iU({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await iB({req:{...t,command:"replay",session:r,positionals:[e],flags:void 0===o?t.flags:{...t.flags??{},platform:o},meta:s?{...t.meta??{},requestId:s}:t.meta},sessionName:r,logPath:a,sessionStore:i,invoke:async e=>{var t;return t=await n(e),l&&iK(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await aD({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let iJ=new Set(["session_list","ensure-simulator","devices","apps"]),iZ=new Set(["boot","appstate"]),iX=new Set(["perf","logs","network"]),iY=new Set(["replay","test"]);async function iQ(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=i.get(r),u=t.flags??{},c=r4(n,d,u);if(c)return c;let f=await r6({session:d,flags:u,ensureReady:!0});if(!Q(n,f))return eH("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await I(f,n,o,t.flags?.out,{...eD(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,p,f):d;i.recordAction(e,{command:n,positionals:s??o,flags:t.flags??{},result:p??{}}),e!==d&&i.set(r,e)}return{ok:!0,data:p??{}}}async function i0(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r4("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return eH("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await r6({session:n,flags:o,ensureReady:!0});if(!Q("clipboard",d))return eH("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await I(d,"clipboard",t.positionals??[],t.flags?.out,{...eD(a,t.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function i1(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(iJ.has(t.command))return await aj({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await as({req:t,sessionName:r,sessionStore:i});if(iZ.has(t.command))return await aK({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await i0({req:t,sessionName:r,logPath:a,sessionStore:i});if("keyboard"===t.command){let e=i.get(r),n=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==n||"ios"!==w((t.flags??{}).platform)?await iQ({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):eH("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(iX.has(t.command))return await iN({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aE({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?aO:aR});if("install_source"===t.command)return await rY({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r0({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await iQ({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=eC(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tO.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):eH("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await iQ({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 ah(e.device,r,e.appBundleId,am)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aN({req:t,sessionName:r,logPath:a,sessionStore:i}):iY.has(t.command)?await iW({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await aC(t,r,n):"close"===t.command?await aD({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function i2(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,o=t.command;if("find"!==o)return null;let s=t.positionals??[];if(0===s.length)return eH("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=eg(s);if(!d)return eH("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return eH("INVALID_ARGS","find accepts only one of --first or --last");let p=await eB({req:t,sessionName:r,logPath:a,sessionStore:i});if(p)return p;let m=i.get(r);if(!m&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await ef(t.flags??{});m||await eW(h);let g="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,y=0,v=null,I=async()=>{let e=Date.now();if(v&&e-y<750&&!eQ(m))return{nodes:v};let{snapshot:n}=await en({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return y=e,v=o,m&&(m.snapshot=n,i.set(r,m)),{nodes:o,truncated:n.truncated,backend:n.backend}},S={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:o,locator:l,query:d};if("wait"===u)return i4(S,I,l,d,f);let{nodes:A}=await I(),b=e5(A,l,d,{requireRect:w});if(w&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,k;let e;return _=b.matches,N=l,k=d,e=_.slice(0,8).map(e=>{let t=eI(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eH("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${k}". Use a more specific locator or selector.`,{locator:N,query:k,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let x=b.matches[0]??null;if(!x)return eH("COMMAND_FAILED","find did not match any element");let M="click"===u||"focus"===u||"fill"===u||"type"===u?e2(A,x)??x:x,D=`@${M.ref}`,P={node:x,resolvedNode:M,ref:D,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>i3(S),get_text:()=>i5(S,P),get_attrs:()=>i8(S,P),click:()=>i6(S,P),fill:()=>i9(S,P,c),focus:()=>i7(S,P),type:()=>ne(S,P,c)}[u];return L?L():null}async function i4(e,t,r,a,i){let{req:n,sessionStore:o,session:s,command:l}=e,d=i??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(e5(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:n.positionals??[],flags:n.flags??{},result:{found:!0,waitedMs:Date.now()-u}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-u}};await new Promise(e=>setTimeout(e,300))}return eH("COMMAND_FAILED","find wait timed out")}async function i3(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 i5(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await eS({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eD(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 i8(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 i6(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,invoke:o,command:s,locator:l,query:d}=e,u=await o({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let c=t.resolvedNode.rect?k(t.resolvedNode.rect):null,f={ref:t.ref,locator:l,query:d};return c&&(f.x=c.x,f.y=c.y),n&&i.recordAction(n,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:f}}async function i9(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return eH("INVALID_ARGS","find fill requires text");let d=await s({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&n.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function i7(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?k(t.node.rect):null;if(!l)return eH("COMMAND_FAILED","matched element has no bounds");let d=await I(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eD(s,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function ne(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return eH("INVALID_ARGS","find type requires text");let d=t.node.rect?k(t.node.rect):null;if(!d)return eH("COMMAND_FAILED","matched element has no bounds");await I(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eD(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await I(o,"type",[r],a.flags?.out,{...eD(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let nt=`
|
|
1
|
+
let e,t,r;import a from"node:crypto";import i,{promises as n}from"node:fs";import o from"node:path";import{spawn as s}from"node:child_process";import l from"node:http";import{fileURLToPath as d,pathToFileURL as u}from"node:url";import"node:https";import c from"node:os";import f from"node:fs/promises";import{setTimeout as p}from"node:timers/promises";import{PNG as m}from"pngjs";import h from"node:net";import{resolveUserPath as g}from"./3267.js";import{localCommandPolicy as w,createAgentDevice as y,readVersion as v,resolveDaemonCodeSignature as I,normalizeTenantId as S,resolveSessionIsolationMode as A,withDiagnosticsScope as b,resolveDaemonPaths as _,flushDiagnosticsToSessionFile as N,getDiagnosticsMeta as k,resolveDaemonServerMode as M,resolveDeployResultTarget as x,resolveInstallFromSourceResultTarget as D,emitDiagnostic as P}from"./8564.js";import{readProcessStartTime as L,isAgentDeviceDaemonProcess as R,readProcessCommand as O}from"./3883.js";import{asAppError as C,normalizeError as E,AppError as T}from"./9152.js";import{runCmdBackground as $,runCmd as U}from"./9818.js";import{resolveIosSimulatorDeviceSetPath as F,classifyAndroidAppTarget as G,buildSimctlArgs as V,parseSerialAllowlist as j,adbArgs as q,resolveAndroidSerialAllowlist as H,clearRuntimeHintsFromApp as B,hasRuntimeTransportHints as K,buildSimctlArgsForDevice as z,formatAndroidInstalledPackageRequiredMessage as W,applyRuntimeHintsToApp as J}from"./9323.js";import{resolveTimeoutMs as Z}from"./989.js";import{resolveAppleSimulatorSetPathForSelector as X,dispatchCommand as Y,validateAndNormalizeBatchSteps as Q,refSnapshotFlagGuardResponse as ee,buttonTag as et,handleSnapshotCommands as er,device_isApplePlatform as ea,runner_client_runIosRunnerCommand as ei,shutdownSimulator as en,stopIosRunnerSession as eo,getClickButtonValidationError as es,createRequestCanceledError as el,registerRequestAbort as ed,isNavigationSensitiveAction as eu,resolveIosDevicectlHint as ec,snapshotAndroid as ef,capabilities_isCommandSupportedOnDevice as ep,snapshot_capture_captureSnapshot as em,resolveTargetDevice as eh,assertAndroidPressStayedInApp as eg,stopAllIosRunnerSessions as ew,withKeyedLock as ey,dispatchGetViaRuntime as ev,DEFAULT_BATCH_MAX_STEPS as eI,getAndroidAppState as eS,runMacOsAlertAction as eA,getAndroidScreenSize as eb,isDeepLinkTarget as e_,readTextForNode as eN,dispatchIsViaRuntime as ek,resolveClickButton as eM,IOS_DEVICECTL_DEFAULT_HINT as ex,buildSnapshotState as eD,openAndroidApp as eP,context_contextFromFlags as eL,captureSnapshotData as eR,isRequestCanceled as eO,resolveRequestTrackingId as eC,resolvePayloadInput as eE,abortAllIosRunnerSessions as eT,getRunnerSessionSnapshot as e$,createUnsupportedArtifactAdapter as eU,isAndroidEscapeError as eF,markRequestCanceled as eG,resolveIosDeviceDeepLinkBundleId as eV,parseCoordinateTarget as ej,response_errorResponse as eq,dispatchFindReadOnlyViaRuntime as eH,ensureDeviceReady as eB,readInfoPlistString as eK,clearRequestCanceled as ez,getActiveAndroidSnapshotFreshness as eW,parseXmlDocumentSync as eJ,resolveFrontmostMacOsApp as eZ,IOS_SIMCTL_LIST_TIMEOUT_MS as eX,matchesPlatformSelector as eY,listIosDeviceApps as eQ,parseSessionSurface as e0,listIosDeviceProcesses as e1,normalizePlatformSelector as e2,getRequestSignal as e3,markAndroidSnapshotFreshness as e8,buildScrollGesturePlan as e4,IOS_RUNNER_CONTAINER_BUNDLE_IDS as e5}from"./3918.js";import{withSuccessText as e9,decodePng as e6,successText as e7}from"./9076.js";import{splitSelectorFromArgs as te,findNearestHittableAncestor as tt,extractNodeText as tr,splitIsSelectorArgs as ta,tryParseSelectorChain as ti,resolveSelectorChain as tn,resolveRefLabel as to,buildSelectorChainForNode as ts,normalizeType as tl,pruneGroupNodes as td}from"./7847.js";import{attachRefs as tu,centerOfRect as tc}from"./4057.js";import{findBestMatchesByLocator as tf,parseFindArgs as tp}from"./7556.js";function tm(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function th(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tg=/^-?\d+(\.\d+)?$/,tw=/^[^\s"\\]+$/,ty=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tv=new Map([["--count","count"],["--pause-ms","pauseMs"]]),tI=new Map([["--delay-ms","delayMs"]]);function tS(e){return"click"===e||"press"===e}function tA(e){return"type"===e||"fill"===e}function tb(e){return tN(e,tk)}function t_(e){return JSON.stringify(e)}function tN(e,t){return t(e)?e:t_(e)}function tk(e){return tM(e)&&e.startsWith("@")||tg.test(e)}function tM(e){return tw.test(e)}function tx(e,t){let r=t.flags??{};if(tS(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");let t=r.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern);return}tA(t.command)&&"number"==typeof r.delayMs&&e.push("--delay-ms",String(r.delayMs))}function tD(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",tN(t.metroHost,tM)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tN(t.bundleUrl,tM)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tN(t.launchUrl,tM)))}function tP(e,t){let[r,...a]=t.positionals??[];for(let t of(r&&e.push(tN(r,tM)),a))e.push(tb(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}function tL(e,t){let r=[],a={},i=tS(e)?ty:"swipe"===e?tv:tA(e)?tI:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(tS(e)&&"--double-tap"===o){a.doubleTap=!0;continue}if(tS(e)&&"--button"===o&&n+1<t.length){let e=t[n+1];("primary"===e||"secondary"===e||"middle"===e)&&(a.clickButton=e),n+=1;continue}let s=i?.get(o);if(s&&n+1<t.length){let e=tO(t[n+1]);if(null!==e){a[s]=e,n+=1;continue}}if("swipe"===e&&"--pattern"===o&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(o)}return{positionals:r,flags:a}}function tR(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let i=e[a];if("--platform"===i&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===i&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===i&&a+1<e.length){let t=tO(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===i&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===i&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(i)}return{positionals:t,flags:r}}function tO(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function tC(e,t){for(let r of t.positionals??[])e.push(tb(r));t.flags?.relaunch&&e.push("--relaunch"),tD(e,t.runtime)}class tE{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=tE.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:function(e){if(!e)return{};let t={};for(let r of tT)void 0!==e[r]&&(t[r]=e[r]);return t}(t.flags),result:t.result}),P({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=o.dirname(t);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.kind?` kind=${e.device.kind}`:"";for(let i of(r.push(`context platform=${e.device.platform} device=${t_(e.device.name)}${a} theme=unknown`),t))i.flags?.noRecord||r.push(function(e){let t=[e.command];if(tS(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tb(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tb(a)),tx(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tb(r)),tx(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tb(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tb(a)),e.positionals.length>1&&t.push(tb(i)),tx(t,e),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tb(r)),t.push(tb(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tb(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tb(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tb(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}if("open"===e.command)return tC(t,e),t.join(" ");if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tN(r,tM)),tD(t,e.flags),t.join(" ")}if("record"===e.command)return tP(t,e),t.join(" ");for(let r of e.positionals??[])t.push(tb(r));return tx(t,e),t.join(" ")}(i));return`${r.join("\n")}
|
|
2
|
+
`}(e,this.buildOptimizedActions(e));i.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=tE.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return o.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return o.join(this.sessionsDir,tE.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return o.join(this.sessionsDir,tE.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return g(e,{cwd:t})}resolveScriptPath(e){if(e.saveScriptPath)return tE.expandHome(e.saveScriptPath);i.existsSync(this.sessionsDir)||i.mkdirSync(this.sessionsDir,{recursive:!0});let t=tE.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return o.join(this.sessionsDir,`${t}-${r}.ad`)}buildOptimizedActions(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let a=Array.isArray(r.result?.selectorChain)&&r.result?.selectorChain.every(e=>"string"==typeof e)?r.result.selectorChain:[];if(a.length>0&&(tS(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(tS(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=tm(r);if(a.length>0){t.push({...r,positionals:[e,a]});continue}}if("get"===r.command){let a=r.positionals?.[0];if("text"===a||"attrs"===a){t.push({...r,positionals:[a,e]});continue}}}if(tS(r.command)||"fill"===r.command||"get"===r.command){let a=r.result?.refLabel;"string"==typeof a&&a.trim().length>0&&t.push({ts:r.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:a.trim()},result:{scope:a.trim()}})}t.push(r)}return t}}let tT=["platform","device","udid","serial","out","verbose","metroHost","metroPort","bundleUrl","launchUrl","snapshotInteractiveOnly","snapshotCompact","snapshotDepth","snapshotScope","snapshotRaw","screenshotFullscreen","relaunch","saveScript","noRecord","fps","quality","hideTouches","count","intervalMs","delayMs","holdMs","jitterPx","doubleTap","clickButton","pauseMs","pattern"],t$="app-log.pid";function tU(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 tF(e,t){if(!e)return;let r=o.dirname(e);i.existsSync(r)||i.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:L(t)??void 0,command:O(t)??void 0};i.writeFileSync(e,`${JSON.stringify(a)}
|
|
3
|
+
`)}function tG(e){if(e&&i.existsSync(e))try{i.unlinkSync(e)}catch{}}async function tV(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}async function tj(e){await new Promise(t=>setTimeout(t,e))}function tq(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],a="",i=a=>{(!(r.length>0)||r.some(e=>a.includes(e)))&&e.write(function(e,t){if(0===t.length)return e;let r=e;for(let e of t)r=r.replace(e,"[REDACTED]");return r}(a,t.redactionPatterns))};return{onChunk:e=>{let t=`${a}${e}`.split("\n");for(let e of(a=t.pop()??"",t))i(`${e}
|
|
4
|
+
`)},flush:()=>{a&&(i(a),a="")}}}function tH(e,t,r){let a=e.stdout,i=e.stderr;return a&&i?(a.setEncoding("utf8"),i.setEncoding("utf8"),a.on("data",r.writer.onChunk),i.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(a=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),a({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}function tB(e){if(!/^[a-zA-Z0-9._:-]+$/.test(e))throw new T("INVALID_ARGS",`Invalid Android package name for logs: ${e}`)}async function tK(e,t){let r=(await U("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tz(e,t){var r,a;let i;tB(t);let n=await tK(e,t),o=await U("adb",["-s",e,"logcat","-d","-v","time","-t","4000"],{allowFailure:!0,timeoutMs:3e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=function(e,t,r){let a=new Set;for(let i of(r&&a.add(r),e.split("\n")))if(i.includes(t))for(let e of function(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=[RegExp(`\\bStart proc\\s+(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`\\b(\\d+):${r}(?:\\b|/)`,"i"),RegExp(`${r}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,"i"),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${r}`,"i")],i=[];for(let t of a){let r=t.exec(e),a=r?.[1];a&&/^\d+$/.test(a)&&i.push(a)}return i}(i,t))a.add(e);return[...a]}(o.stdout,t,n);if(0===s.length)return null;let l=(r=o.stdout,a=t,i=new Set(s),r.split("\n").filter(e=>{var t;let r;if(!e.trim())return!1;if(e.includes(a))return!0;let n=(t=e,r=/\(\s*(\d+)\)\s*:/.exec(t),r?.[1]??null);return!!n&&i.has(n)}).join("\n"));return 0===l.trim().length?null:{pid:n,text:l,recoveredPids:s}}async function tW(e,t,r,a,i){let n,o,l="recovering",d=!1,u=(async()=>{try{for(;!d;){let u=await tK(e,t);if(!u){l="recovering",await tj(1e3);continue}let c=s("adb",["-s",e,"logcat","-v","time","--pid",u],{stdio:["ignore","pipe","pipe"]});n=c;let f=tq(r,{redactionPatterns:a});if(o=tH(c,r,{endStreamOnClose:!1,writer:f}),"number"==typeof c.pid&&(tF(i,c.pid),l="active"),await o,tG(i),n=void 0,o=void 0,d)break;l="recovering",await tj(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tG(i)}})();return{backend:"android",getState:()=>l,startedAt:Date.now(),wait:u,stop:async()=>{d=!0,n&&!n.killed&&n.kill("SIGINT"),o&&await tV(o),n&&!n.killed&&n.kill("SIGKILL"),await tV(u),tG(i)}}}function tJ(e){return`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}"`}async function tZ(e){let{deviceId:t,appBundleId:r,startedAt:a,simulatorSetPath:i}=e,n=V(["spawn",t,"log","show","--style","compact","--info","--predicate",tJ(r)],{simulatorSetPath:i});"number"==typeof a&&Number.isFinite(a)&&a>0?n.push("--start",`@${Math.floor(a/1e3)}`):n.push("--last","5m");let o=await U("xcrun",n,{allowFailure:!0,timeoutMs:4e3});if(0!==o.exitCode||0===o.stdout.trim().length)return null;let s=o.stdout.split("\n").map(e=>e.trimEnd()).filter(e=>{let t=e.trim();return t.length>0&&!t.startsWith("Timestamp Ty Process[PID:TID]")});return 0===s.length?null:{text:`${s.join("\n")}
|
|
5
|
+
`,recoveredLineCount:s.length}}async function tX(e,t,r,a,i,n){let o="active",l=s("xcrun",function(e){let{deviceId:t,appBundleId:r,simulatorSetPath:a}=e;return V(["spawn",t,"log","stream","--style","compact","--level","info","--predicate",tJ(r)],{simulatorSetPath:a})}({deviceId:e,appBundleId:t,simulatorSetPath:i}),{stdio:["ignore","pipe","pipe"]}),d=tq(r,{redactionPatterns:a});"number"==typeof l.pid&&tF(n,l.pid);let u=tH(l,r,{endStreamOnClose:!0,writer:d}).then(e=>(0!==e.exitCode&&(o="failed"),tG(n),e));return{backend:"ios-simulator",getState:()=>o,startedAt:Date.now(),wait:u,stop:async()=>{l.killed||l.kill("SIGINT"),await tV(u),l.killed||l.kill("SIGKILL"),await tV(u),tG(n)}}}async function tY(e,t,r,a){let i="active",n=s("log",["stream","--style","compact","--predicate",tJ(e)],{stdio:["ignore","pipe","pipe"]}),o=tq(t,{redactionPatterns:r});"number"==typeof n.pid&&tF(a,n.pid);let l=tH(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tG(a),e));return{backend:"macos",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tV(l),n.killed||n.kill("SIGKILL"),await tV(l),tG(a)}}}async function tQ(e,t,r,a){let i="active",n=s("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tq(t,{redactionPatterns:r});"number"==typeof n.pid&&tF(a,n.pid);let l=tH(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),tG(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:l,stop:async()=>{n.killed||n.kill("SIGINT"),await tV(l),n.killed||n.kill("SIGKILL"),await tV(l),tG(a)}}}let t0=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b\\s+https?:\\/\\/","i"),t1=/https?:\/\/[^\s"'<>\])]+/i,t2=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function t3(e,t,r=e.limits.maxEntries){let a=[...e.entries],i=new Set(a.map(e=>t4(e)));for(let e of t.entries){let t=t4(e);if(!i.has(t)&&(i.add(t),a.push(e),a.length>=r))break}return{...e,matchedLines:a.length,entries:a}}function t8(e,t){let r=rn(t?.maxEntries,25,1,200),a=t?.backend,i=t?.include??"summary",n=rn(t?.maxPayloadChars,2048,64,16384),o=rn(t?.maxScanLines,4e3,100,2e4),s=e.split("\n"),l=Math.max(0,s.length-o),d=s.slice(l),u=[];for(let e=d.length-1;e>=0&&u.length<r;e-=1){let t=d[e];if(!t?.trim())continue;let r=function(e,t,r,a,i,n){let o=e[t]?.trim();if(!o)return null;let s=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(o),l=rt(s,["method","httpMethod"]),d=rt(s,["url","requestUrl"]),u=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(s,["status","statusCode","responseCode"]),c=t0.exec(o),f=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(o),p=(l??f?.[1]??c?.[1])?.toUpperCase(),m=t1.exec(o),h=d??m?.[0];if(!h)return null;let g=u??t9(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:t6(o),packetId:t7(o)??void 0,durationMs:re(o)??void 0,raw:ri(o,n),line:r};if("android"===a&&function(e,t,r){let a=t5(t,r,5),i=e.packetId??a.map(e=>t7(e)).find(e=>"string"==typeof e&&e.length>0);i&&(e.packetId=i);let n=i?t5(t,r,12).filter(e=>t7(e)===i):a;e.timestamp||(e.timestamp=n.map(e=>t6(e)).find(e=>"string"==typeof e&&e.length>0)),void 0===e.status&&(e.status=n.map(e=>t9(e)).find(e=>"number"==typeof e)),void 0===e.durationMs&&(e.durationMs=n.map(e=>re(e)).find(e=>"number"==typeof e))}(w,e,t),"headers"===i||"all"===i){let e=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return ra(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(o,s);e&&(w.headers=ri(e,n))}if("body"===i||"all"===i){let e=rr(o,s,["requestBody","body","payload","request"]),t=rr(o,s,["responseBody","response"]);e&&(w.requestBody=ri(e,n)),t&&(w.responseBody=ri(t,n))}return w}(d,e,l+e+1,a,i,n);r&&u.push(r)}return{path:t?.path??"<memory>",exists:!0,scannedLines:d.length,matchedLines:u.length,entries:u,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:o}}}function t4(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw}`}function t5(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 t9(e){for(let t of t2){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}function t6(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);if(t)return t[0];let r=/\b\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\b/.exec(e);return r?.[0]}function t7(e){let t=/\bpacket id (\d+)\b/i.exec(e);return t?.[1]??null}function re(e){let t=/\b(?:duration|elapsed request\/response time, ms)[:= ]+(\d+)\b/i.exec(e);if(!t)return null;let r=Number.parseInt(t[1]??"",10);return Number.isInteger(r)?r:null}function rt(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function rr(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return ra(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(a?.[1])return a[1].trim()}}function ra(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function ri(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function rn(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}function ro(e,t){let r=process.env[e];if(!r)return t;let a=Number.parseInt(r,10);return Number.isInteger(a)&&a>0?a:t}function rs(e){let t=o.dirname(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),function(e,t){if(i.existsSync(e)&&!(i.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;i.existsSync(t)&&(i.existsSync(a)&&i.unlinkSync(a),i.renameSync(t,a))}}(e,{maxBytes:ro("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:ro("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function rl(e){var t,r,a,n;let o,s,l,d,{device:u,appBundleId:c,appLogState:f,appLogStartedAt:p,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y}=e,v="macos"===u.platform?"macos":"ios"===u.platform?"device"===u.kind?"ios-device":"ios-simulator":"android",I=(t={backend:v,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y},o=rn(t?.maxEntries,25,1,200),s=t?.include??"summary",l=rn(t?.maxPayloadChars,2048,64,16384),d=rn(t?.maxScanLines,4e3,100,2e4),i.existsSync(m)?t8(i.readFileSync(m,"utf8"),{...t,path:m}):{path:m,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:s,limits:{maxEntries:o,maxPayloadChars:l,maxScanLines:d}}),S=[],A=await rd({device:u,appBundleId:c,appLogPath:m,appLogState:f});if(A){let e=await tz(u.id,c);if(e){let t=t8(e.text,{path:`${m} (adb logcat recovery)`,backend:"android",maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});t.entries.length>0&&(I=t3(t,I,h),S.push((r=A,a=e.recoveredPids,"stale-active"===r.reason?`Session app log stream was still bound to prior Android PID ${r.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${a.join(", ")}.`)))}}if("ios"===u.platform&&"simulator"===u.kind&&c&&0===I.entries.length){let e=await rc({deviceId:u.id,appBundleId:c,startedAt:p,simulatorSetPath:u.simulatorSetPath,appLogPath:m,maxEntries:h,include:g,maxPayloadChars:w,maxScanLines:y});e&&(e.dump.entries.length>0?(I=t3(e.dump,I,h),S.push(`Recovered ${e.dump.entries.length} iOS simulator HTTP entr${1===e.dump.entries.length?"y":"ies"} from simctl log show (${e.recoveredLineCount} app log lines scanned).`)):e.recoveredLineCount>0&&S.push(`Recovered ${e.recoveredLineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return void 0===f?S.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."):"active"!==f&&0===S.length&&("ios"===u.platform&&"simulator"===u.kind?S.push("Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop."):S.push("Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.")),0===I.entries.length&&S.push("ios"===(n=u).platform&&"simulator"===n.kind?"No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.":"ios"===n.platform?"No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.":"No HTTP(s) entries were found in recent session app logs."),{backend:v,dump:I,notes:S}}async function rd(e){let{device:t,appBundleId:r,appLogPath:a,appLogState:n}=e;if("android"!==t.platform||!r)return null;if(void 0!==n&&"active"!==n)return{reason:"inactive"};if("active"!==n)return null;let s=function(e){let t=function(e){if(!e||!i.existsSync(e))return null;try{return tU(i.readFileSync(e,"utf8"))}catch{return null}}(e)?.command;if(!t)return null;let r=/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(t);return r?.[1]??null}(o.join(o.dirname(a),t$));if(!s)return null;let l=await tK(t.id,r);return l&&l!==s?{reason:"stale-active",trackedPid:s}:null}async function ru(e,t,r,a){rs(r);let n=i.createWriteStream(r,{flags:"a"}),o=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await tQ(e.id,n,o,a):await tX(e.id,t,n,o,e.simulatorSetPath,a);if("android"===e.platform)return tB(t),await tW(e.id,t,n,o,a);if("macos"===e.platform)return await tY(t,n,o,a);throw n.end(),new T("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function rc(e){let t=await tZ({deviceId:e.deviceId,appBundleId:e.appBundleId,startedAt:e.startedAt,simulatorSetPath:e.simulatorSetPath});return t?{dump:t8(t.text,{path:`${e.appLogPath} (simctl log show recovery)`,backend:"ios-simulator",maxEntries:e.maxEntries,include:e.include,maxPayloadChars:e.maxPayloadChars,maxScanLines:e.maxScanLines}),recoveredLineCount:t.recoveredLineCount}:null}async function rf(e){await e.stop(),await tV(e.wait)}async function rp(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await U("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await U("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await U("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await U("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}if("macos"===e.platform)try{let e=await U("log",["help"],{allowFailure:!0});r.logAvailable=0===e.exitCode}catch{r.logAvailable=!1}return{checks:r,notes:a}}function rm(e){let t=o.dirname(e),r=o.basename(e);i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(e)?i.truncateSync(e,0):i.writeFileSync(e,"","utf8");let a=0;for(let e of i.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{i.unlinkSync(o.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let rh=new Map;function rg(e){let t=rh.get(e);if(t&&(clearTimeout(t.timer),rh.delete(e),t.deleteAfterDownload))try{i.rmSync(t.artifactPath,{force:!0})}catch{}}let rw=new Map;function ry(e,t){let r=rw.get(e);if(!r)throw new T("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}function rv(e){let t=rw.get(e);t&&(clearTimeout(t.timer),rw.delete(e),i.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function rI(e){let t=await rS(e);await U("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=o.join(e.tempDir,t);if(!i.existsSync(r))throw new T("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function rS(e){let t=await U("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new T("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new T("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(rA),i=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new T("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new T("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new T("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===i||e.startsWith(`${i}/`)))throw new T("INVALID_ARGS",`Uploaded archive must contain a top-level "${i}" bundle`);for(let e of a){var n=e,o=i;if(n!==o&&!n.startsWith(`${o}/`))throw new T("INVALID_ARGS",`Archive entry must stay inside top-level "${o}" bundle: ${n}`)}for(let t of(await U("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean))if("l"===t[0]||"h"===t[0])throw new T("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links");return i}function rA(e){if(e.includes("\0"))throw new T("INVALID_ARGS",`Invalid archive entry: ${e}`);if(o.posix.isAbsolute(e))throw new T("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=o.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new T("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t}let rb=Z(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function r_(e,t){return new Promise((r,a)=>{let n,o=i.createWriteStream(t),s=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},l=!1,d=0,u=e=>{if(!l){if(l=!0,n&&clearTimeout(n),e){o.destroy(),i.rmSync(t,{force:!0}),a(e);return}r()}},c=()=>{n&&clearTimeout(n),n=setTimeout(()=>{let e=new T("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:rb});s(e),o.destroy(e),u(e)},rb)};e.on("data",e=>{c();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((d+=t)>0x80000000){let e=new T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");s(e),o.destroy(e),u(e)}}),e.on("error",u),e.on("aborted",()=>{u(new T("COMMAND_FAILED","Artifact transfer was interrupted"))}),o.on("error",u),o.on("finish",()=>u()),c(),e.pipe(o)})}async function rN(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new T("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new T("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new T("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=o.basename(t);if(!r||"."===r||".."===r)throw new T("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),s=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),i.mkdtempSync(o.join(c.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=o.join(s,n);return await r_(e,t),{artifactPath:t,tempDir:s}}let t=o.join(s,"artifact.tar");await r_(e,t);let a=await rI({archivePath:t,tempDir:s,platform:"ios",expectedRootName:n});return i.rmSync(t,{force:!0}),{artifactPath:a,tempDir:s}}catch(e){throw i.rmSync(s,{recursive:!0,force:!0}),e}}let rk=new Set(["agent_device.command","agent-device.command"]),rM=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),rx=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),rD={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},rP=new Set([...rk,...rM,...rx,...Object.keys(rD)]);function rL(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function rR(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function rO(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function rC(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function rE(e,t){let r=e[t];return"string"==typeof r?r:void 0}function rT(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function r$(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=E(new T("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:rL(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=E(new T(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:rL(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=S(r.tenantId);if(!e){let e=E(new T("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:rL(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function rU(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=o.isAbsolute(t)?t:o.resolve(t);try{e=await import(u(a).href)}catch(e){throw new T("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let i=e[r];if("function"!=typeof i)throw new T("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return i}async function rF(e){let t=await rU(),{handleRequest:r,token:a}=e;return l.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void rG(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void rV(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||rR(i,rL(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{rR(i,rL(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void rR(i,rL(a.id??null,-32600,"Invalid Request"),400);if(!rP.has(a.method))return void rR(i,rL(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void rR(i,rL(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(rk.has(e))return{token:rC(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(rM.has(e)){let e,a=rE(t,"platform");if("ios"!==a&&"android"!==a)throw new T("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:rC(t,r),session:rE(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:rE(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new T("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new T("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new T("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new T("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new T("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:rT(t,"retentionMs")}}}if(rx.has(e)){let e=rE(t,"materializationId")?.trim();if(!e)throw new T("INVALID_ARGS","Invalid params: materializationId is required");return{token:rC(t,r),session:rE(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:rE(t,"requestId"),materializationId:e}}}let a=rD[e];if(a)return{token:rC(t,r),session:rE(t,"session")??"default",command:a,positionals:[],meta:{tenantId:rE(t,"tenantId")??rE(t,"tenant"),runId:rE(t,"runId"),leaseId:rE(t,"leaseId"),leaseTtlMs:rT(t,"ttlMs"),leaseBackend:rE(t,"backend")}};throw new T("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,rk.has(s)&&("string"!=typeof l.command||0===l.command.length))return void rR(i,rL(a.id??null,-32602,"Invalid params: command is required"),400);o=eC(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},ed(o);let d=()=>{i.writableFinished||eG(o)};e.on("aborted",d),i.on("close",d);let u=await r$(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void rR(i,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void rR(i,{jsonrpc:"2.0",id:a.id??null,result:c});rR(i,rL(a.id??null,-32e3,c.error.message,c.error),rO(c.error.code))}catch(t){let e=E(t);rR(i,rL(a.id??null,-32e3,e.message,e),rO(e.code))}finally{ez(o)}})})}async function rG(e,t,r,i){try{var n;let o,s,l=rC({},e.headers),d=rj(l,i);if(d){t.statusCode=rO(d.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.message,code:d.code}));return}let u=await r$(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:l,session:"default",command:"upload",positionals:[]}});if(!u.ok){t.statusCode=u.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:u.response.error?.data?.message??u.response.error?.message??"Unauthorized"}));return}let c=await rN(e),f=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:u.tenantId},o=a.randomUUID(),(s=setTimeout(()=>{rv(o)},3e5)).unref(),rw.set(o,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:s}),o);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:f}))}catch(r){let e=E(r);t.statusCode=rO(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function rV(e,t,r,a){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let o=rC({},e.headers),s=rj(o,a);if(s){t.statusCode=rO(s.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.message,code:s.code}));return}let l=await r$(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:o,session:"default",command:"download_artifact",positionals:[n]}});if(!l.ok){t.statusCode=l.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.response.error?.data?.message??l.response.error?.message??"Unauthorized"}));return}let d=function(e,t){let r=rh.get(e);if(!r)throw new T("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Artifact belongs to a different tenant");if(!i.existsSync(r.artifactPath))throw rg(e),new T("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,l.tenantId),u=i.createReadStream(d.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),d.fileName&&t.setHeader("content-disposition",`attachment; filename="${d.fileName.replace(/"/g,"")}"`),u.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=E(e);t.statusCode=rO(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&rg(n)}),u.pipe(t)}catch(r){let e=E(r);t.statusCode=rO(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function rj(e,t){return t&&e!==t?E(new T("UNAUTHORIZED","Invalid token")):null}function rq(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rH(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function rB(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";if("ios-instance"===t||"android-instance"===t)return t;throw new T("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class rK{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=rB(e.backend),r=S(e.tenantId);if(!r)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=rq(e.runId);if(!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),o=this.bindingKey(r,i,t),s=this.runBindings.get(o);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(o)}this.enforceCapacity(t);let l=this.now(),d={leaseId:a.randomBytes(16).toString("hex"),tenantId:r,runId:i,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(d.leaseId,d),this.runBindings.set(o,d.leaseId),{...d}}heartbeatLease(e){let t=rH(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=rH(e.leaseId);if(!t)throw new T("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=rB(e.backend),r=S(e.tenantId);if(!r)throw new T("INVALID_ARGS","tenant isolation requires tenant id.");let a=rq(e.runId);if(!a)throw new T("INVALID_ARGS","tenant isolation requires run id.");let i=rH(e.leaseId);if(!i)throw new T("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new T("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new T("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new T("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=S(t),i=rq(r);if(t&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new T("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new T("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}let rz=Z(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),rW=new Map;async function rJ(e){let t=await f.mkdtemp(o.join(c.tmpdir(),"agent-device-materialized-"));try{let r=await rY(e.installablePath,o.join(t,"installable")),i=e.archivePath?await rY(e.archivePath,o.join(t,"archive")):void 0,n=a.randomUUID(),s=e.ttlMs??rz,l=Date.now()+s,d=setTimeout(()=>{rZ(n)},s);return rW.set(n,{rootPath:t,installablePath:r,archivePath:i,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:l,timer:d}),{materializationId:n,installablePath:r,...i?{archivePath:i}:{},expiresAt:new Date(l).toISOString()}}catch(e){throw await f.rm(t,{recursive:!0,force:!0}),e}}async function rZ(e,t){let r=rW.get(e);if(!r)throw new T("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new T("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),rW.delete(e),await f.rm(r.rootPath,{recursive:!0,force:!0})}async function rX(e){let t=Array.from(rW.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await rZ(e)}))}async function rY(e,t){let r=await f.stat(e);await f.mkdir(t,{recursive:!0});let a=o.join(t,o.basename(e));return r.isDirectory()?await f.cp(e,a,{recursive:!0}):await f.copyFile(e,a),a}async function rQ(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new T("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await eB(e.session.device),e.session.device}if(!r)throw new T("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await eh(e.flags??{});return await eB(a),a}async function r0(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n,o,s=(n=function(e){let t=e.meta?.installSource;if(!t)throw new T("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new T("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new T("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),(o=t.meta?.uploadedArtifactId)&&"path"===n.kind?{source:{kind:"path",path:ry(o,t.meta?.tenantId)},cleanup:()=>{rv(o)}}:{source:n,cleanup:()=>{}}),l=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new T("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),d=await rQ({session:i,flags:t.flags});if(!ep("install",d))return eq("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=e3(t.meta?.requestId);if("ios"===d.platform){let e,{installIosInstallablePath:n}=await import("./3918.js"),{prepareIosInstallArtifact:o}=await import("./3918.js"),c=await o(s.source,{signal:u});try{if(l.enabled&&(e=await rJ({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs})),await n(d,c.installablePath),!c.bundleId)throw new T("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let o={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},s=e9(o,r1(o));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:s}),{ok:!0,data:s}}catch(r){throw e&&await rZ(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup(),s.cleanup()}}let{prepareAndroidInstallArtifact:c}=await import("./3918.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./3918.js"),p=await c(s.source,{signal:u});try{l.enabled&&(e=await rJ({archivePath:p.archivePath,installablePath:p.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:l.ttlMs}));let n=await f(d,p.installablePath,p.packageName);if(!n)throw new T("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:o}=await import("./3918.js"),s=o(n),u={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:n,...s?{appName:s}:{},launchTarget:n,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}},c=e9(u,r1(u));return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:c}),{ok:!0,data:c}}catch(r){throw e&&await rZ(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await p.cleanup(),s.cleanup()}}catch(e){return{ok:!1,error:E(e)}}}function r1(e){return`Installed: ${D(e)}`}async function r2(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new T("INVALID_ARGS","release_materialized_paths requires a materializationId");return await rZ(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:E(e)}}}let r3=Z(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),r8=Z(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function r4(e,t,r){return t||r5(r)?null:eq("INVALID_ARGS",`${e} requires an active session or an explicit device selector (e.g. --platform ios).`)}function r5(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function r9(e){return"ios"===e.platform&&"simulator"===e.kind}async function r6(e,t){r9(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function r7(e){let t=r5(e.flags)||!e.session?await eh(e.flags??{}):await ae(e.session.device);return!1!==e.ensureReady&&await eB(t),t}async function ae(e){if("ios"!==e.platform||"simulator"!==e.kind||"darwin"!==process.platform)return e;let t={platform:"ios",target:e.target,udid:e.id,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}};try{return await eh(t)}catch(e){if(!(e instanceof T)||"DEVICE_NOT_FOUND"!==e.code)throw e}return await eh({platform:"ios",target:e.target,device:e.name,...e.simulatorSetPath?{iosSimulatorDeviceSet:e.simulatorSetPath}:{}})}function at(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let ar=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function aa(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ai(e){let t=e?.trim();return t&&t.length>0?t:void 0}function an(e,t){if(void 0!==e){if("string"!=typeof e)throw new T("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return ai(e)}}function ao(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new T("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function as(e){if("ios"===e||"android"===e)return e}async function al(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i}=e;!t||!i?.appBundleId||!K(r)||K(a)||await B({device:i.device,appId:i.appBundleId})}async function ad(e){var t,r;let{req:a,sessionName:i,sessionStore:n}=e,o=(a.positionals?.[0]??"show").toLowerCase(),s=n.get(i),l=n.getRuntimeHints(i);if(!["set","show","clear"].includes(o))return eq("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){K(l)&&s?.appBundleId&&await B({device:s.device,appId:s.appBundleId});let e=n.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===o)return{ok:!0,data:{session:i,configured:!!l,runtime:l}};let d=as(e2(a.flags?.platform)??l?.platform??s?.device.platform);if(!d)return eq("INVALID_ARGS","runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first.");if(s&&s.device.platform!==d)return eq("INVALID_ARGS",`runtime set targets ${d}, but session "${i}" is already bound to ${s.device.platform}.`);let u={platform:(t=a.flags,r={platform:d,metroHost:ai(t?.metroHost),metroPort:ao(t?.metroPort),bundleUrl:ai(t?.bundleUrl),launchUrl:ai(t?.launchUrl)}).platform??l?.platform,metroHost:r.metroHost??l?.metroHost,metroPort:r.metroPort??l?.metroPort,bundleUrl:r.bundleUrl??l?.bundleUrl,launchUrl:r.launchUrl??l?.launchUrl};return 0===aa(u)?eq("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(n.setRuntimeHints(i,u),{ok:!0,data:{session:i,configured:!0,runtime:u}})}let au="open-command-roundtrip",ac="Not implemented for this platform in this release.",af=new Set(["app","desktop","frontmost-app"]);async function ap(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eZ();return{appBundleId:t.bundleId,appName:t.appName}}async function am(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return e_(t)?"macos"===e.platform?void 0:"device"===e.kind?eV(r,t):void 0:await ah(e,t)}async function ah(e,t){try{let{resolveIosApp:r}=await import("./3918.js");return await r(e,t)}catch{return}}async function ag(e,t){if(!("android"!==e.platform||!t||e_(t)))try{let{resolveAndroidApp:r}=await import("./3918.js"),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function aw(e,t,r,a){return await am(e,t,r)??await a(e,t)??("android"===e.platform&&t&&e_(t)?r:void 0)}function ay(e){return eq("INVALID_ARGS",e)}function av(e,t,r,a){try{return function(e){let{device:t,surfaceFlag:r,openTarget:a,existingSurface:i}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return i??"app";if("linux"===t.platform){if(!r)return"app";let e=e0(r);if(!af.has(e))throw new T("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&a)throw new T("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new T("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let n=r?e0(r):"app";if("app"!==n&&"menubar"!==n&&a)throw new T("INVALID_ARGS",`open --surface ${n} does not accept an app target`);return n}({device:e,surfaceFlag:t,openTarget:r,existingSurface:a})}catch(e){return eq(e instanceof T?e.code:"INVALID_ARGS",String(e.message))}}function aI(e){let{shouldRelaunch:t,openTarget:r,surface:a,device:i}=e;return t?r&&e_(r)?ay("open --relaunch does not support URL targets."):"app"!==a?ay("open --relaunch is supported only for app surfaces."):"android"===i.platform&&r&&"binary"===G(r)?ay(W(r)):null:null}async function aS(e){let{req:t,sessionName:r,sessionStore:a,device:i,surface:n,openTarget:o,existingSession:s}=e;await eB(i);let{appBundleId:l,appName:d}=await aA({device:i,surface:n,openTarget:o,existingAppBundleId:s?.appBundleId}),u=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new T("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!ar.includes(e));if(i)throw new T("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${ar.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new T("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new T("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:an(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new T("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return ao(e)}}(t.metroPort),bundleUrl:an(t.bundleUrl,"bundleUrl"),launchUrl:an(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:as(i.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(!a)return;let i=r?.platform,n=as(i);if(a.platform&&r&&!n)throw new T("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${i}.`);if(a.platform&&n&&a.platform!==n)throw new T("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${i}. Clear the runtime hints or use a different session.`);return n&&a.platform!==n?{...a,platform:n}:a}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&aa(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=C(t);return eq(e.code,e.message,e.details)}}({req:t,sessionStore:a,sessionName:r,device:i});if(!u.ok)return{type:"response",response:u};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=u.data;await al({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:u.data.runtime}}}async function aA(e){let{device:t,surface:r,openTarget:a,existingAppBundleId:i}=e,n=await ap(r);return{appBundleId:n.appBundleId??await aw(t,a,i,ag),appName:n.appName??a}}let ab=new Map;async function a_(e){let{device:t,closeTarget:r,outFlag:a,context:i}=e;"android"!==t.platform&&await eo(t.id),await Y(t,"close",[r],a,i),await r6(t,r3)}async function aN(e){let{runtime:t,device:r,req:a,logPath:i,appBundleId:n,traceLogPath:o,openPositionals:s}=e,l=t?.launchUrl;if(!l||0===s.length||s.length>1)return;let d=s[0]?.trim();!d||e_(d)||await Y(r,"open",[l],a.flags?.out,{...eL(i,a.flags,n,o)})}async function ak(e){var t,r,a;let{req:i,sessionName:n,sessionStore:o,logPath:s,device:l,openTarget:d,openPositionals:u,appName:c,surface:f,appBundleId:p,runtime:m,existingSession:h}=e,g=i.flags?.relaunch===!0,w=h?.trace?.outPath;if(g&&d){let e=p??d;await a_({device:l,closeTarget:e,outFlag:i.flags?.out,context:{...eL(s,i.flags,p??h?.appBundleId,w)}})}await J({device:l,appId:p,runtime:m});let y=Date.now();await Y(l,"open",u,i.flags?.out,{...eL(s,i.flags,p)}),await aN({runtime:m,device:l,req:i,logPath:s,appBundleId:p,traceLogPath:w,openPositionals:u});let v=d?{durationMs:Math.max(0,Date.now()-y),measuredAt:new Date().toISOString(),method:au,appTarget:d,appBundleId:p}:void 0;if(await r6(l,r8),eO(i.meta?.requestId)){let e=el();return eq(e.code,e.message,e.details)}h&&e8(h,"open",h.snapshot);let I=function(e){let{existingSession:t,sessionName:r,device:a,surface:i,appBundleId:n,appName:o,saveScript:s}=e;return t?{...t,device:a,surface:i,appBundleId:n,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),surface:i,appBundleId:n,appName:o,recordSession:s,actions:[]}}({existingSession:h,sessionName:n,device:l,surface:f,appBundleId:p,appName:c,saveScript:!!i.flags?.saveScript});void 0!==i.runtime&&(t=o,r=n,(a=m)&&(0===aa(a)?t.clearRuntimeHints(r):t.setRuntimeHints(r,a)));let S=function(e){let{sessionName:t,appName:r,appBundleId:a,surface:i,startup:n,device:o,runtime:s,runtimeHintCount:l}=e,d={session:t,surface:i};return r&&(d.appName=r),a&&(d.appBundleId=a),n&&(d.startup=n),s&&l(s)>0&&(d.runtime=s),o&&(d.platform=o.platform,d.target=o.target??"mobile",d.device=o.name,d.id=o.id,d.kind=o.kind,"android"===o.platform&&(d.serial=o.id)),o?.platform==="ios"&&(d.device_udid=o.id,d.ios_simulator_device_set=o.simulatorSetPath??null),{...d,...e7(`Opened: ${r??a??t}`)}}({sessionName:n,appName:c,appBundleId:p,surface:f,startup:v,device:l,runtime:m,runtimeHintCount:aa});return o.recordAction(I,{command:"open",positionals:u,flags:i.flags??{},runtime:void 0!==i.runtime?m:void 0,result:S}),o.set(n,I),{ok:!0,data:S}}async function aM(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e;if(i.has(r)){let e=i.get(r);if(!e)return eq("SESSION_NOT_FOUND",`Session "${r}" not found.`);let n=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(n?e.appName:void 0),l=av(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return n?ay("open --relaunch requires an app name or an active session app."):ay("Session already active. Close it first or pass a new --session name.");let d=aI({shouldRelaunch:n,openTarget:s,surface:l,device:e.device});if(d)return d;let u=await ae(e.device),c=await aS({req:t,sessionName:r,sessionStore:i,device:u,surface:l,openTarget:s,existingSession:e});return"response"===c.type?c.response:await ak({req:t,sessionName:r,sessionStore:i,logPath:a,device:u,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:e})}let n=t.flags?.relaunch===!0,o=t.positionals?.[0];if(n&&!o)return ay("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:a}=e;return t?r&&e_(r)?ay("open --relaunch does not support URL targets."):"android"===a&&r&&"binary"===G(r)?ay(W(r)):null:null}({shouldRelaunch:n,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await eh(t.flags??{}),d=av(l,t.flags?.surface,o);if("string"!=typeof d)return d;let u=aI({shouldRelaunch:n,openTarget:o,surface:d,device:l});return u||await ey(ab,l.id,async()=>{let e=i.toArray().find(e=>e.device.id===l.id);if(e)return eq("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name});let n=await aS({req:t,sessionName:r,sessionStore:i,device:l,surface:d,openTarget:o});return"response"===n.type?n.response:await ak({req:t,sessionName:r,sessionStore:i,logPath:a,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:n.details.appBundleId,appName:n.details.appName,runtime:n.details.runtime,surface:d})})}async function ax(e){let t=await U("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function aD(e){let{device:t,shutdownRequested:r}=e;if(r&&(r9(t)||"android"===t.platform&&"emulator"===t.kind))try{return r9(t)?await en(t):await ax(t)}catch(t){let e=E(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function aP(e){if(await eo(e.device.id),"macos"!==e.device.platform)return;let t="frontmost-app"===e.surface?{surface:"frontmost-app"}:e.appBundleId?{bundleId:e.appBundleId}:{};await eA("dismiss",t).catch(t=>{P({level:"debug",phase:"macos_close_alert_dismiss_failed",data:{session:e.name,error:t instanceof Error?t.message:String(t)}})})}async function aL(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r);if(!n)return eq("SESSION_NOT_FOUND","No active session");n.appLog&&await rf(n.appLog),t.positionals&&t.positionals.length>0&&(("ios"===n.device.platform||"macos"===n.device.platform)&&await aP(n),await Y(n.device,"close",t.positionals,t.flags?.out,{...eL(a,t.flags,n.appBundleId,n.trace?.outPath)}),await r6(n.device,r3)),("ios"===n.device.platform||"macos"===n.device.platform)&&await aP(n),K(i.getRuntimeHints(r))&&n.appBundleId&&await B({device:n.device,appId:n.appBundleId}).catch(()=>{}),i.recordAction(n,{command:"close",positionals:t.positionals??[],flags:t.flags??{},result:{session:r,...e7(`Closed: ${r}`)}}),t.flags?.saveScript&&(n.recordSession=!0),i.writeSessionLog(n),await rX(r).catch(()=>{}),i.delete(r);let o=await aD({device:n.device,shutdownRequested:t.flags?.shutdown});return o?{ok:!0,data:e9({session:r,shutdown:o},`Closed: ${r}`)}:{ok:!0,data:{session:r,...e7(`Closed: ${r}`)}}}let aR=["platform","target","device","udid","serial","verbose","out"];function aO(e,t){let r=e??{};for(let e of aR)void 0===t[e]&&void 0!==r[e]&&(t[e]=r[e]);return t}let aC={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await import("./3918.js");return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await import("./3918.js");return await a(e,t,r)}},aE={ios:async(e,t,r)=>{let{installIosApp:a}=await import("./3918.js"),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await import("./3918.js"),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function aT(e){let{req:t,command:r,sessionName:a,sessionStore:n,deployOps:o}=e,s=n.get(a),l=t.flags??{},d=r4(r,s,l);if(d)return d;let u=t.positionals?.[0]?.trim(),c=t.positionals?.[1]?.trim();if(!u||!c)return eq("INVALID_ARGS",`${r} requires: ${r} <app> <path-to-app-binary>`);let f=t.meta?.uploadedArtifactId;try{var p;let e,a=f?ry(f,t.meta?.tenantId):tE.expandHome(c);if(!i.existsSync(a))return eq("INVALID_ARGS",`App binary not found: ${a}`);let d=await r7({session:s,flags:l,ensureReady:!1});if(!ep(r,d))return eq("UNSUPPORTED_OPERATION",`${r} is not supported on this device`);if("ios"===d.platform){let t=await o.ios(d,u,a),r=t.bundleId;e=r?{app:u,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(d,u,a),r=t.package;e=r?{app:u,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:u,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=e9(e,(p=e,`Installed: ${p.appName??x(p)}`));return s&&n.recordAction(s,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:m??{}}),{ok:!0,data:m}}finally{f&&rv(f)}}async function a$(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return eq("INVALID_ARGS",`Unsupported batch on-error mode: ${a}.`);let i=e.flags?.batchMaxSteps??eI;if(!Number.isInteger(i)||i<1||i>1e3)return eq("INVALID_ARGS",`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`);try{let a=Q(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await aU(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=C(t);return eq(e.code,e.message,e.details)}}async function aU(e,t,r,a,i){let n=Date.now(),o=function(e,t){let{batchSteps:r,batchOnError:a,batchMaxSteps:i,...n}=t??{};return aO(e,n)}(e.flags,r.flags);void 0===o.session&&(o.session=t);let s=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:o,runtime:void 0===r.runtime?e.runtime:r.runtime,meta:e.meta}),l=Date.now()-n;return s.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:s.data??{},durationMs:l}}:{ok:!1,step:i,error:s.error}}async function aF(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new T("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await aG({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await aV({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aj(t,u),a=!0)}else t=(await aV({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await aj(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function aG(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await U("xcrun",V(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:eX});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let[a,i]of Object.entries(e.devices??{}))if(!r||aq(a).includes(aq(r))){for(let e of i)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function aV(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await U("xcrun",V(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new T("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(n.stdout??"").trim();if(!o)throw new T("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function aj(e,t){let r=await U("xcrun",V(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:eX});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,a]of Object.entries(t.devices??{}))if(a.some(t=>t.udid===e))return r;return""}catch{return""}}function aq(e){return e.toLowerCase().replace(/[._-]/g,"")}async function aH(e){let{req:t,sessionName:r,sessionStore:a}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:a.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("ensure-simulator"===t.command)try{let e=t.flags??{},r=e.device,a=e.runtime,i=F(e.iosSimulatorDeviceSet);if(!r)return eq("INVALID_ARGS","ensure-simulator requires --device <name>");let n=await aF({deviceName:r,runtime:a,simulatorSetPath:i,reuseExisting:!1!==e.reuseExisting,boot:!0===e.boot,ensureReady:eB});return{ok:!0,data:{udid:n.udid,device:n.device,runtime:n.runtime,ios_simulator_device_set:i??null,created:n.created,booted:n.booted}}}catch(t){let e=C(t);return eq(e.code,e.message,e.details)}if("devices"===t.command)try{let e=[],r=H(t.flags?.androidDeviceAllowlist),a=e2(t.flags?.platform),i=X({simulatorSetPath:F(t.flags?.iosSimulatorDeviceSet),platform:a,target:t.flags?.target});if("android"===a){let{listAndroidDevices:t}=await import("./3918.js");e.push(...await t({serialAllowlist:r}))}else if("ios"===a||"macos"===a){let{listAppleDevices:t}=await import("./3918.js");e.push(...await t({simulatorSetPath:i}))}else{if("apple"!==a){let{listAndroidDevices:t}=await import("./3918.js");try{e.push(...await t({serialAllowlist:r}))}catch{}}let{listAppleDevices:t}=await import("./3918.js");try{e.push(...await t({simulatorSetPath:i}))}catch{}}let n="ios"===a||"macos"===a?e.filter(e=>e.platform===a):e,o=(t.flags?.target?n.filter(e=>(e.target??"mobile")===t.flags?.target):n).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=C(t);return eq(e.code,e.message,e.details)}if("apps"===t.command){let e=a.get(r),i=t.flags??{},n=r4(t.command,e,i);if(n)return n;let o=await r7({session:e,flags:i,ensureReady:!0});if(!ep("apps",o))return eq("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=t.flags?.appsFilter??"all";if(ea(o.platform)){let{listIosApps:e}=await import("./3918.js");return{ok:!0,data:{apps:(await e(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await import("./3918.js");return{ok:!0,data:{apps:(await l(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function aB(e){let{ensureAndroidEmulatorBooted:t}=await import("./3918.js");return await t(e)}let aK='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',az='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function aW(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n=t.flags??{},o=e2(n.platform);if(!i&&"string"==typeof n?.session&&n.session.trim().length>0)return eq("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=r4("appstate",i,n);if(s)return s;let l=(i?.device.platform==="ios"||i?.device.platform==="macos")&&function(e,t){if(!t)return!1;if(!r5(e))return!0;let r=e2(e?.platform);return!(r&&!eY(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 eq("SESSION_NOT_FOUND",aK);if("macos"===o&&!l)return eq("SESSION_NOT_FOUND",az);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 eq("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:i.device.platform,appName:e??"unknown",appBundleId:i.appBundleId,source:"session",surface:i.surface??"app",..."ios"===i.device.platform?{device_udid:i.device.id,ios_simulator_device_set:i.device.simulatorSetPath??null}:{}}}}let d=await r7({session:i,flags:n,ensureReady:!0});if("ios"===d.platform)return eq("SESSION_NOT_FOUND",aK);if("macos"===d.platform)return eq("SESSION_NOT_FOUND",az);let{getAndroidAppState:u}=await import("./3918.js"),c=await u(d);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function aJ(e){let{req:t,sessionName:r,sessionStore:a}=e;if("boot"===t.command){let e,i=a.get(r),n=t.flags??{},o=r4(t.command,i,n);if(o)return o;let s="android"===(e2(n.platform)??i?.device.platform),l=!0===n.headless;if(l&&!s)return eq("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=at({flags:n,sessionDevice:i?.device}),u=s&&!!d,c=!1;try{e=await r7({session:i,flags:n,ensureReady:!1})}catch(r){let t=C(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return eq("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await aB({avdName:d,serial:n.serial,headless:l}),c=!0}if(n.target&&(e.target??"mobile")!==n.target)return eq("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${n.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return eq("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!c){let t=at({flags:n,sessionDevice:i?.device,resolvedDevice:e});if(!t)return eq("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await aB({avdName:t,serial:n.serial,headless:!0})}await eB(e)}else("android"!==e.platform||!0!==e.booted)&&await eB(e);return ep("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:eq("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await aW({req:t,sessionName:r,sessionStore:a}):null}function aZ(e){return Math.round(10*e)/10}let aX="adb-shell-dumpsys-cpuinfo",aY="adb-shell-dumpsys-meminfo";async function aQ(e,t){try{let r=await U("adb",q(e,["shell","dumpsys","cpuinfo"]),{timeoutMs:15e3});return function(e,t,r){let a=new Set,i=0;for(let r of e.split("\n")){var n,o;let e=r.trim();if(0===e.length)continue;let s=e.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!s)continue;let l=Number(s[1]),d=s[2];Number.isFinite(l)&&(n=d,o=t,n===o||n.startsWith(`${o}:`))&&(i+=l,a.add(d))}return{usagePercent:aZ(i),measuredAt:r,method:aX,matchedProcesses:[...a]}}(r.stdout,t,new Date().toISOString())}catch(e){throw a1("cpu",t,e)}}async function a0(e,t){try{let r=await U("adb",q(e,["shell","dumpsys","meminfo",t]),{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new T("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let a=a2(e,"TOTAL PSS")??function(e){for(let t of e.split("\n")){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let r=e.split(/\s+/).slice(1).find(e=>null!==a3(e));if(!r)break;return a3(r)??void 0}}(e);if(void 0===a)throw new T("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:a,totalRssKb:a2(e,"TOTAL RSS"),measuredAt:r,method:aY}}(r.stdout,t,new Date().toISOString())}catch(e){throw a1("memory",t,e)}}function a1(e,t,r){return r instanceof T&&("TOOL_MISSING"===r.code||"COMMAND_FAILED"===r.code)?new T(r.code,r.message,{...r.details??{},metric:e,package:t},r):r instanceof T?r:new T("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function a2(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(a)return a3(a[1])??void 0}function a3(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}let a8="ps-process-snapshot",a4="ps-process-snapshot",a5="xctrace-activity-monitor",a9="xctrace-activity-monitor";async function a6(e,t){if("ios"===e.platform&&"device"===e.kind)return await it(e,t);let r=await ie(e,t),a=await il(e,r);if(0===a.length)throw new T("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let i=new Date().toISOString(),n=th(a.map(e=>o.basename(id(e.command))));return iu({usagePercent:a.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:a.reduce((e,t)=>e+t.rssKb,0),measuredAt:i,matchedProcesses:n,cpuMethod:a8,memoryMethod:a4})}async function a7(e){let t=eJ(e),r=ic(t,e=>"schema"===e.name&&"activity-monitor-process-live"===e.attributes.name);if(!r)throw new T("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let a=r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}),i=a.indexOf("pid"),n=a.indexOf("process"),o=a.indexOf("cpu-total"),s=a.indexOf("memory-real");if(i<0||n<0||o<0||s<0)throw new T("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let l=function e(t,r){let a=[];for(let i of t)r(i)&&a.push(i),a.push(...e(i.children,r));return a}(t,e=>"row"===e.name),d=[],u=new Map;for(let e of l){var c,f;let t=e.children;if(0===t.length)continue;for(let e of t){let t=ic(e.children,e=>"pid"===e.name&&"string"==typeof e.attributes.id);if(t?.attributes.id){let e=Number(t.text);u.set(t.attributes.id,{numberValue:Number.isFinite(e)?e:null})}e.attributes.id&&u.set(e.attributes.id,{numberValue:ip(e),processName:ih(e)})}let r=im(t[i],u),a=(c=t[n],f=u,c?c.attributes.ref?f.get(c.attributes.ref)?.processName??null:ih(c):null);null!==r&&Number.isFinite(r)&&a&&d.push({pid:r,processName:a,cpuTimeNs:im(t[o],u),residentMemoryBytes:im(t[s],u)})}return d}async function ie(e,t){let r="macos"===e.platform?await io(t):await is(e,t),a="macos"===e.platform?o.join(r,"Contents","Info.plist"):o.join(r,"Info.plist"),i=await eK(a,"CFBundleExecutable");if(!i)throw new T("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?o.join(r,"Contents","MacOS",i):void 0}}async function 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 T("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===n.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new T("COMMAND_FAILED",`Incomplete Activity Monitor sample for ${t}`,{appBundleId:t,deviceId:e.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});return iu({usagePercent:Math.max(0,o.cpuTimeNs-n.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(i.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:a5,memoryMethod:a9})}async function ir(e,t){let r=(await eQ(e,"all")).find(e=>e.bundleId===t);if(!r)throw new T("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new T("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let a=r.url.replace(/\/$/,""),i=d(a),n=(await e1(e)).filter(e=>e.executable.startsWith(`${a}/`));if(0===n.length)throw new T("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:i,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return n}async function ia(e,t){let r=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-ios-perf-")),a=o.join(r,"sample.trace"),i=o.join(r,"activity-monitor-process-live.xml");try{let r=["xctrace","record","--template","Activity Monitor","--device",e.id,"--all-processes","--time-limit","1s","--output",a,"--quiet","--no-prompt"],o=await U("xcrun",r,{allowFailure:!0,timeoutMs:6e4}),s=Date.now();if(0!==o.exitCode)throw new T("COMMAND_FAILED",`Failed to record iOS device Activity Monitor sample for ${t}`,{cmd:"xcrun",args:r,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:ig(o.stdout,o.stderr)});let l=["xctrace","export","--input",a,"--xpath",'/trace-toc/run/data/table[@schema="activity-monitor-process-live"]',"--output",i],d=await U("xcrun",l,{allowFailure:!0,timeoutMs:15e3});if(0!==d.exitCode)throw new T("COMMAND_FAILED",`Failed to export iOS device perf sample for ${t}`,{cmd:"xcrun",args:l,exitCode:d.exitCode,stdout:d.stdout,stderr:d.stderr,appBundleId:t,deviceId:e.id,hint:ig(d.stdout,d.stderr)});return{capturedAtMs:s,xml:await n.readFile(i,"utf8")}}finally{await n.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function ii(e,t,r,a){let i=new Set(t.map(e=>e.pid)),n=new Set(t.map(e=>o.basename(d(e.executable)))),s=e.filter(e=>i.has(e.pid)||n.has(e.processName));if(0===s.length)throw new T("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:a.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let l=new Map;for(let e of s){let t=l.get(e.pid);if(!t){l.set(e.pid,e);continue}l.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:iw(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:iw(t.residentMemoryBytes,e.residentMemoryBytes)})}let u=[...l.values()],c=u.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=u.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:c.length>0?c.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:th(u.map(e=>e.processName))}}async function io(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await U("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new T("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!a)throw new T("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return a}async function is(e,t){let r=z(e,["get_app_container",e.id,t,"app"]),a=await U("xcrun",r,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode)throw new T("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let i=a.stdout.trim();if(0===i.length)throw new T("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return i}async function il(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:z(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of e.split("\n")){let e=r.trim();if(0===e.length)continue;let a=e.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!a)continue;let i=Number(a[1]),n=Number(a[2]),o=Number(a[3]),s=a[4].trim();Number.isFinite(i)&&Number.isFinite(n)&&Number.isFinite(o)&&t.push({pid:i,cpuPercent:n,rssKb:o,command:s})}return t})((await U("macos"===e.platform?"ps":"xcrun",r,{timeoutMs:15e3})).stdout).filter(e=>{var r,a;let i;return r=e.command,a=t,i=id(r),!!(a.executablePath&&(i===a.executablePath||r.startsWith(`${a.executablePath} `)))||o.basename(i)===a.executableName})}function id(e){let[t=""]=e.trim().split(/\s+/,1);return t}function iu(e){return{cpu:{usagePercent:aZ(e.usagePercent),measuredAt:e.measuredAt,method:e.cpuMethod,matchedProcesses:e.matchedProcesses},memory:{residentMemoryKb:Math.round(e.residentMemoryKb),measuredAt:e.measuredAt,method:e.memoryMethod,matchedProcesses:e.matchedProcesses}}}function ic(e,t){for(let r of e){if(t(r))return r;let e=ic(r.children,t);if(e)return e}}function ip(e){if(!e||e.children.some(e=>"sentinel"===e.name)||!e.text)return null;let t=Number(e.text);return Number.isFinite(t)?t:null}function im(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:ip(e):null}function ih(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function ig(e,t){let r=ec(e,t);if(r)return r;let a=`${e}
|
|
6
|
+
${t}`.toLowerCase();return a.includes("no device matched")||a.includes("failed to find device")?ex:a.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function iw(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function iy(e){var t;let r=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===au&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:au,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}(e.actions),a=r.at(-1),i=a?{available:!0,lastDurationMs:a.durationMs,lastMeasuredAt:a.measuredAt,method:au,sampleCount:r.length,samples:r}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:au},n={session:e.name,platform:e.device.platform,device:e.device.name,deviceId:e.device.id,metrics:{startup:i,fps:{available:!1,reason:ac},memory:{available:!1,reason:ac},cpu:{available:!1,reason:ac}},sampling:{startup:{method:au,description:"Elapsed wall-clock time around dispatching the open command for the active session app target.",unit:"ms"},...function(e){if("android"===e.device.platform)return{memory:{method:aY,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:aX,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"}};var t=e.device;if("ios"===t.platform&&"device"===t.kind)return{memory:{method:a9,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:a5,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:a4,description:`Resident memory snapshot from ${r}`,unit:"kB"},cpu:{method:a8,description:`Recent CPU usage snapshot from ${r}`,unit:"percent"}}}(e)}};if("android"!==(t=e).device.platform&&"ios"!==t.device.platform&&"macos"!==t.device.platform)return n;if(!e.appBundleId){let t="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.";return n.metrics.memory={available:!1,reason:t},n.metrics.cpu={available:!1,reason:t},n}let[o,s]=await iv(e);return n.metrics.memory=iI(o),n.metrics.cpu=iI(s),n}async function iv(e){let t=e.appBundleId;if("android"===e.device.platform){let[r,a]=await Promise.allSettled([a0(e.device,t),aQ(e.device,t)]);return[r,a]}try{let r=await a6(e.device,t);return[{status:"fulfilled",value:r.memory},{status:"fulfilled",value:r.cpu}]}catch(e){return[{status:"rejected",reason:e},{status:"rejected",reason:e}]}}function iI(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=E(e.reason);return{available:!1,reason:t.message,error:t}}let iS=["path","start","stop","doctor","mark","clear"],iA=`logs requires ${iS.slice(0,-1).join(", ")}, or ${iS.at(-1)}`,ib=["dump","log"],i_=`network requires ${ib.join(" or ")}`,iN=["summary","headers","body","all"],ik=`network include mode must be one of: ${iN.join(", ")}`;async function iM(e){let{req:t}=e;return"perf"===t.command?ix(e):"logs"===t.command?iD(e):"network"===t.command?iC(e):null}async function ix(e){let{sessionName:t,sessionStore:r}=e,a=r.get(t);if(!a)return eq("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await iy(a)}}catch(e){return{ok:!1,error:E(e)}}}async function iD(e){let{req:t,sessionName:r,sessionStore:a}=e,n=a.get(r);if(!n)return eq("SESSION_NOT_FOUND","logs requires an active session");if(!ep("logs",n.device))return eq("UNSUPPORTED_OPERATION","logs is not supported on this device");let o=(t.positionals?.[0]??"path").toLowerCase(),s=!!t.flags?.restart;return iS.includes(o)?s&&"clear"!==o?eq("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===o?function(e,t,r){let a=r.resolveAppLogPath(t),n=function(e){if(!i.existsSync(e))return{exists:!1,sizeBytes:0};let t=i.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(a);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:n.sizeBytes,modifiedAt:n.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(n,r,a):"doctor"===o?iP(n,r,a):"mark"===o?function(e,t,r){let a,n=e.positionals?.slice(1).join(" ")??"",o=r.resolveAppLogPath(t);return rs(o),a=`[agent-device][mark][${new Date().toISOString()}] ${n.trim()||"marker"}
|
|
7
|
+
`,i.appendFileSync(o,a,"utf8"),{ok:!0,data:{path:o,marked:!0}}}(t,r,a):"clear"===o?iL(n,r,a,s):"start"===o?iR(n,r,a):"stop"===o?iO(n,r,a):eq("INVALID_ARGS",iA):eq("INVALID_ARGS",iA)}async function iP(e,t,r){let a=r.resolveAppLogPath(t),i=await rp(e.device,e.appBundleId);return{ok:!0,data:{path:a,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:i.checks,notes:i.notes}}}async function iL(e,t,r,a){if(e.appLog&&!a)return eq("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(a&&!e.appBundleId)return eq("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let i=r.resolveAppLogPath(t);if(!a)return{ok:!0,data:rm(i)};e.appLog&&await rf(e.appLog);let n=rm(i),o=r.resolveAppLogPidPath(t);try{let a=await ru(e.device,e.appBundleId,i,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:i,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}}),{ok:!0,data:{...n,restarted:!0}}}catch(a){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:E(a)}}}async function iR(e,t,r){if(e.appLog)return eq("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return eq("INVALID_ARGS","logs start requires an app session; run open <app> first");let a=r.resolveAppLogPath(t),i=r.resolveAppLogPidPath(t);try{let n=await ru(e.device,e.appBundleId,a,i);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{path:a,started:!0}}}catch(e){return{ok:!1,error:E(e)}}}async function iO(e,t,r){if(!e.appLog)return eq("INVALID_ARGS","no app log stream active");let a=e.appLog.outPath;return await rf(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:a,stopped:!0}}}async function iC(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eq("SESSION_NOT_FOUND","network requires an active session");if(!ep("network",i.device))return eq("UNSUPPORTED_OPERATION","network is not supported on this device");let n=(t.positionals?.[0]??"dump").toLowerCase();if(!ib.includes(n))return eq("INVALID_ARGS",i_);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return eq("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 eq("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let a=(r??t??"summary").toLowerCase();return iN.includes(a)?{ok:!0,include:a}:eq("INVALID_ARGS",ik)}(t);if(!s.ok)return s;let{include:l}=s,d=await rl({device:i.device,appBundleId:i.appBundleId,appLogState:i.appLog?.getState(),appLogStartedAt:i.appLog?.startedAt,appLogPath:a.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...d.dump,active:!!i.appLog,state:i.appLog?.getState()??"inactive",backend:d.backend,notes:d.notes}}}let iE=new Set(["ios","android","macos","linux"]);function iT(e,t,r){let a=e[t];if(void 0!==a)throw new T("INVALID_ARGS",a===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(a)} vs ${String(r)}.`);e[t]=r}function i$(e){return!!e&&!Number.isNaN(Number(e))}let iU=/[*?[\]{}]/;async function iF(e){let t,{filePath:r,sessionName:a,requestId:i,timeoutMs:n,platform:o,runReplay:s,cleanupSession:l}=e;ed(i);let d=new Set,u=!1,c=s({filePath:r,sessionName:a,platform:o,requestId:i,artifactPaths:d}).catch(e=>{let t=C(e);return eq(t.code,t.message)}).finally(()=>{ez(i)});try{return"number"==typeof n?await Promise.race([c,new Promise(e=>{t=setTimeout(()=>{u=!0,eG(i),e(function(e,t=[]){return{ok:!1,error:{code:"COMMAND_FAILED",message:`TIMEOUT after ${e}ms`,hint:"Replay test timeouts are cooperative; the active command may take a short grace period to stop.",details:{reason:"timeout",timeoutMs:e,timeoutMode:"cooperative",artifactPaths:t}}}}(n,[...d]))},n)})]):await c}finally{t&&clearTimeout(t),u&&(await iG(c)||P({level:"warn",phase:"test_timeout_cleanup_race",data:{session:a,requestId:i,graceMs:2e3}}));try{await l(a)}catch(e){P({level:"warn",phase:"test_cleanup_failed",data:{session:a,error:C(e).message}})}}}async function iG(e){return await Promise.race([e.then(()=>!0),p(2e3).then(()=>!1)])}async function iV(e){let{req:t,sessionName:r,runReplay:a,cleanupSession:n}=e;if((t.positionals?.length??0)===0)return eq("INVALID_ARGS","test requires at least one path or glob");try{var s,l,d,u,c,f;let e,p,m,h,g,w=function(e){let{inputs:t,cwd:r,platformFilter:a}=e,n=r??process.cwd(),s=[...new Set(t.flatMap(e=>(function(e,t){var r,a;let n=tE.expandHome(e,t);if(i.existsSync(n)){let t=i.statSync(n);if(t.isDirectory())return i.globSync("**/*.ad",{cwd:n}).map(e=>o.join(n,e));if(t.isFile()){if(".ad"!==o.extname(n))throw new T("INVALID_ARGS",`test requires .ad files. Received: ${e}`);return[n]}return[]}if(r=e,!iU.test(r)&&(a=n,!iU.test(a)))throw new T("INVALID_ARGS",`test input not found: ${e}`);let s=o.isAbsolute(n)?n:e;return i.globSync(s,{cwd:o.isAbsolute(n)?void 0:t}).map(e=>o.isAbsolute(e)?e:o.resolve(t,e)).filter(e=>".ad"===o.extname(e)&&function(e){try{return i.statSync(e).isFile()}catch{return!1}}(e))})(e,n)))].map(e=>o.normalize(e)).sort((e,t)=>e.localeCompare(t)),l=[];for(let e of s){var d,u;let t=function(e){let t=e.split(/\r?\n/),r={};for(let e of t){let t=e.trim();if(0===t.length||t.startsWith("#"))continue;if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&iE.has(e)&&iT(r,"platform",e)}let i=t.match(/(?:^|\s)timeout=(\d+)/);if(i){let e=Number(i[1]);Number.isFinite(e)&&e>=1&&iT(r,"timeoutMs",Math.floor(e))}let n=t.match(/(?:^|\s)retries=(\d+)/);if(n){let e=Number(n[1]);Number.isFinite(e)&&e>=0&&iT(r,"retries",Math.floor(e))}}return r}(i.readFileSync(e,"utf8"));if(!a){l.push({kind:"run",path:e,metadata:t});continue}if(!t.platform){l.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${a}`});continue}d=a,u=t.platform,("apple"===d?"apple"===u||"ios"===u||"macos"===u:u===d)&&l.push({kind:"run",path:e,metadata:t})}if(0===l.filter(e=>"run"===e.kind).length){let e=a?` for --platform ${a}`:"";throw new T("INVALID_ARGS",`No .ad tests matched${e}.`)}return l}({inputs:t.positionals,cwd:t.meta?.cwd,platformFilter:t.flags?.platform}),y=(s=t.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),v=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:a}=e,i=tE.expandHome(t??".agent-device/test-artifacts",r);return o.join(i,a)}({artifactsDir:"string"==typeof t.flags?.artifactsDir?t.flags.artifactsDir:void 0,cwd:t.meta?.cwd,suiteInvocationId:y}),I=[],S=Date.now(),A=0;for(let e of w){if("skip"===e.kind){I.push({file:e.path,status:"skipped",durationMs:0,reason:e.reason,message:e.message});continue}A+=1;let i=await ij({entry:e,sessionName:r,suiteInvocationId:y,caseIndex:A-1,cwd:t.meta?.cwd,requestId:t.meta?.requestId,retries:function(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}(t.flags?.retries,e.metadata.retries),timeoutMs:(l=t.flags?.timeoutMs,d=e.metadata.timeoutMs,"number"==typeof l?l:d),suiteArtifactsDir:v,runReplay:a,cleanupSession:n});if(I.push(i),t.flags?.failFast===!0)break}let b=(u=w.length,c=I,f=Date.now()-S,e=c.filter(e=>"passed"===e.status).length,m=(p=c.filter(e=>"failed"===e.status)).length,h=c.filter(e=>"skipped"===e.status).length,g=e+m,{total:u,executed:g,passed:e,failed:m,skipped:h,notRun:Math.max(0,u-g-h),durationMs:f,failures:p,tests:c});return{ok:!0,data:b}}catch(t){let e=C(t);return eq(e.code,e.message)}}async function ij(e){var t,r;let a,n,{entry:s,sessionName:l,suiteInvocationId:d,caseIndex:u,cwd:c,requestId:f,retries:p,timeoutMs:m,suiteArtifactsDir:h,runReplay:g,cleanupSession:w}=e,y=Date.now(),v=o.join(h,(t=s.path,(0===(n=c?o.relative(c,t):o.basename(t)).length||n.startsWith("..")?o.basename(t):n).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",S=0;for(let e=0;e<=p;e+=1){S=e+1;let t=function(e,t,r,a,i=0){let n=o.basename(r,o.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${a+1}${n?`-${n}`:""}:attempt-${i+1}`}(l,d,s.path,u,e),n=o.join(v,`attempt-${S}`);r=s.path,i.mkdirSync(n,{recursive:!0}),i.copyFileSync(r,o.join(n,"replay.ad"));let c=function(e){let{requestId:t,suiteInvocationId:r,filePath:a,caseIndex:i,attemptIndex:n}=e;return eC(`${t??r}:test:${i+1}:${o.basename(a)}:attempt:${n+1}`,r)}({requestId:f,suiteInvocationId:d,filePath:s.path,caseIndex:u,attemptIndex:e}),h=await iF({filePath:s.path,sessionName:t,requestId:c,timeoutMs:m,platform:s.metadata.platform,runReplay:g,cleanupSession:w});if(!function(e){let{response:t,filePath:r,sessionName:a,attempts:n,maxAttempts:s,attemptArtifactsDir:l}=e,d=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(t)];t.ok||"string"!=typeof t.error.logPath||d.push(t.error.logPath);let u=function(e,t){let r=[],a=new Map;for(let n of e){if(!function(e){try{return i.statSync(e).isFile()}catch{return!1}}(n))continue;let e=function(e,t){let r=o.extname(e),a=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${a}-${i+1}${r}`}(o.basename(n),a),s=o.join(t,e);o.resolve(n)!==o.resolve(s)&&i.copyFileSync(n,s),r.push(s)}return r}(d,l),c=[`file: ${r}`,`session: ${a}`,`attempt: ${n}/${s}`,`status: ${t.ok?"passed":"failed"}`];if(t.ok){let e="number"==typeof t.data?.replayed?t.data.replayed:0,r="number"==typeof t.data?.healed?t.data.healed:0;c.push(`replayed: ${e}`,`healed: ${r}`)}else c.push(`code: ${t.error.code}`,`message: ${t.error.message}`),t.error.hint&&c.push(`hint: ${t.error.hint}`),t.error.diagnosticId&&c.push(`diagnosticId: ${t.error.diagnosticId}`),t.error.logPath&&c.push(`logPath: ${t.error.logPath}`),t.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");u.length>0&&c.push(`copiedArtifacts: ${u.map(e=>o.basename(e)).join(", ")}`);let f=o.join(l,"result.txt"),p=`${c.join("\n")}
|
|
8
|
+
`;i.writeFileSync(f,p),t.ok||i.writeFileSync(o.join(l,"failure.txt"),p)}({response:h,filePath:s.path,sessionName:t,attempts:S,maxAttempts:p+1,attemptArtifactsDir:n}),a=h,I=t,h.ok)break}let A=Date.now()-y;if(a?.ok)return{file:s.path,session:I,status:"passed",durationMs:A,attempts:S,artifactsDir:v,replayed:"number"==typeof a.data?.replayed?a.data.replayed:0,healed:"number"==typeof a.data?.healed?a.data.healed:0};let b=a?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:a?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return{file:s.path,session:I,status:"failed",durationMs:A,attempts:S,artifactsDir:v,error:b}}function iq(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=te(r?e.slice(0,-1):e.slice());return!a||a.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:a.selectorExpression,selectorTimeout:r?t:null}}async function iH(e){let{action:t,sessionName:r,logPath:a,sessionStore:i}=e;if(!(tS(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let n=i.get(r);if(!n)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),tS(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=ta(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=iq(e.positionals??[]);r&&t.push(r)}return th(t).filter(e=>e.trim().length>0)})(t).map(e=>ti(e)).filter(e=>null!==e);if(0===o.length)return null;let s=tS(t.command)||"fill"===t.command,l=tS(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await iB(n,t,a,s,i);for(let e of o){let r=tn(d.nodes,e,{platform:n.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let a=ts(r.node,n.device.platform,{action:tS(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tS(t.command))return{...t,positionals:[a]};if("fill"===t.command){let e=tm(t);if(!e)continue;return{...t,positionals:[a,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,a]}}if("is"===t.command){let{predicate:e,split:r}=ta(t.positionals);if(!e)continue;let i=r?.rest.join(" ").trim()??"",n=[e,a];return"text"===e&&i.length>0&&n.push(i),{...t,positionals:n}}if("wait"===t.command){let{selectorTimeout:e}=iq(t.positionals??[]),r=[a];return e&&r.push(e),{...t,positionals:r}}}return null}async function iB(e,t,r,a,i){let n=await Y(e.device,"snapshot",[],t.flags?.out,{...eL(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),o=n?.nodes??[],s={nodes:tu(t.flags?.snapshotRaw?o:td(o)),truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend};return e.snapshot=s,i.set(e.name,e),s}async function iK(e){let{req:t,sessionName:r,logPath:a,sessionStore:n,invoke:o}=e,s=t.positionals?.[0];if(!s)return eq("INVALID_ARGS","replay requires a path");let l="",d=new Set;try{l=tE.expandHome(s,t.meta?.cwd);let e=i.readFileSync(l,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return eq("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let c=function(e){let t=[];for(let r of e.split(/\r?\n/)){let e=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let r=function(e){let t=[],r=0;for(;r<e.length;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let a=r+1,i=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!i)break;i="\\"===t&&!i,"\\"!==t&&(i=!1),a+=1}if(a>=e.length)throw new T("INVALID_ARGS",`Invalid replay script line: ${e}`);let n=e.slice(r,a+1);t.push(JSON.parse(n)),r=a+1;continue}let a=r;for(;a<e.length&&!/\s/.test(e[a]);)a+=1;t.push(e.slice(r,a)),r=a}return t}(t);if(0===r.length)return null;let[a,...i]=r;if("context"===a)return null;let n={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){n.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){n.flags.snapshotCompact=!0;continue}if("--raw"===t){n.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(n.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){n.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}return n}if("open"===a){let e=function(e){var t;let r=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}r.push(t)}let i=tR(r);return{positionals:i.positionals,flags:a,runtime:(t=i.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?i.flags:void 0}}(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n.runtime=e.runtime,n}if("runtime"===a){let e=tR(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(tS(a)){let e=tL(a,i);if(Object.assign(n.flags,e.flags),0===e.positionals.length)return n;let t=e.positionals[0];if(t.startsWith("@"))return n.positionals=[t],e.positionals[1]&&(n.result={refLabel:e.positionals[1]}),n;let r=e.positionals[0],o=e.positionals[1];return i$(r)&&i$(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){let e=tL(a,i);if(Object.assign(n.flags,e.flags),e.positionals.length<2)return n.positionals=e.positionals,n;let t=e.positionals[0];return t.startsWith("@")?(e.positionals.length>=3?(n.positionals=[t,e.positionals.slice(2).join(" ")],n.result={refLabel:e.positionals[1]}):n.positionals=[t,e.positionals[1]],n):(n.positionals=[t,e.positionals.slice(1).join(" ")],n)}if("get"===a){if(i.length<2)return n.positionals=i,n;let e=i[0],t=i[1];return t.startsWith("@")?(n.positionals=[e,t],i[2]&&(n.result={refLabel:i[2]})):n.positionals=[e,i.slice(1).join(" ")],n}if("swipe"===a||"type"===a){let e=tL(a,i);return Object.assign(n.flags,e.flags),n.positionals=e.positionals,n}if("record"===a){let e=[];for(let t=0;t<i.length;t+=1){let r=i[t];if("--hide-touches"===r){n.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===r&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(n.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return n.positionals=e,n}if("screenshot"===a){let e=[];for(let t of i){if("--fullscreen"===t){n.flags.screenshotFullscreen=!0;continue}e.push(t)}return n.positionals=e,n}return n.positionals=i,n}(r);e&&t.push(e)}return t}(e),f=t.flags?.replayUpdate===!0,p=0;for(let e=0;e<c.length;e+=1){let i=c[e];if(!i||"replay"===i.command)continue;let s=await iz({req:t,sessionName:r,action:i,invoke:o});if(s.ok){iJ(s).forEach(e=>d.add(e));continue}if(!f)return iW(s,i,e,l,[...d]);let u=await iH({action:i,sessionName:r,logPath:a,sessionStore:n});if(!u)return iW(s,i,e,l,[...d]);if(c[e]=u,!(s=await iz({req:t,sessionName:r,action:u,invoke:o})).ok)return iW(s,u,e,l,[...d]);iJ(s).forEach(e=>d.add(e)),p+=1}return f&&p>0&&function(e,t,r){let a=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${t} device=${t_(r.device.name)}${e} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tb(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command)return tC(t,e),t.join(" ");if("runtime"===e.command){for(let r of e.positionals??[])t.push(tN(r,tM));return tD(t,e.flags),t.join(" ")}if("record"===e.command)return tP(t,e),t.join(" ");if("screenshot"===e.command){for(let r of e.positionals??[])t.push(tb(r));return e.flags?.screenshotFullscreen&&t.push("--fullscreen"),t.join(" ")}for(let r of e.positionals??[])t.push(tb(r));return tx(t,e),t.join(" ")}(e));let n=`${a.join("\n")}
|
|
9
|
+
`,o=`${e}.tmp-${process.pid}-${Date.now()}`;i.writeFileSync(o,n),i.renameSync(o,e)}(l,c,n.get(r)),{ok:!0,data:{replayed:c.length,healed:p,session:r,artifactPaths:[...d]}}}catch(t){let e=C(t);return eq(e.code,e.message,d.size>0?{artifactPaths:[...d]}:void 0)}}async function iz(e){var t;let{req:r,sessionName:a,action:i,invoke:n}=e;return await n({token:r.token,session:a,command:i.command,positionals:i.positionals??[],flags:(t=r.flags,aO(t,{...i.flags??{}})),runtime:i.runtime,meta:r.meta})}function iW(e,t,r,a,i=[]){let n;if(e.ok)return e;let o=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${o} (${n=(t.positionals??[]).map(e=>tb(e)),[t.command,...n].join(" ")}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:a,step:o,action:t.command,positionals:t.positionals??[],artifactPaths:i}}}}function iJ(e){if(!e.ok||!e.data)return[];let t=[];if("string"==typeof e.data.path&&t.push(e.data.path),"string"==typeof e.data.outPath&&t.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let r of e.data.artifacts){if(!r||"object"!=typeof r)continue;let e="string"==typeof r.localPath?r.localPath:void 0,a="string"==typeof r.path?r.path:void 0;e?t.push(e):a&&t.push(a)}return[...new Set(t.filter(e=>(function(e){try{return i.statSync(e).isFile()}catch{return!1}})(e)))]}async function iZ(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;return"replay"===t.command?await iK({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"test"===t.command?await iV({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,requestId:s,artifactPaths:l})=>await iK({req:{...t,command:"replay",session:r,positionals:[e],flags:void 0===o?t.flags:{...t.flags??{},platform:o},meta:s?{...t.meta??{},requestId:s}:t.meta},sessionName:r,logPath:a,sessionStore:i,invoke:async e=>{var t;return t=await n(e),l&&iJ(t).forEach(e=>l.add(e)),t}}),cleanupSession:async e=>{i.get(e)&&await aL({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:a,sessionStore:i})}}):null}let iX=new Set(["session_list","ensure-simulator","devices","apps"]),iY=new Set(["boot","appstate"]),iQ=new Set(["perf","logs","network"]),i0=new Set(["replay","test"]);async function i1(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,command:n,positionals:o,recordPositionals:s,deriveNextSession:l}=e,d=i.get(r),u=t.flags??{},c=r4(n,d,u);if(c)return c;let f=await r7({session:d,flags:u,ensureReady:!0});if(!ep(n,f))return eq("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);let p=await Y(f,n,o,t.flags?.out,{...eL(a,t.flags,d?.appBundleId,d?.trace?.outPath)});if(d){let e=l?await l(d,p,f):d;i.recordAction(e,{command:n,positionals:s??o,flags:t.flags??{},result:p??{}}),e!==d&&i.set(r,e)}return{ok:!0,data:p??{}}}async function i2(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=i.get(r),o=t.flags??{},s=r4("clipboard",n,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return eq("INVALID_ARGS","clipboard requires a subcommand: read or write");let d=await r7({session:n,flags:o,ensureReady:!0});if(!ep("clipboard",d))return eq("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let u=await Y(d,"clipboard",t.positionals??[],t.flags?.out,{...eL(a,t.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:u??{}}),{ok:!0,data:{platform:d.platform,...u??{}}}}async function i3(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e;if(iX.has(t.command))return await aH({req:t,sessionName:r,sessionStore:i});if("runtime"===t.command)return await ad({req:t,sessionName:r,sessionStore:i});if(iY.has(t.command))return await aJ({req:t,sessionName:r,sessionStore:i});if("clipboard"===t.command)return await i2({req:t,sessionName:r,logPath:a,sessionStore:i});if("keyboard"===t.command){let e=i.get(r),n=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==n||"ios"!==e2((t.flags??{}).platform)?await i1({req:t,sessionName:r,logPath:a,sessionStore:i,command:"keyboard",positionals:t.positionals??[]}):eq("SESSION_NOT_FOUND","iOS keyboard dismiss requires an active session so the target app stays foregrounded. Run open first.")}if(iQ.has(t.command))return await iM({req:t,sessionName:r,sessionStore:i});if("install"===t.command||"reinstall"===t.command)return await aT({req:t,command:t.command,sessionName:r,sessionStore:i,deployOps:"install"===t.command?aE:aC});if("install_source"===t.command)return await r0({req:t,sessionName:r,sessionStore:i});if("release_materialized_paths"===t.command)return await r2({req:t});if("push"===t.command){let e,n=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return n&&o?await i1({req:t,sessionName:r,logPath:a,sessionStore:i,command:"push",positionals:[n,"file"===(e=eE(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>tE.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[n,o]}):eq("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return"trigger-app-event"===t.command?await i1({req:t,sessionName:r,logPath:a,sessionStore:i,command:"trigger-app-event",positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await aw(e.device,r,e.appBundleId,ag)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}}):"open"===t.command?await aM({req:t,sessionName:r,logPath:a,sessionStore:i}):i0.has(t.command)?await iZ({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}):"batch"===t.command?await a$(t,r,n):"close"===t.command?await aL({req:t,sessionName:r,logPath:a,sessionStore:i}):null}async function i8(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 eq("INVALID_ARGS","find requires a locator or text");let{locator:l,query:d,action:u,value:c,timeoutMs:f}=tp(s);if(!d)return eq("INVALID_ARGS","find requires a value");if(t.flags?.findFirst&&t.flags?.findLast)return eq("INVALID_ARGS","find accepts only one of --first or --last");let p=await eH({req:t,sessionName:r,logPath:a,sessionStore:i});if(p)return p;let m=i.get(r);if(!m&&"exists"!==u&&"wait"!==u&&"get_text"!==u&&"get_attrs"!==u)return eq("SESSION_NOT_FOUND","No active session. Run open first.");let h=m?.device??await eh(t.flags??{});m||await eB(h);let g="role"!==l?d:void 0,w="click"===u||"focus"===u||"fill"===u||"type"===u,y=0,v=null,I=async()=>{let e=Date.now();if(v&&e-y<750&&!eW(m))return{nodes:v};let{snapshot:n}=await em({device:h,session:m,flags:{...t.flags,snapshotInteractiveOnly:w,snapshotCompact:w},outPath:t.flags?.out,logPath:a,snapshotScope:g}),o=n.nodes;return y=e,v=o,m&&(m.snapshot=n,i.set(r,m)),{nodes:o,truncated:n.truncated,backend:n.backend}},S={req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n,session:m,device:h,command:o,locator:l,query:d};if("wait"===u)return i4(S,I,l,d,f);let{nodes:A}=await I(),b=tf(A,l,d,{requireRect:w});if(w&&b.matches.length>1)if(t.flags?.findFirst)b.matches=[b.matches[0]];else{if(!t.flags?.findLast){var _,N,k;let e;return _=b.matches,N=l,k=d,e=_.slice(0,8).map(e=>{let t=tr(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),eq("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${N} "${k}". Use a more specific locator or selector.`,{locator:N,query:k,matches:_.length,candidates:e})}b.matches=[b.matches[b.matches.length-1]]}let M=b.matches[0]??null;if(!M)return eq("COMMAND_FAILED","find did not match any element");let x="click"===u||"focus"===u||"fill"===u||"type"===u?tt(A,M)??M:M,D=`@${x.ref}`,P={node:M,resolvedNode:x,ref:D,nodes:A,actionFlags:{...t.flags??{},noRecord:!0}},L={exists:()=>i5(S),get_text:()=>i9(S,P),get_attrs:()=>i6(S,P),click:()=>i7(S,P),fill:()=>ne(S,P,c),focus:()=>nt(S,P),type:()=>nr(S,P,c)}[u];return L?L():null}async function i4(e,t,r,a,i){let{req:n,sessionStore:o,session:s,command:l}=e,d=i??1e4,u=Date.now();for(;Date.now()-u<d;){let{nodes:e}=await t();if(tf(e,r,a,{requireRect:!1}).matches[0])return s&&o.recordAction(s,{command:l,positionals:n.positionals??[],flags:n.flags??{},result:{found:!0,waitedMs:Date.now()-u}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-u}};await new Promise(e=>setTimeout(e,300))}return eq("COMMAND_FAILED","find wait timed out")}async function i5(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 i9(e,t){let{req:r,sessionStore:a,session:i,command:n,device:o,logPath:s}=e,l=await eN({device:o,node:t.node,flags:r.flags,appBundleId:i?.appBundleId,traceOutPath:i?.trace?.outPath,surface:i?.surface,contextFromFlags:(e,t,r)=>eL(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 i6(e,t){let{req:r,sessionStore:a,session:i,command:n}=e;return i&&a.recordAction(i,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function i7(e,t){let{req:r,sessionName:a,sessionStore:i,session:n,invoke:o,command:s,locator:l,query:d}=e,u=await o({token:r.token,session:a,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let c=t.resolvedNode.rect?tc(t.resolvedNode.rect):null,f={ref:t.ref,locator:l,query:d};return c&&(f.x=c.x,f.y=c.y),n&&i.recordAction(n,{command:s,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"click",locator:l,query:d}}),{ok:!0,data:f}}async function ne(e,t,r){let{req:a,sessionName:i,sessionStore:n,session:o,invoke:s,command:l}=e;if(!r)return eq("INVALID_ARGS","find fill requires text");let d=await s({token:a.token,session:i,command:"fill",positionals:[t.ref,r],flags:t.actionFlags});return d.ok&&o&&n.recordAction(o,{command:l,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"fill"}}),d}async function nt(e,t){let{req:r,sessionStore:a,session:i,device:n,command:o,logPath:s}=e,l=t.node.rect?tc(t.node.rect):null;if(!l)return eq("COMMAND_FAILED","matched element has no bounds");let d=await Y(n,"focus",[String(l.x),String(l.y)],r.flags?.out,{...eL(s,r.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:o,positionals:r.positionals??[],flags:r.flags??{},result:{ref:t.ref,action:"focus"}}),{ok:!0,data:d??{ref:t.ref}}}async function nr(e,t,r){let{req:a,sessionStore:i,session:n,device:o,command:s,logPath:l}=e;if(!r)return eq("INVALID_ARGS","find type requires text");let d=t.node.rect?tc(t.node.rect):null;if(!d)return eq("COMMAND_FAILED","matched element has no bounds");await Y(o,"focus",[String(d.x),String(d.y)],a.flags?.out,{...eL(l,a.flags,n?.appBundleId,n?.trace?.outPath)});let u=await Y(o,"type",[r],a.flags?.out,{...eL(l,a.flags,n?.appBundleId,n?.trace?.outPath)});return n&&i.recordAction(n,{command:s,positionals:a.positionals??[],flags:a.flags??{},result:{ref:t.ref,action:"type"}}),{ok:!0,data:u??{ref:t.ref}}}let na=`
|
|
10
10
|
import Foundation
|
|
11
11
|
import AVFoundation
|
|
12
12
|
|
|
@@ -30,11 +30,11 @@ Task {
|
|
|
30
30
|
|
|
31
31
|
semaphore.wait()
|
|
32
32
|
exit(exitCode)
|
|
33
|
-
`.trim();async function
|
|
34
|
-
${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return nn(e);return!1}catch(t){if(t instanceof tc&&"TOOL_MISSING"===t.code)return nn(e);throw t}}async function ni(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await na(e))return;await new Promise(e=>setTimeout(e,r))}}function nn(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 no(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function ns(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nl(e){let t=o.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new tc("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure ios-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}async function nd(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await nr(t),await ni(t);let s=i.mkdtempSync(o.join(c.tmpdir(),"agent-device-record-overlay-")),l=o.join(s,`input${o.extname(t)||".mp4"}`),d=o.join(s,o.basename(t)),u=o.join(s,"home"),f=o.join(s,"module-cache");i.copyFileSync(t,l),i.mkdirSync(u,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await tl("xcrun",["swift",r,"--input",l,"--output",d,...a],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await ni(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof tc?a:new tc("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new tc("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function nu(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nd({videoPath:r,scriptPath:t??=nl("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function nc(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nd({videoPath:r,scriptPath:e??=nl("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function nf(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await nd({videoPath:t,scriptPath:r??=nl("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function np(e){return e instanceof Error?e.message:String(e)}function nm(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function nh(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:n}=e,o=function(e){var t,r,a;let n,o,{recording:s,trimStartMs:l}=e,d=(n=no((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?ns(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)}]})):ns(r))},i.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:a});if(t.showTouches){let e=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(e)t.overlayWarning??=e;else try{await r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,targetLabel:n})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${np(e)}`}}}async function ng(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 nw(e,t,r){for(let a=0;a<40;a+=1){if(!await ng(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await ng(e,t,r)}async function ny(e,t,r){let a,i=0;for(let n=0;n<20;n+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?n.stdout.trim():"";if(o.length>0&&o===a){if((i+=1)>=4)return}else i=0;a=o,await new Promise(e=>setTimeout(e,250))}}async function nv(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 ng(e,t,a))break;if(i+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function nI(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=nm(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(e0({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;e0({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1}})}e<1&&await new Promise(e=>setTimeout(e,750))}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function nS(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: ${nm(i,"adb shell wm size")}`);return{width:nA(Number(n[1]),a),height:nA(Number(n[2]),a)}}function nA(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nb(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function n_(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return e0({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 ng(e,t,r))&&await nw(e,t,r)}async function nN(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 nS({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return eH("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),a=`agent-device-recording-${t}.mp4`,[`/sdcard/${a}`,`/data/local/tmp/${a}`])){let t=await i.runCmd("adb",["-s",n.id,"shell",function(e,t){let r=["screenrecord"];return t&&r.push("--size",`${t.width}x${t.height}`),r.push(e),`${r.join(" ")} >/dev/null 2>&1 & echo $!`}(e,r)],{allowFailure:!0});if(0!==t.exitCode){s=`failed to start recording: ${nm(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 nb(i,n.id,e);continue}if(e0({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nv(i,n.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...o,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await n_(i,n.id,a),await nb(i,n.id,e)}return eH("COMMAND_FAILED",s)}async function nk(e){let t,r,{deps:a,device:i,recording:n}=e;e0({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(e0({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 ng(a,i.id,n.remotePid)&&!await n_(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${nm(o,"adb shell kill")}`):await nw(a,i.id,n.remotePid)||await n_(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await ny(a,i.id,n.remotePath);let e=await nI({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),eH("COMMAND_FAILED",e);await nh({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return eH("COMMAND_FAILED",t);if(r)return eH("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});e0({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:i.id,remotePath:n.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${nm(e,"adb shell rm")}`)}}function nx(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nM(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nD(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nx(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nM(t,i,r))}catch(e){e0({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:np(e)}})}}async function nP(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=nM(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,fps:d,quality:u.quality,appBundleId:c},m);try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(a){var g,w;if(!np(a).toLowerCase().includes("recording already in progress"))return eH("COMMAND_FAILED",`failed to start recording: ${np(a)}`);e0({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:np(a)}});let e=(g=o.id,w=i.name,n.toArray().find(e=>e.name!==w&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return eH("COMMAND_FAILED",`failed to start recording: recording already in progress in session '${e.name}'`);try{await l.runIosRunnerCommand(o,{command:"recordStop",appBundleId:c},m)}catch{}try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${np(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function nL(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},nM(t,i,r))}catch(e){return eH("COMMAND_FAILED",`failed to start recording: ${np(e)}`)}return{platform:"macos-runner",...s}}async function nR(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nx(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nM(t,i,r))}catch(e){e0({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:np(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of H)if(0===(l=await n.runCmd("xcrun",["devicectl","device","copy","from","--device",a.id,"--source",o.remotePath,"--destination",o.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(0!==l.exitCode){let e=l.stderr.trim()||l.stdout.trim()||`devicectl exited with code ${l.exitCode}`;return eH("COMMAND_FAILED",`failed to copy recording from device: ${e}`)}let d="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);return d>0&&await n.trimRecordingStart({videoPath:o.outPath,trimStartMs:d}),await nh({recording:o,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function nO(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nx(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nM(t,i,r))}catch(e){e0({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:np(e)}})}return await nh({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nE(e){for(let t=0;t<2;t+=1){try{if(i.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await new Promise(e=>setTimeout(e,250))}return Date.now()}async function nC(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await nD({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",eY(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await nE(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nx(i)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:i.trace?.outPath}),d=Date.now();t=Math.round((e+d)/2),r="number"==typeof l.currentUptimeMs?l.currentUptimeMs:void 0}catch{}return{platform:"ios",child:u,wait:c,...l,startedAt:f,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function nT(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return eH("INVALID_ARGS","recording already in progress");let c=r.flags?.fps,f=r.flags?.quality;if(void 0!==c&&(!Number.isInteger(c)||c<1||c>120))return eH("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return eH("INVALID_ARGS","quality must be an integer between 5 and 10");if(!Q("record",l))return eH("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tO.expandHome(p,r.meta?.cwd),h={outPath:m,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),quality:r.flags?.quality,showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(i.mkdirSync(o.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nx(s);if(!e)return eH("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nP({req:r,activeSession:s,sessionStore:n,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nx(s);if(!e)return eH("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nL({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await nC({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:h,resolvedOut:m}):await nN({deps:u,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,n.set(a,s),n.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??p,showTouches:t.showTouches}})}async function n$(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nk({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;if(0!==i.exitCode)return eH("COMMAND_FAILED",`failed to stop recording: ${nm(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: ${np(e)}`}return await nh({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nF(e){var t;let r,{req:a,activeSession:i,device:n,logPath:s,deps:l}=e;if(!i.recording)return eH("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await nR({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await nO({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):await n$({deps:l,device:n,recording:d});return c||(u?eH("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return no(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nU(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:tl,runCmdBackground:ts,runIosRunnerCommand:C,waitForStableFile:nr,isPlayableVideo:na,trimRecordingStart:nu,resizeRecording:nf,overlayRecordingTouches:nc},o=a.get(r),s=o?.device??await ef(t.flags??{});o||await eW(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return eH("INVALID_ARGS","record requires start|stop");if("start"===d)return nT({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await nF({req:t,activeSession:l,device:s,logPath:i,deps:n});return u.ok&&a.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:u.data?.outPath,showTouches:u.data?.showTouches}}),u}async function nG(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,s=t.command;if("record"===s)return nU({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return eH("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return eH("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return eH("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=tO.expandHome(e);return i.mkdirSync(o.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return eH("INVALID_ARGS","no active trace");let l=n.trace.outPath;if(t.positionals?.[1]){let e=tO.expandHome(t.positionals[1]);i.mkdirSync(o.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nV(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 nj=new WeakMap;function nq(e){if(!e)return;let t=nj.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)&&nB(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(nB);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 nj.set(e,r),r}function nB(e){return!!e&&e.width>0&&e.height>0}let nH={referenceWidth:1e3,referenceHeight:1e3};function nz(e,t,r,a,i={},n=Date.now(),o=Date.now()){var s,l,d;let u,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=nZ(p.effectiveDurationMs)??nZ(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:nZ(p.gestureStartUptimeMs),gestureEndUptimeMs:nZ(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:nZ(p.gestureStartUptimeMs),gestureEndUptimeMs:nZ(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),w="ios"===e.device.platform&&void 0===nZ(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=nX(nZ(t.count),1)??1,r=!0===t.doubleTap,a=nX(nZ(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 nV(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nV(h),y=(l=e.snapshot,u=nZ((d=p).referenceWidth),c=nZ(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:nq(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=nY(t,e);if(!i)return[];let{x:n,y:o}=i,s=nX(nZ(t.count),1)??1,l=nX(nZ(t.intervalMs),0)??0,d=!0===t.doubleTap,u=nX(nZ(t.holdMs),1),c=[];for(let e=0;e<s;e+=1){let t=r+e*l;if(void 0!==u&&u>0){c.push(nW(t,n,o,u,a));continue}c.push(nK(t,n,o,a)),d&&c.push(nK(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=nY(t,e);if(!i)return[];let{x:n,y:o}=i;return[nK(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=nY(t,e);if(!n)return[];let{x:o,y:s}=n;return[nW(r,o,s,n0(a,[nZ(t.durationMs),nZ(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=nQ(t,e),o=nJ(t.contentDirection)??nJ(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=n0(a,[],250),f=nZ(t.amount)??nZ(e[1]),p=nZ(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...i,durationMs:c,contentDirection:o,...void 0!==f?{amount:f}:{},...void 0!==p?{pixels:p}:{}}]}(t,r,a,i,n);case"swipe":return function(e,t,r,a,i){let n=nQ(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=n0(a,[nZ(t.effectiveDurationMs),nZ(t.durationMs),nZ(e[4])],250),c=nX(nZ(t.count),1)??1,f=nX(nZ(t.pauseMs),0)??0,p="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===p&&e%2==1,a=t?l:o,n=t?d:s,c=t?o:l,h=t?s:d,g=r+e*(u+f);if("back-swipe"===function(e,t,r,a,i){if(!i||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let n=.08*i.referenceWidth;return e<=n&&r>e||e>=i.referenceWidth-n&&r<e?"back-swipe":"swipe"}(a,n,c,h,i)){m.push({kind:"back-swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u,edge:function(e,t,r){if(r){let t=.08*r.referenceWidth;if(e<=t)return"left";if(e>=r.referenceWidth-t)return"right"}return t>=e?"left":"right"}(a,c,i)});continue}m.push({kind:"swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u})}return m}(t,r,a,i,n);case"pinch":return function(e,t,r,a,i){let n=nY(t,e,1),o=nZ(t.scale)??nZ(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:n0(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),e0({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:w,gestureDurationMs:g,kinds:v.map(e=>e.kind)}}))}function nK(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function nW(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function nJ(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 nZ(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 nX(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function nY(e,t,r=0){let a=nZ(e.x)??nZ(t[r]),i=nZ(e.y)??nZ(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function nQ(e,t){let r=nZ(e.x1)??nZ(t[0]),a=nZ(e.y1)??nZ(t[1]),i=nZ(e.x2)??nZ(t[2]),n=nZ(e.y2)??nZ(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 n0(e,t,r){return nX(e,1)??t.map(e=>nX(e,1)).find(e=>void 0!==e)??r}function n1(e){var t,r,a;let i,n,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,i="string"==typeof t?.ref?t.ref:void 0,n="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:i?n&&"primary"!==n?`Clicked ${n} @${i} (${r}, ${a})`:`Tapped @${i} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...ee(c)}}function n2(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:o}),K(a)&&ta(t,a),nz(t,a,i,o,n??{},l,d),{ok:!0,data:s}}async function n4(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 ey(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=nq(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=nq(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function n3(e){try{return await n4(e)}catch(t){e0({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function n5(e){return nq({nodes:e,createdAt:0})}function n8(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:eH("UNSUPPORTED_OPERATION",`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}async function n6(e,t){if("android"!==e.device.platform||!e.appBundleId)return;let r=await ev(e.device),a=r.package?.trim();if(a&&a!==e.appBundleId){var i;if("com.android.settings"===(i=a)||"com.android.systemui"===i||"com.google.android.permissioncontroller"===i||i.includes("launcher"))throw new tc("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${a}. The tap likely escaped the app.`,{expectedPackage:e.appBundleId,foregroundPackage:a,activity:r.activity,hint:"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."})}}function n9(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new tc("SESSION_NOT_FOUND","No active session. Run open first.");return ec({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,i)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0})}),tap:async(a,i)=>n7(await I(r.device,"press",[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(a,i,n)=>n7(await I(r.device,"fill",[String(i.x),String(i.y),n],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(a,i)=>n7(await I(r.device,"type",[i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),artifacts:eG("interaction commands",{plural:!0}),sessions:{get:r=>r===e.sessionName?{name:e.sessionName,appBundleId:t.appBundleId,appName:t.appName,snapshot:t.snapshot,metadata:{surface:t.surface}}:void 0,set:r=>{r.snapshot&&(t.snapshot=r.snapshot,e.sessionStore.set(e.sessionName,t))}},policy:j()})}function n7(e){return e&&"object"==typeof e?e:void 0}function oe(e){return"ref"===e.kind?{ref:ot(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 ot(e){return e?.startsWith("@")?e.slice(1):e}async function or(e){switch(e.req.command){case"press":case"click":return await oa(e);case"fill":return await oi(e);default:return null}}async function oa(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n="click"===t.command?"click":"press";if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let o=n8(i,n);if(o)return o;if(!Q("press",i.device))return eH("UNSUPPORTED_OPERATION","press is not supported on this device");let s=e_(t.flags),l=R(s);if("primary"!==s){let e=X({commandLabel:n,platform:i.device.platform,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return eH(e.code,e.message,e.details)}let d=function(e,t){let r=ez(e);if(r)return{ok:!0,target:{kind:"point",x:r.x,y:r.y}};let a=e[0]??"";if(a.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:a,fallbackLabel:e.length>1?e.slice(1).join(" ").trim():""}};let i=e.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:i}}:{ok:!1,response:eH("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(t.positionals??[],n);if(!d.ok)return d.response;if("ref"===d.target.kind){let r=e.refSnapshotFlagGuardResponse("press",t.flags);if(r)return r}return await on(e,{run:async e=>{let a={session:r,requestId:t.meta?.requestId,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap};return"click"===n?await e.interactions.click(d.target,a):await e.interactions.press(d.target,a)},afterRun:async e=>{var t;await n6(i,(t=d.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{let n="point"===r.kind?await n3({session:i,flags:t.flags,sessionStore:a,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):n5(i.snapshot?.nodes??[]),o=n1({data:r.backendResult,fallbackX:r.point.x,fallbackY:r.point.y,referenceFrame:n,extra:{...oe(r),...l}});return{result:o,responseData:o}}})}async function oi(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=n8(i,"fill");if(e)return e}if(i&&!Q("fill",i.device))return eH("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let n=function(e){let t=e[0]??"";if(t.startsWith("@")){let r=e.length>=3?e[1]:"",a=e.length>=3?e.slice(2).join(" "):e.slice(1).join(" ");return a?{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:r},text:a}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after ref")}}let r=ez(e);if(r){let t=e.slice(2).join(" ");return t?{ok:!0,target:{kind:"point",x:r.x,y:r.y},text:t}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after coordinates")}}let a=V(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:eH("INVALID_ARGS","fill requires x y text, @ref text, or selector text")};let i=a.rest.join(" ").trim();return i?{ok:!0,target:{kind:"selector",selector:a.selectorExpression},text:i}:{ok:!1,response:eH("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!n.ok)return n.response;if("ref"===n.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r}return await on(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:n5(i.snapshot?.nodes??[]),r=n1({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...oe(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:ot(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 on(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eH("SESSION_NOT_FOUND","No active session. Run open first.");let a=n9(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 n2({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:i,actionFinishedAt:o})}catch(t){let e=td(t);if("COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage)throw e;return{ok:!1,error:tu(t)}}}async function oo(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},o=a(n,e.appBundleId,e.trace?.outPath),{snapshot:s}=await en({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}let os=/\bis(?:n't| not)\s+responding\b/i,ol=/^close app$/i;async function od(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await ou(t),r=function(e){if(om(e))return e.find(e=>{let t=op(e);return t.length>0&&ol.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=k(r.rect),n=await tl("adb",eE(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return e0({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 oc(t))return e0({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eM(t.device,t.appBundleId),!await of(t,t.appBundleId)))return e0({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return e0({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 e0({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 ou(e){return N(et((await Y(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function oc(e){for(let t=0;t<12;t+=1){if(!om(await ou(e)))return!0;await oh(500)}return!om(await ou(e))}async function of(e,t){for(let r=0;r<12;r+=1){if((await ev(e.device)).package===t)return!0;await oh(500)}return(await ev(e.device)).package===t}function op(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 om(e){return e.some(e=>{let t=op(e);return t.length>0&&os.test(t)})}function oh(e){return new Promise(t=>setTimeout(t,e))}async function og(e){let t=await or({...e,captureSnapshotForSession:oo,refSnapshotFlagGuardResponse:O});if(t)return t;switch(e.req.command){case"type":return await ow({...e,captureSnapshotForSession:oo});case"get":return await eo(e);case"is":return await eb(e);default:return null}}async function ow(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eH("SESSION_NOT_FOUND","No active session. Run open first.");if(!Q("type",i.device))return eH("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await od({session:i}))return eH("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=n9(e),s=Date.now();try{let e=await o.interactions.typeText(n,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),d={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...ee(e.message??`Typed ${Array.from(e.text).length} chars`)};return n2({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:d,responseData:d,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:tu(e)}}}function oy(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 ov(e){let{req:t,leaseRegistry:r}=e,a=oy(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}function oI(e,t){if(!t)return[];let r=[],a=e.device,i=w(t.platform);if(i&&!e6(a.platform,i)&&r.push({key:"platform",value:t.platform}),t.target&&t.target!==(a.target??"mobile")&&r.push({key:"target",value:t.target}),t.udid&&("ios"!==a.platform||t.udid!==a.id)&&r.push({key:"udid",value:t.udid}),t.serial&&("android"!==a.platform||t.serial!==a.id)&&r.push({key:"serial",value:t.serial}),t.device&&t.device.trim().toLowerCase()!==a.name.trim().toLowerCase()&&r.push({key:"device",value:t.device}),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),i=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==i)&&r.push({key:"iosSimulatorDeviceSet",value:t.iosSimulatorDeviceSet})}if(t.androidDeviceAllowlist){let e=ed(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oS(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 oA=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function ob(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:s}=e,l=ec({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let o={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?o_(await I(t.device,"screenshot",[],i,o)):o_(await I(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:i,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new tc("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-screenshot-")),r=o.join(t,"screenshot.png")),await n.mkdir(o.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await n.mkdtemp(o.join(c.tmpdir(),`${e.prefix}-`));return{path:o.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}}},sessions:{get:e=>e===r?{name:r,appBundleId:t.appBundleId,metadata:{surface:t.surface}}:void 0,set:()=>{}},policy:j()});return await l.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function o_(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let oN=[255,59,48,255],ok=[255,214,10,255],ox=[0,0,0,255],oM={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 oD(e){let t=U(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oL(r)&&oT(r.rect)&&(!t||o$(r.rect)>o$(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,i=-1/0;for(let n of e)n.rect&&oT(n.rect)&&(t=Math.min(t,n.rect.x),r=Math.min(r,n.rect.y),a=Math.max(a,n.rect.x+n.rect.width),i=Math.max(i,n.rect.y+n.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||i<=r?null:{x:t,y:r,width:a-t,height:i-r}}(e.filter(e=>{var t;return oT(e.rect)&&!("image"===T((t=e).type??"")&&!oR(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oO)||oE(e.identifier);return oP(e)?t:t&&function(e){let t=T(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let o=function(e,t){if(function(e){return oP(e)&&!oL(e)}(t)&&oT(t.rect))return t;let r=function(e,t){let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){;a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(oP(t)&&!oL(t)&&oT(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&oT(r.rect))return r;if(t.hittable&&oT(t.rect)&&!oL(t))return t;let a=e2(e,t);return a?.rect&&oT(a.rect)&&!oL(a)?a:null}(e.nodes,a);if(!o?.rect||!oT(o.rect))continue;let s=function(e,t,r){let a=oC(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=oC(a);if(!i)continue;let n=function(e){let t=0;return T(e.type??"").includes("text")&&(t+=2),oO(e.label)&&(t+=2),oO(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oC(t)??ei(t,r))}(a,o,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),oP(t)&&(a+=3),oP(e)&&(a+=2),r&&(a+=2),oE(t.identifier)&&(a+=1),oR(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return oG({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 oG({x:Math.round((t.x-e.x)*i),y:Math.round((t.y-e.y)*n),width:Math.max(1,Math.round(t.width*i)),height:Math.max(1,Math.round(t.height*n))},r,a)}(i,o.rect,t,r);if(!oT(d))continue;let u=n.get(o.ref);(!u||l>u.score)&&n.set(o.ref,{ref:o.ref,label:s,rect:o.rect,overlayRect:d,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>o$(e.overlayRect)-o$(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oF(e.overlayRect,r.overlayRect)||oF(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}o$(r.overlayRect)<o$(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:oU(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:oU(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:k(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,i;(function(e,t,r){for(let a=0;a<2;a+=1)oj(e,t.x,t.x+t.width-1,t.y+a,r),oj(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),oq(e,t.x+a,t.y,t.y+t.height-1,r),oq(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,oN),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oV(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:oV(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)oB(e,t+o,r+n,i)})(e,i,o,a,ok),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oM[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&oB(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,ox)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,m.sync.write(t)),r}function oP(e){let t=[e.type,e.role,e.subrole].map(e=>T(e??"")).join(" ");return t.includes("button")||t.includes("link")||t.includes("menu")||t.includes("tab")||t.includes("textfield")||t.includes("searchfield")||t.includes("securetextfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("cell")}function oL(e){let t=[e.type,e.role,e.subrole].map(e=>T(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oR(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oO(e){var t;let r;return!!oR(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oE(e){var t;return"string"==typeof e&&!!oO(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oC(e){let t=[e.label,e.value].find(oO);return t?t.trim():oE(e.identifier)?e.identifier.trim():void 0}function oT(e){return!!(e&&e.width>0&&e.height>0)}function o$(e){return e.width*e.height}function oF(e,t){return t.x>=e.x&&t.y>=e.y&&t.x+t.width<=e.x+e.width&&t.y+t.height<=e.y+e.height}function oU(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oG(e,t,r){let a=oV(e.x,0,Math.max(0,t-1)),i=oV(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:oV(e.width,1,n),height:oV(e.height,1,o)}}function oV(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oj(e,t,r,a,i){for(let n=t;n<=r;n+=1)oB(e,n,a,i)}function oq(e,t,r,a,i){for(let n=r;n<=a;n+=1)oB(e,t,n,i)}function oB(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let i=(e.width*r+t)*4;e.data[i]=a[0],e.data[i+1]=a[1],e.data[i+2]=a[2],e.data[i+3]=a[3]}let oH=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),oz=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),oK=new Set(oz),oW=new Map;function oJ(e,t,r,a){let i=eJ().requestId;return{...eD(e,t,r,a,i),requestId:i}}async function oZ(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||r3(e.flags))try{let t=await ef(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function oX(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await ov({req:t,leaseRegistry:n});if(l)return l;let d=await i1({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await E({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await nG({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await i2({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await og({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:s});return p||null}async function oY(e){var t,r;let a,i,n,o,s,l,d,{req:u,session:c,logPath:f,sessionStore:p}=e,m=u.command;if(!Q(m,c.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${m} is not supported on this device`}};if("android"===c.device.platform&&c.recording&&"record"!==m&&"failed"===await od({session:c}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:h,resolvedOut:g,recordedPositionals:w,recordedFlags:y}=(a=(t=u).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tO.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tO.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?o:i,d="screenshot"===a&&s?{...t.flags??{},out:s}:t.flags??{},{resolvedPositionals:o,resolvedOut:s,recordedPositionals:l,recordedFlags:d}),v=Date.now(),S={...oJ(f,u.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},A="screenshot"===m?await ob({session:c,sessionName:e.sessionName,outPath:h[0]??g,outputPlacement:"screenshot"!==(r=u).command?"default":(r.positionals??[])[0]?"positional":r.flags?.out?"out":"default",dispatchContext:S}):await I(c.device,m,h,g,{...S});return"screenshot"===m&&u.flags?.overlayRefs&&"string"==typeof A?.path&&await oQ(c,A,f),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=nq(e.snapshot),n={...a??{}},o=nJ(n.direction)??nJ(r[0]);if(!o)return a;let s=nZ(n.amount)??nZ(r[1]),l=nZ(n.pixels),d=nQ(n,[]),u=nZ(n.referenceWidth),c=nZ(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??nH;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...n,x1:d.x1,y1:d.y1,x2:d.x2,y2:d.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==l?{pixels:l}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=x({direction:o,amount:s,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,s);nz(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:A,actionStartedAt:v,actionFinishedAt:Date.now(),flags:u.flags??{}}),K(m)&&ta(c,m),{ok:!0,data:A??{}}}async function oQ(e,t,r){let a=ex(await eP({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oD({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function o0(e){i.existsSync(e)&&i.unlinkSync(e)}function o1(e){if(!i.existsSync(e))return null;try{let t=JSON.parse(i.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function o2(e){let t=o1(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function o4(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:o3,infoPath:o5,lockPath:o8,logPath:o6,sessionsDir:o9}=tr(process.env.AGENT_DEVICE_STATE_DIR),o7=ti(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var se=o9;if(i.existsSync(se))for(let e of i.readdirSync(se,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=o.join(se,e.name,tC);if(i.existsSync(t))try{let e=tT(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=e9(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=y(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{tF(t)}}let st=new tO(o9),sr=new rB({maxActiveSimulatorLeases:o4(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:o4(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:o4(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:o4(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),sa=e8(),si=a.randomBytes(24).toString("hex"),sn=e9(process.pid)??void 0,so=ew(),ss=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:n}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await e7({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:tu(new tc("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=J(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=eA(r);if(r&&!a)throw new tc("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new tc("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let i=e.session||"default";return i.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${i}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);e0({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let l=r.command,d=oy(r);oz.has(l)||r.meta?.sessionIsolation!=="tenant"||i.assertLeaseAdmission({tenantId:d.tenantId,runId:d.runId,leaseId:d.leaseId,backend:d.leaseBackend});let u=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,a),c=oK.has(l)?null:await oZ(r,u,a),f=async()=>{let e=a.get(u);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=eF(e.device.id);if(!t.runnerSessionId){r?.alive&&(t.runnerSessionId=r.sessionId);return}if(!r?.alive){t.invalidatedReason??="iOS runner session exited during recording";return}r.sessionId!==t.runnerSessionId&&(t.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(u,e));let d=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?oI(t,a):function(e,t,r){var a,i;let n=[],o=w(t);if(void 0!==e.platform&&o&&(a=w(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!L(i):"apple"!==i||!L(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of oA){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 oA)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new tc("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oS).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=eJ();if(!t.ok){e0({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=tn({force:!0})??void 0;return{ok:!1,error:tu(new tc(t.error.code,t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return e0({level:"info",phase:"request_success"}),tn(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let s=(a=e,i=t,n=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||n.some(e=>e?.field==="path")||"string"!=typeof i.path||n.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:o.basename(a.meta?.clientArtifactPaths?.path??i.path)}),n.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(d,e,n);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||oH.has(l)||function(e,t){let r=oI(e,t);if(0!==r.length){var a;let t,i,n;throw new tc("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oS).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await oX({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...oJ(t,e,r,i),surface:a.get(u)?.surface})});if(f)return c(f);let p=a.get(u);if(!p)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await oY({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await ea(oW,c,f)}catch(r){e0({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=eJ(),t=tn({force:!0})??void 0;return{ok:!1,error:tu(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:o6,token:si,sessionStore:st,leaseRegistry:sr,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{rm(t)},9e5);return r.unref(),rp.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){i.existsSync(e)||i.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return i.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=o1(t);if(o?.pid&&o.pid!==process.pid&&A(o.pid,o.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(o3,o8,{pid:process.pid,version:sa,startedAt:Date.now(),processStartTime:sn})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===o7||"dual"===o7){let t=h.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))ej(e);e0({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await eT(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){e0({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:r}})}})()}};e.setEncoding("utf8"),e.on("close",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eO(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),W(o),eR(o))throw z();i=await ss(e)}catch(e){i={ok:!1,error:tu(e)}}finally{r-=1,o&&(a.delete(o),eX(o))}e.destroyed||e.write(`${JSON.stringify(i)}
|
|
35
|
-
`),n=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new
|
|
33
|
+
`.trim();async function ni(e,t={}){let r,a=t.pollMs??150,n=t.attempts??12,o=0;for(let t=0;t<n;t+=1){let t=0;try{t=i.statSync(e).size}catch{t=0}if(t>0&&t===r){if((o+=1)>=2)return}else o=0;r=t,await new Promise(e=>setTimeout(e,a))}}async function nn(e){try{var t,r;let a,i=await U("swift",["-",e],{stdin:na,allowFailure:!0,timeoutMs:1e4});if(0===i.exitCode)return!0;if(t=i.stderr,r=i.stdout,a=`${t}
|
|
34
|
+
${r}`,/\b(no such module ['"]AVFoundation['"]|unable to find utility ["']swift["']|xcrun: error: unable to find utility ["']swift["'])\b/i.test(a))return ns(e);return!1}catch(t){if(t instanceof T&&"TOOL_MISSING"===t.code)return ns(e);throw t}}async function no(e,t={}){let r=t.pollMs??150,a=t.attempts??12;for(let t=0;t<a;t+=1){if(await nn(e))return;await new Promise(e=>setTimeout(e,r))}}function ns(e){try{let t=i.statSync(e);if(!t.isFile()||t.size<=0)return!1}catch{return!1}let t=function(e){try{let t=i.openSync(e,"r");try{let e=i.fstatSync(t).size,r=0,a=[];for(;r+8<=e&&a.length<16;){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r))break;let n=e.readUInt32BE(0),o=e.toString("latin1",4,8);if(a.push(o),1===n){let e=Buffer.alloc(8);if(8>i.readSync(t,e,0,8,r+8))break;n=Number(e.readBigUInt64BE(0))}if(!Number.isFinite(n)||n<=0)break;r+=n}return a}finally{i.closeSync(t)}}catch{return[]}}(e);return t.includes("ftyp")&&t.includes("moov")}function nl(e){let t=o.parse(e);return o.join(t.dir,`${t.name}.gesture-telemetry.json`)}function nd(e){return[...e].sort((e,t)=>e.tMs-t.tMs)}function nu(e){let t=o.dirname(d(import.meta.url)),r=[d(new URL(`./${e}`,import.meta.url)),o.resolve(t,`../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(t,`../../../ios-runner/AgentDeviceRunner/RecordingScripts/${e}`),o.resolve(process.cwd(),`ios-runner/AgentDeviceRunner/RecordingScripts/${e}`)];for(let e of r)if(i.existsSync(e))return e;throw new T("COMMAND_FAILED",`Missing recording helper script: ${e}`,{hint:"Ensure ios-runner/AgentDeviceRunner/RecordingScripts is present in this checkout or bundled with the package.",scriptName:e,searchedPaths:r})}async function nc(e){let{videoPath:t,scriptPath:r,scriptArgs:a,commandDescription:n}=e;await ni(t),await no(t);let s=i.mkdtempSync(o.join(c.tmpdir(),"agent-device-record-overlay-")),l=o.join(s,`input${o.extname(t)||".mp4"}`),d=o.join(s,o.basename(t)),u=o.join(s,"home"),f=o.join(s,"module-cache");i.copyFileSync(t,l),i.mkdirSync(u,{recursive:!0}),i.mkdirSync(f,{recursive:!0});try{await U("xcrun",["swift",r,"--input",l,"--output",d,...a],{timeoutMs:12e4,env:{...process.env,HOME:u,CLANG_MODULE_CACHE_PATH:f}}),await no(d),i.copyFileSync(d,t)}catch(a){let e=a instanceof T?a:new T("COMMAND_FAILED",String(a),void 0,a instanceof Error?a:void 0);throw new T("COMMAND_FAILED",n,{videoPath:t,script:r,stderr:e.details?.stderr,stdout:e.details?.stdout,exitCode:e.details?.exitCode,processExitError:e.details?.processExitError},e)}finally{i.rmSync(s,{recursive:!0,force:!0})}}async function nf(e){let{videoPath:r,trimStartMs:a}=e;a>0&&await nc({videoPath:r,scriptPath:t??=nu("recording-trim.swift"),scriptArgs:["--trim-start-ms",String(a)],commandDescription:"Failed to trim the start of the iOS recording"})}async function np(t){let{videoPath:r,telemetryPath:a,targetLabel:i="recording"}=t;await nc({videoPath:r,scriptPath:e??=nu("recording-overlay.swift"),scriptArgs:["--events",a],commandDescription:`Failed to add touch overlays to the ${i}`})}async function nm(e){let{videoPath:t,quality:a,targetLabel:i="recording"}=e;await nc({videoPath:t,scriptPath:r??=nu("recording-resize.swift"),scriptArgs:["--quality",String(a)],commandDescription:`Failed to resize the ${i}`})}function nh(e){return e instanceof Error?e.message:String(e)}function ng(e,t){return e.stderr.trim()||e.stdout.trim()||`${t} exited with code ${e.exitCode}`}async function nw(e){let{recording:t,deps:r,trimStartMs:a,targetLabel:n}=e,o=function(e){var t,r,a;let n,o,{recording:s,trimStartMs:l}=e,d=(n=nl((t={videoPath:s.outPath,events:s.gestureEvents,trimStartMs:l}).videoPath),o={version:1,generatedAt:new Date().toISOString(),events:(r=t.events,(a=t.trimStartMs??0)>0?nd(r.flatMap(e=>{let t=e.tMs-a,r="durationMs"in e?e.durationMs:void 0;return("number"==typeof r?t+r:t)<=0?[]:[{...e,tMs:Math.max(0,t)}]})):nd(r))},i.writeFileSync(n,JSON.stringify(o,null,2)),n);return s.telemetryPath=d,d}({recording:t,trimStartMs:a});if(t.showTouches){let e=function(e=process.platform){if("darwin"!==e)return"touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry"}();if(e)t.overlayWarning??=e;else try{await r.overlayRecordingTouches({videoPath:t.outPath,telemetryPath:o,targetLabel:n})}catch(e){t.overlayWarning??=`failed to overlay recording touches: ${nh(e)}`}}}async function ny(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","ps","-o","pid=","-p",r],{allowFailure:!0});return 0===a.exitCode&&a.stdout.split(/\s+/).map(e=>e.trim()).includes(r)}async function nv(e,t,r){for(let a=0;a<40;a+=1){if(!await ny(e,t,r))return!0;await new Promise(e=>setTimeout(e,250))}return!await ny(e,t,r)}async function nI(e,t,r){let a,i=0;for(let n=0;n<20;n+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?n.stdout.trim():"";if(o.length>0&&o===a){if((i+=1)>=4)return}else i=0;a=o,await new Promise(e=>setTimeout(e,250))}}async function nS(e,t,r,a){for(let i=0;i<8;i+=1){let n=await e.runCmd("adb",["-s",t,"shell","stat","-c","%s",r],{allowFailure:!0}),o=0===n.exitCode?Number(n.stdout.trim()):NaN;if(Number.isFinite(o)&&o>0)return!0;if(!await ny(e,t,a))break;if(i+1>=2)return!0;await new Promise(e=>setTimeout(e,250))}return!1}async function nA(e){let t,{deps:r,deviceId:a,remotePath:n,outPath:o}=e;for(let e=0;e<2;e+=1){try{i.rmSync(o,{force:!0})}catch{}let s=await r.runCmd("adb",["-s",a,"pull",n,o],{allowFailure:!0});if(0!==s.exitCode)t=ng(s,"adb pull");else{await r.waitForStableFile(o,{pollMs:250,attempts:20});let t=await r.isPlayableVideo(o);if(P({level:"debug",phase:"record_stop_android_pull_validation",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1,fileSize:(()=>{try{return i.statSync(o).size}catch{return 0}})(),playable:t}}),t)return;P({level:"warn",phase:"record_stop_android_invalid_video_retry",data:{deviceId:a,remotePath:n,outPath:o,attempt:e+1}})}e<1&&await new Promise(e=>setTimeout(e,750))}return t?`failed to copy recording from device: ${t}`:"failed to copy recording from device: pulled file is not a playable MP4"}async function nb(e){let{deps:t,deviceId:r,quality:a}=e;if(void 0===a||a>=10)return;let i=await t.runCmd("adb",["-s",r,"shell","wm","size"],{allowFailure:!0}),n=i.stdout.match(/Override size:\s*(\d+)x(\d+)/)??i.stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(0!==i.exitCode||!n)throw Error(`failed to resolve Android screen size for recording quality: ${ng(i,"adb shell wm size")}`);return{width:n_(Number(n[1]),a),height:n_(Number(n[2]),a)}}function n_(e,t){return Math.max(2,2*Math.round(e*t/10/2))}async function nN(e,t,r){await e.runCmd("adb",["-s",t,"shell","rm","-f",r],{allowFailure:!0})}async function nk(e,t,r){let a=await e.runCmd("adb",["-s",t,"shell","kill","-9",r],{allowFailure:!0});return P({level:"warn",phase:"record_stop_android_force_signal",data:{deviceId:t,remotePid:r,exitCode:a.exitCode,stdout:a.stdout.trim(),stderr:a.stderr.trim()}}),!(0!==a.exitCode&&await ny(e,t,r))&&await nv(e,t,r)}async function nM(e){var t;let r,a,{deps:i,device:n,recordingBase:o}=e,s="failed to start recording: Android screenrecord did not begin producing frames";try{r=await nb({deps:i,deviceId:n.id,quality:o.quality})}catch(e){return eq("COMMAND_FAILED",e instanceof Error?e.message:String(e))}for(let e of(t=Date.now(),a=`agent-device-recording-${t}.mp4`,[`/sdcard/${a}`,`/data/local/tmp/${a}`])){let t=await i.runCmd("adb",["-s",n.id,"shell",function(e,t){let r=["screenrecord"];return t&&r.push("--size",`${t.width}x${t.height}`),r.push(e),`${r.join(" ")} >/dev/null 2>&1 & echo $!`}(e,r)],{allowFailure:!0});if(0!==t.exitCode){s=`failed to start recording: ${ng(t,"adb shell screenrecord")}`;continue}let a=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(e=>/^\d+$/.test(e)).at(-1);if(!a){s="failed to start recording: adb did not return a valid Android screenrecord pid",await nN(i,n.id,e);continue}if(P({level:"debug",phase:"record_start_android_started",data:{deviceId:n.id,remotePath:e,remotePid:a}}),await nS(i,n.id,e,a))return{platform:"android",remotePath:e,remotePid:a,...o,startedAt:Date.now()};s="failed to start recording: Android screenrecord did not begin producing frames",await nk(i,n.id,a),await nN(i,n.id,e)}return eq("COMMAND_FAILED",s)}async function nx(e){let t,r,{deps:a,device:i,recording:n}=e;P({level:"debug",phase:"record_stop_android_enter",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid}});let o=await a.runCmd("adb",["-s",i.id,"shell","kill","-2",n.remotePid],{allowFailure:!0});if(P({level:"debug",phase:"record_stop_android_signal",data:{deviceId:i.id,remotePath:n.remotePath,remotePid:n.remotePid,exitCode:o.exitCode,stdout:o.stdout.trim(),stderr:o.stderr.trim()}}),0!==o.exitCode?await ny(a,i.id,n.remotePid)&&!await nk(a,i.id,n.remotePid)&&(t=`failed to stop recording: ${ng(o,"adb shell kill")}`):await nv(a,i.id,n.remotePid)||await nk(a,i.id,n.remotePid)||(t=`failed to stop recording: Android screenrecord pid ${n.remotePid} did not exit`),!t){await nI(a,i.id,n.remotePath);let e=await nA({deps:a,deviceId:i.id,remotePath:n.remotePath,outPath:n.outPath});if(e)return await s(),eq("COMMAND_FAILED",e);await nw({recording:n,deps:a,targetLabel:"Android recording"})}if(await s(),t)return eq("COMMAND_FAILED",t);if(r)return eq("COMMAND_FAILED",r);return null;async function s(){let e=await a.runCmd("adb",["-s",i.id,"shell","rm","-f",n.remotePath],{allowFailure:!0});P({level:"debug",phase:"record_stop_android_cleanup",data:{deviceId:i.id,remotePath:n.remotePath,exitCode:e.exitCode,stdout:e.stdout.trim(),stderr:e.stderr.trim()}}),0===e.exitCode||t||(r=`failed to clean up remote recording: ${ng(e,"adb shell rm")}`)}}function nD(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function nP(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function nL(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n}=e,o=nD(r);if(o)try{await n.runIosRunnerCommand(a,{command:"snapshot",appBundleId:o,interactiveOnly:!0,compact:!0,depth:1},nP(t,i,r))}catch(e){P({level:"warn",phase:"record_start_simulator_runner_warm_failed",data:{deviceId:a.id,session:r.name,appBundleId:o,error:nh(e)}})}}async function nR(e){let t,r,{req:a,activeSession:i,sessionStore:n,device:o,logPath:s,deps:l,fpsFlag:d,recordingBase:u,appBundleId:c}=e,f=`agent-device-recording-${Date.now()}.mp4`,p=`tmp/${f}`,m=nP(a,s,i),h=async()=>l.runIosRunnerCommand(o,{command:"recordStart",outPath:f,fps:d,quality:u.quality,appBundleId:c},m);try{let e=await h();t="number"==typeof e.recorderStartUptimeMs?e.recorderStartUptimeMs:void 0,r="number"==typeof e.targetAppReadyUptimeMs?e.targetAppReadyUptimeMs:void 0}catch(a){var g,w;if(!nh(a).toLowerCase().includes("recording already in progress"))return eq("COMMAND_FAILED",`failed to start recording: ${nh(a)}`);P({level:"warn",phase:"record_start_runner_desynced",data:{platform:o.platform,kind:o.kind,deviceId:o.id,session:i.name,error:nh(a)}});let e=(g=o.id,w=i.name,n.toArray().find(e=>e.name!==w&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===g&&e.recording?.platform==="ios-device-runner"));if(e)return eq("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 eq("COMMAND_FAILED",`failed to start recording: ${nh(e)}`)}}return{platform:"ios-device-runner",remotePath:p,runnerStartedAtUptimeMs:t,targetAppReadyUptimeMs:r,...u}}async function nO(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,fpsFlag:o,recordingBase:s,appBundleId:l}=e;try{await n.runIosRunnerCommand(a,{command:"recordStart",outPath:s.outPath,fps:o,quality:s.quality,appBundleId:l},nP(t,i,r))}catch(e){return eq("COMMAND_FAILED",`failed to start recording: ${nh(e)}`)}return{platform:"macos-runner",...s}}async function nC(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nD(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nP(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nh(e)}})}let l={stdout:"",stderr:"",exitCode:1};for(let e of e5)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 eq("COMMAND_FAILED",`failed to copy recording from device: ${e}`)}let d="number"!=typeof o.runnerStartedAtUptimeMs||"number"!=typeof o.targetAppReadyUptimeMs?0:Math.max(0,o.targetAppReadyUptimeMs-o.runnerStartedAtUptimeMs);return d>0&&await n.trimRecordingStart({videoPath:o.outPath,trimStartMs:d}),await nw({recording:o,deps:n,trimStartMs:d,targetLabel:"iOS recording"}),null}async function nE(e){let{req:t,activeSession:r,device:a,logPath:i,deps:n,recording:o}=e,s=nD(r);try{await n.runIosRunnerCommand(a,{command:"recordStop",appBundleId:s},nP(t,i,r))}catch(e){P({level:"warn",phase:"record_stop_runner_failed",data:{platform:a.platform,kind:a.kind,deviceId:a.id,session:r.name,error:nh(e)}})}return await nw({recording:o,deps:n,targetLabel:"macOS recording"}),null}async function nT(e){for(let t=0;t<2;t+=1){try{if(i.statSync(e).size>0)return Date.now()}catch{}if(t+1>=2)break;await new Promise(e=>setTimeout(e,250))}return Date.now()}async function n$(e){let t,r,{req:a,activeSession:i,device:n,logPath:o,deps:s,recordingBase:l,resolvedOut:d}=e;await nL({req:a,activeSession:i,device:n,logPath:o,deps:s});let{child:u,wait:c}=s.runCmdBackground("xcrun",z(n,["io",n.id,"recordVideo",d]),{allowFailure:!0}),f=await nT(d);try{let e=Date.now(),l=await s.runIosRunnerCommand(n,{command:"uptime",appBundleId:nD(i)},{verbose:a.flags?.verbose,logPath:o,traceLogPath:i.trace?.outPath}),d=Date.now();t=Math.round((e+d)/2),r="number"==typeof l.currentUptimeMs?l.currentUptimeMs:void 0}catch{}return{platform:"ios",child:u,wait:c,...l,startedAt:f,gestureClockOriginAtMs:void 0===r?void 0:t,gestureClockOriginUptimeMs:r}}async function nU(e){let t,{req:r,sessionName:a,sessionStore:n,activeSession:s,device:l,logPath:d,deps:u}=e;if(s.recording)return eq("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 eq("INVALID_ARGS","fps must be an integer between 1 and 120");if(void 0!==f&&(!Number.isInteger(f)||f<5||f>10))return eq("INVALID_ARGS","quality must be an integer between 5 and 10");if(!ep("record",l))return eq("UNSUPPORTED_OPERATION","record is not supported on this device");let p=r.positionals?.[1]??`./recording-${Date.now()}.mp4`,m=tE.expandHome(p,r.meta?.cwd),h={outPath:m,clientOutPath:r.meta?.clientArtifactPaths?.outPath,startedAt:Date.now(),quality:r.flags?.quality,showTouches:r.flags?.hideTouches!==!0,gestureEvents:[]};if(i.mkdirSync(o.dirname(m),{recursive:!0}),i.rmSync(m,{force:!0}),"ios"===l.platform&&"device"===l.kind){let e=nD(s);if(!e)return eq("INVALID_ARGS","record on physical iOS devices requires an active app session; run open <app> first");t=await nR({req:r,activeSession:s,sessionStore:n,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else if("macos"===l.platform){let e=nD(s);if(!e)return eq("INVALID_ARGS","record on macOS requires an active app session; run open <app> first");t=await nO({req:r,activeSession:s,device:l,logPath:d,deps:u,fpsFlag:c,recordingBase:h,appBundleId:e})}else t="ios"===l.platform?await n$({req:r,activeSession:s,device:l,logPath:d,deps:u,recordingBase:h,resolvedOut:m}):await nM({deps:u,device:l,recordingBase:h});return"ok"in t?t:(s.recording=t,n.set(a,s),n.recordAction(s,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:{action:"start",showTouches:t.showTouches}}),{ok:!0,data:{recording:"started",outPath:t.clientOutPath??p,showTouches:t.showTouches}})}async function nF(e){let{deps:t,device:r,recording:a}=e;if("android"===a.platform)return await nx({deps:t,device:r,recording:a});a.child.kill("SIGINT");let i=await a.wait;if(0!==i.exitCode)return eq("COMMAND_FAILED",`failed to stop recording: ${ng(i,"simctl recordVideo")}`);if(void 0!==a.quality&&a.quality<10)try{await t.resizeRecording({videoPath:a.outPath,quality:a.quality,targetLabel:"iOS recording"})}catch(e){a.overlayWarning=`failed to resize recording: ${nh(e)}`}return await nw({recording:a,deps:t,targetLabel:"iOS recording"}),null}async function nG(e){var t;let r,{req:a,activeSession:i,device:n,logPath:s,deps:l}=e;if(!i.recording)return eq("INVALID_ARGS","no active recording");let d=i.recording,u=d.invalidatedReason;i.recording=void 0;let c="ios-device-runner"===d.platform?await nC({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):"macos-runner"===d.platform?await nE({req:a,activeSession:i,device:n,logPath:s,deps:l,recording:d}):await nF({deps:l,device:n,recording:d});return c||(u?eq("COMMAND_FAILED",u):(r=[{field:"outPath",path:(t=d).outPath,localPath:t.clientOutPath,fileName:o.basename(t.clientOutPath??t.outPath)}],t.telemetryPath&&r.push({field:"telemetryPath",path:t.telemetryPath,localPath:function(e){if(e.clientOutPath)return nl(e.clientOutPath)}(t),fileName:o.basename(t.telemetryPath)}),{ok:!0,data:{recording:"stopped",outPath:t.outPath,telemetryPath:t.telemetryPath,artifacts:r,showTouches:t.showTouches,overlayWarning:t.overlayWarning}}))}async function nV(e){let{req:t,sessionName:r,sessionStore:a,logPath:i}=e,n={runCmd:U,runCmdBackground:$,runIosRunnerCommand:ei,waitForStableFile:ni,isPlayableVideo:nn,trimRecordingStart:nf,resizeRecording:nm,overlayRecordingTouches:np},o=a.get(r),s=o?.device??await eh(t.flags??{});o||await eB(s);let l=o??{name:r,device:s,createdAt:Date.now(),actions:[]},d=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(d))return eq("INVALID_ARGS","record requires start|stop");if("start"===d)return nU({req:t,sessionName:r,sessionStore:a,activeSession:l,device:s,logPath:i,deps:n});let u=await nG({req:t,activeSession:l,device:s,logPath:i,deps:n});return u.ok&&a.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:u.data?.outPath,showTouches:u.data?.showTouches}}),u}async function nj(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,s=t.command;if("record"===s)return nV({req:t,sessionName:r,sessionStore:a,logPath:n});if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return eq("INVALID_ARGS","trace requires start|stop");let n=a.get(r);if(!n)return eq("SESSION_NOT_FOUND","No active session");if("start"===e){if(n.trace)return eq("INVALID_ARGS","trace already in progress");let e=t.positionals?.[1]??a.defaultTracePath(n),r=tE.expandHome(e);return i.mkdirSync(o.dirname(r),{recursive:!0}),i.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return eq("INVALID_ARGS","no active trace");let l=n.trace.outPath;if(t.positionals?.[1]){let e=tE.expandHome(t.positionals[1]);i.mkdirSync(o.dirname(e),{recursive:!0}),i.existsSync(l)?i.renameSync(l,e):i.appendFileSync(e,""),l=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:l}}),{ok:!0,data:{trace:"stopped",outPath:l}}}return null}function nq(e){return"number"==typeof e.gestureClockOriginAtMs&&"number"==typeof e.gestureClockOriginUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureClockOriginAtMs+(e.gestureStartUptimeMs-e.gestureClockOriginUptimeMs)-e.recordingStartedAt):"number"==typeof e.runnerStartedAtUptimeMs&&"number"==typeof e.gestureStartUptimeMs?Math.max(0,e.gestureStartUptimeMs-e.runnerStartedAtUptimeMs):"number"==typeof e.gestureStartUptimeMs&&"number"==typeof e.gestureEndUptimeMs?Math.max(0,e.fallbackFinishedAtMs-(e.gestureEndUptimeMs-e.gestureStartUptimeMs)-e.recordingStartedAt):Math.max(0,e.fallbackStartedAtMs-e.recordingStartedAt)}let nH=new WeakMap;function nB(e){if(!e)return;let t=nH.get(e);if(t)return t;let r=function(e){let t=function(e){let t=e.filter(e=>(function(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("application")||t.includes("window")})(e.type)&&nK(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(nK);if(0===r.length)return;let a=Math.max(...r.map(e=>e.x+e.width)),i=Math.max(...r.map(e=>e.y+e.height));if(!(a<=0)&&!(i<=0))return{x:0,y:0,width:a,height:i}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}(e.nodes??[]);if(r)return nH.set(e,r),r}function nK(e){return!!e&&e.width>0&&e.height>0}let nz={referenceWidth:1e3,referenceHeight:1e3};function nW(e,t,r,a,i={},n=Date.now(),o=Date.now()){var s,l,d;let u,c,f=e.recording;if(!f)return;let p={...i,...a??{}},m=nY(p.effectiveDurationMs)??nY(p.durationMs),h={recordingStartedAt:f.startedAt,gestureClockOriginAtMs:f.gestureClockOriginAtMs,gestureClockOriginUptimeMs:f.gestureClockOriginUptimeMs,runnerStartedAtUptimeMs:"ios-device-runner"===f.platform?f.runnerStartedAtUptimeMs:void 0,gestureStartUptimeMs:nY(p.gestureStartUptimeMs),gestureEndUptimeMs:nY(p.gestureEndUptimeMs),fallbackStartedAtMs:n,fallbackFinishedAtMs:o},g="number"==typeof(s={gestureStartUptimeMs:nY(p.gestureStartUptimeMs),gestureEndUptimeMs:nY(p.gestureEndUptimeMs),reportedDurationMs:m,fallbackStartedAtMs:n,fallbackFinishedAtMs:o}).gestureStartUptimeMs&&"number"==typeof s.gestureEndUptimeMs?Math.max(0,s.gestureEndUptimeMs-s.gestureStartUptimeMs):"number"==typeof s.reportedDurationMs?Math.max(0,s.reportedDurationMs):Math.max(0,s.fallbackFinishedAtMs-s.fallbackStartedAtMs),w="ios"===e.device.platform&&void 0===nY(p.gestureStartUptimeMs)&&function(e,t){switch(e){case"click":case"fill":case"focus":return!0;case"press":{let e=nQ(nY(t.count),1)??1,r=!0===t.doubleTap,a=nQ(nY(t.holdMs),1);return 1===e&&!r&&void 0===a}default:return!1}}(t,p)?function(e){let t=Math.max(0,e.gestureDurationMs);if(t<600)return nq(e);let r=Math.min(Math.max(.15*t,120),260);return Math.max(0,e.fallbackFinishedAtMs-r-e.recordingStartedAt)}({...h,gestureDurationMs:g}):nq(h),y=(l=e.snapshot,u=nY((d=p).referenceWidth),c=nY(d.referenceHeight),void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:nB(l)),v=function(e,t,r,a,i,n){switch(e){case"click":case"press":return function(e,t,r,a){let i=n0(t,e);if(!i)return[];let{x:n,y:o}=i,s=nQ(nY(t.count),1)??1,l=nQ(nY(t.intervalMs),0)??0,d=!0===t.doubleTap,u=nQ(nY(t.holdMs),1),c=[];for(let e=0;e<s;e+=1){let t=r+e*l;if(void 0!==u&&u>0){c.push(nZ(t,n,o,u,a));continue}c.push(nJ(t,n,o,a)),d&&c.push(nJ(t+90,n,o,a))}return c}(t,r,a,n);case"fill":case"focus":return function(e,t,r,a){let i=n0(t,e);if(!i)return[];let{x:n,y:o}=i;return[nJ(r,n,o,a)]}(t,r,a,n);case"longpress":return function(e,t,r,a,i){let n=n0(t,e);if(!n)return[];let{x:o,y:s}=n;return[nZ(r,o,s,n2(a,[nY(t.durationMs),nY(e[2])],800),i)]}(t,r,a,i,n);case"scroll":return function(e,t,r,a,i){let n=n1(t,e),o=nX(t.contentDirection)??nX(t.direction);if(!n||!o)return[];let{x1:s,y1:l,x2:d,y2:u}=n,c=n2(a,[],250),f=nY(t.amount)??nY(e[1]),p=nY(t.pixels);return[{kind:"scroll",tMs:r,x:s,y:l,x2:d,y2:u,...i,durationMs:c,contentDirection:o,...void 0!==f?{amount:f}:{},...void 0!==p?{pixels:p}:{}}]}(t,r,a,i,n);case"swipe":return function(e,t,r,a,i){let n=n1(t,e);if(!n)return[];let{x1:o,y1:s,x2:l,y2:d}=n,u=n2(a,[nY(t.effectiveDurationMs),nY(t.durationMs),nY(e[4])],250),c=nQ(nY(t.count),1)??1,f=nQ(nY(t.pauseMs),0)??0,p="ping-pong"===t.pattern?"ping-pong":"one-way",m=[];for(let e=0;e<c;e+=1){let t="ping-pong"===p&&e%2==1,a=t?l:o,n=t?d:s,c=t?o:l,h=t?s:d,g=r+e*(u+f);if("back-swipe"===function(e,t,r,a,i){if(!i||Math.abs(r-e)<=1.25*Math.abs(a-t))return"swipe";let n=.08*i.referenceWidth;return e<=n&&r>e||e>=i.referenceWidth-n&&r<e?"back-swipe":"swipe"}(a,n,c,h,i)){m.push({kind:"back-swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u,edge:function(e,t,r){if(r){let t=.08*r.referenceWidth;if(e<=t)return"left";if(e>=r.referenceWidth-t)return"right"}return t>=e?"left":"right"}(a,c,i)});continue}m.push({kind:"swipe",tMs:g,x:a,y:n,x2:c,y2:h,...i,durationMs:u})}return m}(t,r,a,i,n);case"pinch":return function(e,t,r,a,i){let n=n0(t,e,1),o=nY(t.scale)??nY(e[0]);if(!n||void 0===o||o<=0)return[];let{x:s,y:l}=n;return[{kind:"pinch",tMs:r,x:s,y:l,...i,scale:o,durationMs:n2(a,[],280)}]}(t,r,a,i,n);default:return[]}}(t,r,p,w,g,y);0!==v.length&&(f.gestureEvents.push(...v),P({level:"debug",phase:"record_touch_visualization_event",data:{session:e.name,command:t,count:v.length,tMs:w,gestureDurationMs:g,kinds:v.map(e=>e.kind)}}))}function nJ(e,t,r,a){return{kind:"tap",tMs:e,x:t,y:r,...a}}function nZ(e,t,r,a,i){return{kind:"longpress",tMs:e,x:t,y:r,...i,durationMs:a}}function nX(e){if("string"!=typeof e)return;let t=e.trim().toLowerCase();switch(t){case"up":case"down":case"left":case"right":return t;default:return}}function nY(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"!=typeof e||0===e.trim().length)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function nQ(e,t){if(void 0===e)return;let r=Math.floor(e);return r>=t?r:void 0}function n0(e,t,r=0){let a=nY(e.x)??nY(t[r]),i=nY(e.y)??nY(t[r+1]);if(void 0!==a&&void 0!==i)return{x:a,y:i}}function n1(e,t){let r=nY(e.x1)??nY(t[0]),a=nY(e.y1)??nY(t[1]),i=nY(e.x2)??nY(t[2]),n=nY(e.y2)??nY(t[3]);if(void 0!==r&&void 0!==a&&void 0!==i&&void 0!==n)return{x1:r,y1:a,x2:i,y2:n}}function n2(e,t,r){return nQ(e,1)??t.map(e=>nQ(e,1)).find(e=>void 0!==e)??r}function n3(e){var t,r,a;let i,n,{data:o,fallbackX:s,fallbackY:l,referenceFrame:d,extra:u}=e,c=(t=u,r=s,a=l,i="string"==typeof t?.ref?t.ref:void 0,n="string"==typeof t?.button?t.button:void 0,("string"==typeof t?.text?`Filled ${Array.from(t.text).length} chars`:i?n&&"primary"!==n?`Clicked ${n} @${i} (${r}, ${a})`:`Tapped @${i} (${r}, ${a})`:void 0)??("string"==typeof o?.message?o.message:void 0));return{x:s,y:l,...d??{},...u??{},...o??{},...e7(c)}}function n8(e){let{session:t,sessionStore:r,command:a,positionals:i,flags:n,result:o,responseData:s,actionStartedAt:l,actionFinishedAt:d}=e;return r.recordAction(t,{command:a,positionals:i,flags:n??{},result:o}),eu(a)&&e8(t,a),nW(t,a,i,o,n??{},l,d),{ok:!0,data:s}}async function n4(e){let{session:t,flags:r,sessionStore:a,contextFromFlags:i,captureSnapshotForSession:n}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if("android"===t.device.platform){let e=await eb(t.device),r={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=r),r}let o=nB(t.snapshot);if(o)return t.recording&&(t.recording.touchReferenceFrame=o),o;if(!t.recording)return;let s=nB(await n(t,r,a,i,{interactiveOnly:!0}));return s&&t.recording&&(t.recording.touchReferenceFrame=s),s}async function n5(e){try{return await n4(e)}catch(t){P({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function n9(e){return nB({nodes:e,createdAt:0})}function n6(e,t){return"macos"!==e.device.platform||"desktop"!==e.surface&&"menubar"!==e.surface||"menubar"===e.surface&&("click"===t||"press"===t)?null:eq("UNSUPPORTED_OPERATION",`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function n7(e){let t=e.sessionStore.get(e.sessionName);if(!t)throw new T("SESSION_NOT_FOUND","No active session. Run open first.");return y({backend:function(e){let{req:t,session:r}=e;return{platform:r.device.platform,captureSnapshot:async(a,i)=>({snapshot:await e.captureSnapshotForSession(r,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0})}),tap:async(a,i)=>oe(await Y(r.device,"press",[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),fill:async(a,i,n)=>oe(await Y(r.device,"fill",[String(i.x),String(i.y),n],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath))),typeText:async(a,i)=>oe(await Y(r.device,"type",[i],t.flags?.out,e.contextFromFlags(t.flags,r.appBundleId,r.trace?.outPath)))}}({...e,session:t}),artifacts:eU("interaction commands",{plural:!0}),sessions:{get:r=>r===e.sessionName?{name:e.sessionName,appBundleId:t.appBundleId,appName:t.appName,snapshot:t.snapshot,metadata:{surface:t.surface}}:void 0,set:r=>{r.snapshot&&(t.snapshot=r.snapshot,e.sessionStore.set(e.sessionName,t))}},policy:w()})}function oe(e){return e&&"object"==typeof e?e:void 0}function ot(e){return"ref"===e.kind?{ref:or(e.target?.kind==="ref"?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain}:"selector"===e.kind?{selector:e.target?.kind==="selector"?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel}:{}}function or(e){return e?.startsWith("@")?e.slice(1):e}async function oa(e){switch(e.req.command){case"press":case"click":return await oi(e);case"fill":return await on(e);default:return null}}async function oi(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r),n="click"===t.command?"click":"press";if(!i)return eq("SESSION_NOT_FOUND","No active session. Run open first.");let o=n6(i,n);if(o)return o;if(!ep("press",i.device))return eq("UNSUPPORTED_OPERATION","press is not supported on this device");let s=eM(t.flags),l=et(s);if("primary"!==s){let e=es({commandLabel:n,platform:i.device.platform,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap});if(e)return eq(e.code,e.message,e.details)}let d=function(e,t){let r=ej(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:eq("INVALID_ARGS",`${t} requires @ref, selector expression, or x y coordinates`)}}(t.positionals??[],n);if(!d.ok)return d.response;if("ref"===d.target.kind){let r=e.refSnapshotFlagGuardResponse("press",t.flags);if(r)return r}return await oo(e,{run:async e=>{let a={session:r,requestId:t.meta?.requestId,button:s,count:t.flags?.count,intervalMs:t.flags?.intervalMs,holdMs:t.flags?.holdMs,jitterPx:t.flags?.jitterPx,doubleTap:t.flags?.doubleTap};return"click"===n?await e.interactions.click(d.target,a):await e.interactions.press(d.target,a)},afterRun:async e=>{var t;await eg(i,(t=d.target,"point"===t.kind?"coordinate tap":"ref"===e.kind&&e.target?.kind==="ref"?e.target.ref:"selector"===e.kind&&e.target?.kind==="selector"?e.target.selector:"target"))},buildPayloads:async r=>{let n="point"===r.kind?await n5({session:i,flags:t.flags,sessionStore:a,contextFromFlags:e.contextFromFlags,captureSnapshotForSession:e.captureSnapshotForSession}):n9(i.snapshot?.nodes??[]),o=n3({data:r.backendResult,fallbackX:r.point.x,fallbackY:r.point.y,referenceFrame:n,extra:{...ot(r),...l}});return{result:o,responseData:o}}})}async function on(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(i){let e=n6(i,"fill");if(e)return e}if(i&&!ep("fill",i.device))return eq("UNSUPPORTED_OPERATION","fill is not supported on this device");if(!i)return eq("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:eq("INVALID_ARGS","fill requires text after ref")}}let r=ej(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:eq("INVALID_ARGS","fill requires text after coordinates")}}let a=te(e,{preferTrailingValue:!0});if(!a)return{ok:!1,response:eq("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:eq("INVALID_ARGS","fill requires text after selector")}}(t.positionals??[]);if(!n.ok)return n.response;if("ref"===n.target.kind){let r=e.refSnapshotFlagGuardResponse("fill",t.flags);if(r)return r}return await oo(e,{run:async e=>await e.interactions.fill(n.target,n.text,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),buildPayloads:e=>{let t="point"===e.kind?void 0:n9(i.snapshot?.nodes??[]),r=n3({data:e.backendResult,fallbackX:e.point.x,fallbackY:e.point.y,referenceFrame:t,extra:{...ot(e),text:n.text}});e.warning&&(r.warning=e.warning);let a="ref"===e.kind?{...e.backendResult??{ref:or(e.target?.kind==="ref"?e.target.ref:void 0),x:e.point.x,y:e.point.y}}:r;return e.warning&&(a.warning=e.warning),{result:r,responseData:a}}})}async function oo(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return eq("SESSION_NOT_FOUND","No active session. Run open first.");let a=n7(e),i=Date.now();try{let n=await t.run(a);await t.afterRun?.(n);let o=Date.now(),{result:s,responseData:l}=await t.buildPayloads(n);return n8({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags,result:s,responseData:l,actionStartedAt:i,actionFinishedAt:o})}catch(t){let e=C(t);if(eF(e))throw e;return{ok:!1,error:E(t)}}}async function os(e,t,r,a,i){let n={...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},o=a(n,e.appBundleId,e.trace?.outPath),{snapshot:s}=await em({device:e.device,session:e,flags:n,outPath:n.out,logPath:o.logPath??""});return e.snapshot=s,r.set(e.name,e),e.snapshot}let ol=/\bis(?:n't| not)\s+responding\b/i,od=/^close app$/i;async function ou(e){let{session:t}=e;if("android"!==t.device.platform||!t.recording)return"absent";try{let e=await oc(t),r=function(e){if(oh(e))return e.find(e=>{let t=om(e);return t.length>0&&od.test(t)&&e.rect})}(e);if(!r?.rect)return"absent";let{x:a,y:i}=tc(r.rect),n=await U("adb",q(t.device,["shell","input","tap",String(Math.round(a)),String(Math.round(i))]),{allowFailure:!0});if(0!==n.exitCode)return P({level:"warn",phase:"android_blocking_dialog_tap_failed",data:{session:t.name,deviceId:t.device.id,exitCode:n.exitCode,stdout:n.stdout.trim(),stderr:n.stderr.trim()}}),"failed";if(!await of(t))return P({level:"warn",phase:"android_blocking_dialog_still_present",data:{session:t.name,deviceId:t.device.id}}),"failed";if(t.appBundleId&&(await eP(t.device,t.appBundleId),!await op(t,t.appBundleId)))return P({level:"warn",phase:"android_blocking_dialog_relaunch_unfocused",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId}}),"failed";return P({level:"warn",phase:"android_blocking_dialog_recovered",data:{session:t.name,deviceId:t.device.id,appBundleId:t.appBundleId,x:a,y:i}}),"recovered"}catch(e){return P({level:"warn",phase:"android_blocking_dialog_recovery_failed",data:{session:t.name,deviceId:t.device.id,error:e instanceof Error?e.message:String(e)}}),"failed"}}async function oc(e){return tu(td((await ef(e.device,{interactiveOnly:!1,compact:!1})).nodes))}async function of(e){for(let t=0;t<12;t+=1){if(!oh(await oc(e)))return!0;await og(500)}return!oh(await oc(e))}async function op(e,t){for(let r=0;r<12;r+=1){if((await eS(e.device)).package===t)return!0;await og(500)}return(await eS(e.device)).package===t}function om(e){let t=[e.label,e.identifier];return"string"==typeof e.value&&e.value.trim().length>0&&t.push(e.value),t.filter(e=>"string"==typeof e&&e.trim().length>0).join(" ").trim()}function oh(e){return e.some(e=>{let t=om(e);return t.length>0&&ol.test(t)})}function og(e){return new Promise(t=>setTimeout(t,e))}async function ow(e){let t=await oa({...e,captureSnapshotForSession:os,refSnapshotFlagGuardResponse:ee});if(t)return t;switch(e.req.command){case"type":return await oy({...e,captureSnapshotForSession:os});case"get":return await ev(e);case"is":return await ek(e);default:return null}}async function oy(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);if(!i)return eq("SESSION_NOT_FOUND","No active session. Run open first.");if(!ep("type",i.device))return eq("UNSUPPORTED_OPERATION","type is not supported on this device");if("android"===i.device.platform&&i.recording&&"failed"===await ou({session:i}))return eq("COMMAND_FAILED","Android system dialog blocked the recording session");let n=(t.positionals??[]).join(" "),o=n7(e),s=Date.now();try{let e=await o.interactions.typeText(n,{session:r,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs}),l=Date.now(),d={...e.backendResult??{},text:e.text,delayMs:e.delayMs,...e7(e.message??`Typed ${Array.from(e.text).length} chars`)};return n8({session:i,sessionStore:a,command:t.command,positionals:t.positionals??[],flags:t.flags,result:d,responseData:d,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:E(e)}}}function ov(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function oI(e){let{req:t,leaseRegistry:r}=e,a=ov(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}function oS(e,t){if(!t)return[];let r=[],a=e.device,i=e2(t.platform);if(i&&!eY(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=j(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push({key:"androidDeviceAllowlist",value:t.androidDeviceAllowlist})}return r}function oA(e){return`${function(e){switch(e){case"iosSimulatorDeviceSet":return"--ios-simulator-device-set";case"androidDeviceAllowlist":return"--android-device-allowlist";default:return`--${e}`}}(e.key)}=${e.value}`}let ob=["target","device","udid","serial","iosSimulatorDeviceSet","androidDeviceAllowlist"];async function o_(e){let{session:t,sessionName:r,outPath:a,outputPlacement:i,dispatchContext:s}=e,l=y({backend:function(e){let{session:t,outputPlacement:r,dispatchContext:a}=e;return{platform:t.device.platform,captureScreenshot:async(e,i,n)=>{let o={...a,screenshotFullscreen:n?.fullscreen,overlayRefs:n?.overlayRefs,surface:n?.surface};return"out"===r?oN(await Y(t.device,"screenshot",[],i,o)):oN(await Y(t.device,"screenshot",[i],void 0,o))}}}({session:t,outputPlacement:i,dispatchContext:s}),artifacts:{resolveInput:async()=>{throw new T("UNSUPPORTED_OPERATION","screenshot does not resolve input artifacts")},reserveOutput:async e=>{let t,r;return e?.kind==="path"?r=e.path:(t=await n.mkdtemp(o.join(c.tmpdir(),"agent-device-screenshot-")),r=o.join(t,"screenshot.png")),await n.mkdir(o.dirname(r),{recursive:!0}),{path:r,visibility:"client-visible",publish:async()=>void 0,...t?{cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}:{}}},createTempFile:async e=>{let t=await n.mkdtemp(o.join(c.tmpdir(),`${e.prefix}-`));return{path:o.join(t,`file${e.ext}`),visibility:"internal",cleanup:async()=>{await n.rm(t,{recursive:!0,force:!0})}}}},sessions:{get:e=>e===r?{name:r,appBundleId:t.appBundleId,metadata:{surface:t.surface}}:void 0,set:()=>{}},policy:w()});return await l.capture.screenshot({session:r,requestId:s.requestId,appBundleId:t.appBundleId,fullscreen:s.screenshotFullscreen,surface:t.surface,...a?{out:{kind:"path",path:a}}:{}})}function oN(e){if("object"==typeof e&&null!==e)return{..."string"==typeof e.path?{path:e.path}:{},...Array.isArray(e.overlayRefs)?{overlayRefs:e.overlayRefs}:{}}}let ok=[255,59,48,255],oM=[255,214,10,255],ox=[0,0,0,255],oD={e:["01110","10000","11110","10000","10000","10001","01110"],0:["01110","10001","10011","10101","11001","10001","01110"],1:["00100","01100","00100","00100","00100","00100","01110"],2:["01110","10001","00001","00010","00100","01000","11111"],3:["11110","00001","00001","01110","00001","00001","11110"],4:["00010","00110","01010","10010","11111","00010","00010"],5:["11111","10000","10000","11110","00001","00001","11110"],6:["01110","10000","10000","11110","10001","10001","01110"],7:["11111","00001","00010","00100","01000","01000","01000"],8:["01110","10001","10001","01110","10001","10001","01110"],9:["01110","10001","10001","01111","00001","00001","01110"]};async function oP(e){let t=e6(await n.readFile(e.screenshotPath),"screenshot"),r=function(e,t,r,a={}){let i=function(e){let t=null;for(let r of e)oR(r)&&o$(r.rect)&&(!t||oU(r.rect)>oU(t))&&(t=r.rect);return t||function(e){let t=1/0,r=1/0,a=-1/0,i=-1/0;for(let n of e)n.rect&&o$(n.rect)&&(t=Math.min(t,n.rect.x),r=Math.min(r,n.rect.y),a=Math.max(a,n.rect.x+n.rect.width),i=Math.max(i,n.rect.y+n.rect.height));return!Number.isFinite(t)||!Number.isFinite(r)||a<=t||i<=r?null:{x:t,y:r,width:a-t,height:i-r}}(e.filter(e=>{var t;return o$(e.rect)&&!("image"===tl((t=e).type??"")&&!oO(t.label))}))}(e.nodes),n=new Map;for(let a of e.nodes){if(!function(e){let t=[e.label,e.value].some(oC)||oE(e.identifier);return oL(e)?t:t&&function(e){let t=tl(e.type??"");return t.includes("statictext")||t.includes("image")||t.includes("text")||t.includes("other")}(e)}(a))continue;let o=function(e,t){if(function(e){return oL(e)&&!oR(e)}(t)&&o$(t.rect))return t;let r=function(e,t){let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){;a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(oL(t)&&!oR(t)&&o$(t.rect))return t;r=t}return null}(e,t);if(r?.rect&&o$(r.rect))return r;if(t.hittable&&o$(t.rect)&&!oR(t))return t;let a=tt(e,t);return a?.rect&&o$(a.rect)&&!oR(a)?a:null}(e.nodes,a);if(!o?.rect||!o$(o.rect))continue;let s=function(e,t,r){let a=oT(e);if(e.ref!==t.ref&&a)return a;let i=function(e,t){let r=null;for(let a of t){if(a.ref===e.ref||!function(e,t,r){let a=e;for(;void 0!==a.parentIndex;){let e=r[a.parentIndex];if(!e)break;if(e.ref===t.ref)return!0;a=e}return!1}(a,e,t))continue;let i=oT(a);if(!i)continue;let n=function(e){let t=0;return tl(e.type??"").includes("text")&&(t+=2),oC(e.label)&&(t+=2),oC(e.value)&&(t+=1),t}(a);(!r||n>r.score)&&(r={label:i,score:n})}return r?.label}(t,r);return i||(oT(t)??to(t,r))}(a,o,e.nodes),l=function(e,t,r){let a=0;return e.ref===t.ref&&(a+=4),t.hittable&&(a+=3),oL(t)&&(a+=3),oL(e)&&(a+=2),r&&(a+=2),oE(t.identifier)&&(a+=1),oO(t.value)&&(a+=1),a}(a,o,s),d=function(e,t,r,a){if(!e)return oV({x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},r,a);let i=r/e.width,n=a/e.height;return oV({x:Math.round((t.x-e.x)*i),y:Math.round((t.y-e.y)*n),width:Math.max(1,Math.round(t.width*i)),height:Math.max(1,Math.round(t.height*n))},r,a)}(i,o.rect,t,r);if(!o$(d))continue;let u=n.get(o.ref);(!u||l>u.score)&&n.set(o.ref,{ref:o.ref,label:s,rect:o.rect,overlayRect:d,score:l})}return(function(e){let t=[];for(let r of e.sort((e,t)=>oU(e.overlayRect)-oU(t.overlayRect))){let e=t.findIndex(e=>e.label===r.label&&(oF(e.overlayRect,r.overlayRect)||oF(r.overlayRect,e.overlayRect)));if(-1===e){t.push(r);continue}oU(r.overlayRect)<oU(t[e].overlayRect)&&(t[e]=r)}return t})([...n.values()]).sort((e,t)=>{if(t.score!==e.score)return t.score-e.score;let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:oG(e.ref,t.ref)}).slice(0,a.maxRefs??24).sort((e,t)=>{let r=e.overlayRect.y-t.overlayRect.y;if(0!==r)return r;let a=e.overlayRect.x-t.overlayRect.x;return 0!==a?a:oG(e.ref,t.ref)}).map(e=>({ref:e.ref,label:e.label,rect:e.rect,overlayRect:e.overlayRect,center:tc(e.overlayRect)}))}(e.snapshot,t.width,t.height,{maxRefs:e.maxRefs});for(let e of r){var a,i;(function(e,t,r){for(let a=0;a<2;a+=1)oq(e,t.x,t.x+t.width-1,t.y+a,r),oq(e,t.x,t.x+t.width-1,t.y+t.height-1-a,r),oH(e,t.x+a,t.y,t.y+t.height-1,r),oH(e,t.x+t.width-1-a,t.y,t.y+t.height-1,r)})(a=t,(i=e).overlayRect,ok),function(e,t,r){let a=6+5*r.length+ +Math.max(0,r.length-1),i=oj(t.x,0,Math.max(0,e.width-a)),n=t.y-11-2,o=n>=0?n:oj(t.y+2,0,Math.max(0,e.height-11));(function(e,t,r,a,i){for(let n=0;n<11;n+=1)for(let o=0;o<a;o+=1)oB(e,t+o,r+n,i)})(e,i,o,a,oM),function(e,t,r,a,i){let n=t;for(let t of a.toLowerCase()){let a=oD[t];if(a)for(let t=0;t<a.length;t+=1)for(let o=0;o<a[t].length;o+=1)"1"===a[t][o]&&oB(e,n+o,r+t,i);n+=6}}(e,i+3,o+2,r,ox)}(a,i.overlayRect,i.ref)}return await n.writeFile(e.screenshotPath,m.sync.write(t)),r}function oL(e){let t=[e.type,e.role,e.subrole].map(e=>tl(e??"")).join(" ");return t.includes("button")||t.includes("link")||t.includes("menu")||t.includes("tab")||t.includes("textfield")||t.includes("searchfield")||t.includes("securetextfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("cell")}function oR(e){let t=[e.type,e.role,e.subrole].map(e=>tl(e??"")).join(" ");return t.includes("application")||t.includes("window")}function oO(e){if("string"!=typeof e)return!1;let t=e.trim();return!(!t||/^(true|false)$/i.test(t))}function oC(e){var t;let r;return!!oO(e)&&(t=e,"toolbar"!==(r=t?.trim().toLowerCase())&&"window"!==r&&"application"!==r&&r?.startsWith("vertical scroll bar")!==!0)}function oE(e){var t;return"string"==typeof e&&!!oC(e)&&(t=e,!/^[a-z0-9_.]+:id\/[a-z0-9_.-]+$/i.test(t.trim()))}function oT(e){let t=[e.label,e.value].find(oC);return t?t.trim():oE(e.identifier)?e.identifier.trim():void 0}function o$(e){return!!(e&&e.width>0&&e.height>0)}function oU(e){return e.width*e.height}function oF(e,t){return t.x>=e.x&&t.y>=e.y&&t.x+t.width<=e.x+e.width&&t.y+t.height<=e.y+e.height}function oG(e,t){return Number.parseInt(e.replace(/^\D+/,""),10)-Number.parseInt(t.replace(/^\D+/,""),10)}function oV(e,t,r){let a=oj(e.x,0,Math.max(0,t-1)),i=oj(e.y,0,Math.max(0,r-1)),n=Math.max(1,t-a),o=Math.max(1,r-i);return{x:a,y:i,width:oj(e.width,1,n),height:oj(e.height,1,o)}}function oj(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function oq(e,t,r,a,i){for(let n=t;n<=r;n+=1)oB(e,n,a,i)}function oH(e,t,r,a,i){for(let n=r;n<=a;n+=1)oB(e,t,n,i)}function oB(e,t,r,a){if(t<0||r<0||t>=e.width||r>=e.height)return;let i=(e.width*r+t)*4;e.data[i]=a[0],e.data[i+1]=a[1],e.data[i+2]=a[2],e.data[i+3]=a[3]}let oK=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),oz=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]),oW=new Set(oz),oJ=new Map;function oZ(e,t,r,a){let i=k().requestId;return{...eL(e,t,r,a,i),requestId:i}}async function oX(e,t,r){let a=r.get(t);if(a)return`device:${a.device.id}`;if("open"===e.command||r5(e.flags))try{let t=await eh(e.flags??{});return`device:${t.id}`}catch{}return`session:${t}`}async function oY(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,leaseRegistry:n,invoke:o,contextFromFlags:s}=e,l=await oI({req:t,leaseRegistry:n});if(l)return l;let d=await i3({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(d)return d;let u=await er({req:t,sessionName:r,logPath:a,sessionStore:i});if(u)return u;let c=await nj({req:t,sessionName:r,sessionStore:i,logPath:a});if(c)return c;let f=await i8({req:t,sessionName:r,logPath:a,sessionStore:i,invoke:o});if(f)return f;let p=await ow({req:t,sessionName:r,logPath:a,sessionStore:i,contextFromFlags:s});return p||null}async function oQ(e){var t,r;let a,i,n,o,s,l,d,{req:u,session:c,logPath:f,sessionStore:p}=e,m=u.command;if(!ep(m,c.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${m} is not supported on this device`}};if("android"===c.device.platform&&c.recording&&"record"!==m&&"failed"===await ou({session:c}))return{ok:!1,error:{code:"COMMAND_FAILED",message:"Android system dialog blocked the recording session"}};let{resolvedPositionals:h,resolvedOut:g,recordedPositionals:w,recordedFlags:y}=(a=(t=u).command,i=t.positionals??[],n=t.flags?.out,o="screenshot"===a&&i[0]?[tE.expandHome(i[0],t.meta?.cwd),...i.slice(1)]:i,s="screenshot"===a&&n?tE.expandHome(n,t.meta?.cwd):n,l="screenshot"===a?o:i,d="screenshot"===a&&s?{...t.flags??{},out:s}:t.flags??{},{resolvedPositionals:o,resolvedOut:s,recordedPositionals:l,recordedFlags:d}),v=Date.now(),I={...oZ(f,u.flags,c.appBundleId,c.trace?.outPath),surface:c.surface},S="screenshot"===m?await o_({session:c,sessionName:e.sessionName,outPath:h[0]??g,outputPlacement:"screenshot"!==(r=u).command?"default":(r.positionals??[])[0]?"positional":r.flags?.out?"out":"default",dispatchContext:I}):await Y(c.device,m,h,g,{...I});return"screenshot"===m&&u.flags?.overlayRefs&&"string"==typeof S?.path&&await o0(c,S,f),function(e){let{session:t,sessionStore:r,command:a,resolvedPositionals:i,recordedPositionals:n,recordedFlags:o,data:s,actionStartedAt:l,actionFinishedAt:d,flags:u}=e,c=function(e,t,r,a){if("scroll"!==t)return a;let i=nB(e.snapshot),n={...a??{}},o=nX(n.direction)??nX(r[0]);if(!o)return a;let s=nY(n.amount)??nY(r[1]),l=nY(n.pixels),d=n1(n,[]),u=nY(n.referenceWidth),c=nY(n.referenceHeight),f=void 0!==u&&u>0&&void 0!==c&&c>0?{referenceWidth:u,referenceHeight:c}:i??nz;if(d&&(d.x1!==d.x2||d.y1!==d.y2))return{...n,x1:d.x1,y1:d.y1,x2:d.x2,y2:d.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==l?{pixels:l}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250};let p=e4({direction:o,amount:s,pixels:l,referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight});return{...n,x1:p.x1,y1:p.y1,x2:p.x2,y2:p.y2,contentDirection:o,...void 0!==s?{amount:s}:{},...void 0!==p.pixels?{pixels:p.pixels}:{},referenceWidth:f.referenceWidth,referenceHeight:f.referenceHeight,durationMs:250}}(t,a,i,s);nW(t,a,i,c,u,l,d),r.recordAction(t,{command:a,positionals:n,flags:o,result:s??{}})}({session:c,sessionStore:p,command:m,resolvedPositionals:h,recordedPositionals:w,recordedFlags:y,data:S,actionStartedAt:v,actionFinishedAt:Date.now(),flags:u.flags??{}}),eu(m)&&e8(c,m),{ok:!0,data:S??{}}}async function o0(e,t,r){let a=eD(await eR({device:e.device,session:e,flags:void 0,logPath:r,snapshotScope:void 0}),void 0);e.snapshot=a;let i=await oP({screenshotPath:t.path,snapshot:a});t.overlayRefs=i}function o1(e){i.existsSync(e)&&i.unlinkSync(e)}function o2(e){if(!i.existsSync(e))return null;try{let t=JSON.parse(i.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function o3(e){let t=o2(e);if(!t||t.pid===process.pid)try{i.existsSync(e)&&i.unlinkSync(e)}catch{}}function o8(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:o4,infoPath:o5,lockPath:o9,logPath:o6,sessionsDir:o7}=_(process.env.AGENT_DEVICE_STATE_DIR),se=M(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var st=o7;if(i.existsSync(st))for(let e of i.readdirSync(st,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=o.join(st,e.name,t$);if(i.existsSync(t))try{let e=tU(i.readFileSync(t,"utf8"));if(e&&function(e){let t,r=L(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=O(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{tG(t)}}let sr=new tE(o7),sa=new rK({maxActiveSimulatorLeases:o8(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:o8(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),si=v(),sn=a.randomBytes(24).toString("hex"),so=L(process.pid)??void 0,ss=I(),sl=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:i,trackDownloadableArtifact:n}=e;async function s(e){let l=!!(e.meta?.debug||e.flags?.verbose);return await b({session:e.session,requestId:e.meta?.requestId,command:e.command,debug:l,logPath:t},async()=>{if(e.token!==r)return{ok:!1,error:E(new T("UNAUTHORIZED","Invalid token"))};try{let r=function(e){let t=A(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=S(r);if(r&&!a)throw new T("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new T("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");let i=e.session||"default";return i.startsWith(`${a}:`)?{...e,meta:{...e.meta,tenantId:a,sessionIsolation:t}}:{...e,session:`${a}:${i}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(e);P({level:"info",phase:"request_start",data:{session:r.session,command:r.command,tenant:r.meta?.tenantId,isolation:r.meta?.sessionIsolation}});let l=r.command,d=ov(r);oz.has(l)||r.meta?.sessionIsolation!=="tenant"||i.assertLeaseAdmission({tenantId:d.tenantId,runId:d.runId,leaseId:d.leaseId,backend:d.leaseBackend});let u=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(r,a),c=oW.has(l)?null:await oX(r,u,a),f=async()=>{let e=a.get(u);e&&(!function(e){let t=e.recording;if(!t||"ios"!==e.device.platform)return;let r=e$(e.device.id);if(!t.runnerSessionId){r?.alive&&(t.runnerSessionId=r.sessionId);return}if(!r?.alive){t.invalidatedReason??="iOS runner session exited during recording";return}r.sessionId!==t.runnerSessionId&&(t.invalidatedReason??="iOS runner session restarted during recording")}(e),a.set(u,e));let d=function(e,t){let r=e.meta?.lockPolicy;if(!r)return e;let a={...e.flags??{}},i=t?oS(t,a):function(e,t,r){var a,i;let n=[],o=e2(t);if(void 0!==e.platform&&o&&(a=e2(e.platform),i=o,a&&i&&a!==i&&("apple"===a?!ea(i):"apple"!==i||!ea(a)))&&n.push({key:"platform",value:e.platform}),"open"===r)return n;for(let t of ob){let r=e[t];"string"==typeof r&&r.trim().length>0&&n.push({key:t,value:r})}return n}(a,e.meta?.lockPlatform,e.command);if(0===i.length)return!t&&e.meta?.lockPlatform&&void 0===a.platform&&(a.platform=e.meta.lockPlatform),{...e,flags:a};if("strip"===r)return t?(function(e,t){for(let r of t)delete e[r.key]}(a,i),a.platform=t.device.platform):function(e,t){for(let t of ob)delete e[t];t&&(e.platform=t)}(a,e.meta?.lockPlatform),{...e,flags:a};throw new T("INVALID_ARGS",`${e.command} cannot override session lock policy with ${i.map(oA).join(", ")}. Unset those selectors or remove the request lock policy.`)}(r,e),c=e=>(function(e,t,r){let a=k();if(!t.ok){P({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=N({force:!0})??void 0;return{ok:!1,error:E(new T(t.error.code,t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return P({level:"info",phase:"request_success"}),N(),{ok:!0,data:function(e,t,r){var a,i;let n;if(!t)return t;let s=(a=e,i=t,n=Array.isArray(i.artifacts)?[...i.artifacts]:[],"screenshot"!==a.command||n.some(e=>e?.field==="path")||"string"!=typeof i.path||n.push({field:"path",path:i.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:o.basename(a.meta?.clientArtifactPaths?.path??i.path)}),n.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(d,e,n);if(e?.recording?.invalidatedReason&&"record"!==l&&"close"!==l)return c({ok:!1,error:{code:"COMMAND_FAILED",message:e.recording.invalidatedReason}});!e||d.meta?.lockPolicy||oK.has(l)||function(e,t){let r=oS(e,t);if(0!==r.length){var a;let t,i,n;throw new T("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.map(oA).join(", ")}. Use a different --session name or close this session first.`)}}(e,d.flags);let f=await oY({req:d,sessionName:u,logPath:t,sessionStore:a,leaseRegistry:i,invoke:s,contextFromFlags:(e,r,i)=>({...oZ(t,e,r,i),surface:a.get(u)?.surface})});if(f)return c(f);let p=a.get(u);if(!p)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});let m=await oQ({req:d,session:p,sessionName:u,logPath:t,sessionStore:a});return c(m)};if(!c)return await f();return await ey(oJ,c,f)}catch(r){P({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=k(),t=N({force:!0})??void 0;return{ok:!1,error:E(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return s}({logPath:o6,token:sn,sessionStore:sr,leaseRegistry:sa,trackDownloadableArtifact:function(e){let t=a.randomUUID(),r=setTimeout(()=>{rg(t)},9e5);return r.unref(),rh.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){i.existsSync(e)||i.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),n=()=>{try{return i.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let o=o2(t);if(o?.pid&&o.pid!==process.pid&&R(o.pid,o.processStartTime))return!1;try{i.unlinkSync(t)}catch{}return n()}(o4,o9,{pid:process.pid,version:si,startedAt:Date.now(),processStartTime:so})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let n;if("socket"===se||"dual"===se){let t=h.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))eG(e);P({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{try{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await eT(),!(r<=0));)await new Promise(e=>setTimeout(e,200))}catch(e){P({level:"error",phase:"request_client_disconnect_abort_failed",data:{message:e instanceof Error?e.message:String(e),inFlightRequests:r}})}})()}};e.setEncoding("utf8"),e.on("close",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=eC(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),ed(o),eO(o))throw el();i=await sl(e)}catch(e){i={ok:!1,error:E(e)}}finally{r-=1,o&&(a.delete(o),ez(o))}e.destroyed||e.write(`${JSON.stringify(i)}
|
|
35
|
+
`),n=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new T("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===se||"dual"===se){let e=await rF({handleRequest:sl,token:sn});r.push(e),t=await new Promise((t,r)=>{e.once("error",r),e.listen(0,"127.0.0.1",()=>{e.off("error",r);let a=e.address();"object"==typeof a&&a?.port?t(a.port):r(new T("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:sn,version:si,codeSignature:ss,processStartTime:so},i.existsSync(o4)||i.mkdirSync(o4,{recursive:!0}),i.writeFileSync(o6,""),n=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",i.writeFileSync(o5,JSON.stringify({port:a.socketPort,httpPort:a.httpPort,transport:n,token:a.token,pid:process.pid,version:a.version,codeSignature:a.codeSignature,processStartTime:a.processStartTime,stateDir:o4},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
|
|
36
36
|
`),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${t}
|
|
37
|
-
`)}catch(t){let e=
|
|
38
|
-
`),r))try{t.close(()=>{})}catch{}
|
|
39
|
-
`),s()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof
|
|
37
|
+
`)}catch(t){let e=C(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
|
|
38
|
+
`),r))try{t.close(()=>{})}catch{}o1(o5),o3(o9),process.exit(1);return}let n=!1,o=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},s=async()=>{if(!n){for(let e of(n=!0,await o(),sr.toArray()))sr.writeSessionLog(e);await ew(),o1(o5),o3(o9),process.exit(0)}};process.on("SIGINT",()=>{s()}),process.on("SIGTERM",()=>{s()}),process.on("SIGHUP",()=>{s()}),process.on("uncaughtException",e=>{let t=e instanceof T?e:C(e);process.stderr.write(`Daemon error: ${t.message}
|
|
39
|
+
`),s()}),process.on("unhandledRejection",e=>{let t=e instanceof Error?e:Error(String(e)),r=t instanceof T?t:C(t);process.stderr.write(`Daemon error: ${r.message}
|
|
40
40
|
`),s()})}();
|