agent-device 0.16.10 → 0.16.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.10.apk → agent-device-android-multitouch-helper-0.16.11.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.11.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.10.manifest.json → agent-device-android-multitouch-helper-0.16.11.manifest.json} +4 -4
  4. package/android-snapshot-helper/README.md +6 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.11.apk +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.11.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.10.manifest.json → agent-device-android-snapshot-helper-0.16.11.manifest.json} +6 -6
  8. package/dist/src/1352.js +1 -1
  9. package/dist/src/221.js +6 -6
  10. package/dist/src/2415.js +27 -27
  11. package/dist/src/2805.js +1 -1
  12. package/dist/src/4778.js +1 -0
  13. package/dist/src/5792.js +1 -1
  14. package/dist/src/6085.js +1 -1
  15. package/dist/src/6232.js +1 -1
  16. package/dist/src/8699.js +1 -1
  17. package/dist/src/9238.js +4 -0
  18. package/dist/src/9533.js +1 -1
  19. package/dist/src/9542.js +3 -3
  20. package/dist/src/apple.js +1 -1
  21. package/dist/src/args.js +54 -25
  22. package/dist/src/batch.d.ts +1 -0
  23. package/dist/src/cli.js +19 -19
  24. package/dist/src/command-metadata.js +1 -1
  25. package/dist/src/command-surface.js +1 -1
  26. package/dist/src/contracts.d.ts +1 -0
  27. package/dist/src/contracts.js +1 -1
  28. package/dist/src/generic.js +10 -10
  29. package/dist/src/index.d.ts +9 -0
  30. package/dist/src/record-trace.js +3 -3
  31. package/dist/src/session.js +9 -9
  32. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +7 -0
  33. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +109 -0
  34. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +123 -32
  35. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -0
  36. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +11 -1
  37. package/package.json +1 -1
  38. package/server.json +2 -2
  39. package/skills/dogfood/SKILL.md +1 -1
  40. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.10.apk.sha256 +0 -1
  41. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.10.apk +0 -0
  42. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.10.apk.sha256 +0 -1
  43. package/dist/src/2842.js +0 -1
  44. package/dist/src/8114.js +0 -4
@@ -1,6 +1,6 @@
1
- import{__webpack_require__ as e}from"./rslib-runtime.js";import t,{promises as r}from"node:fs";import n from"node:os";import a from"node:path";import{fileURLToPath as i}from"node:url";import{parseAllDocuments as o}from"yaml";import s from"node:vm";import{setTimeout as l}from"node:timers/promises";import{asAppError as u,normalizeError as c,AppError as d}from"./9152.js";import{runXcrun as p,resolveAppleSimulatorSetPathForSelector as f,dispatchCommand as m,appendAppLogMarker as h,selectorTargetsSessionDevice as w,resolveCommandDevice as g,hasExplicitSessionFlag as y,hasRuntimeTransportHints as v,inferFillText as A,formatPortableActionLine as b,stopIosRunnerSession as S,requireSessionOrExplicitSelector as I,isTouchTargetCommand as _,cleanupUploadedArtifact as N,isClickLikeCommand as M,refreshSessionDeviceIfNeeded as x,createRequestCanceledError as D,resolveIosDevicectlHint as k,registerRequestAbort as O,errorResponse as R,IOS_SIMULATOR_POST_OPEN_SETTLE_MS as L,parseReplayOpenFlags as P,IOS_SIMULATOR_POST_CLOSE_SETTLE_MS as $,settleIosSimulator as F,uniqueStrings as C,applyRuntimeHintsToApp as E,withKeyedLock as V,resolveTargetDevice as U,getAppLogPathMetadata as T,parseReplayRuntimeFlags as G,setSessionSnapshot as j,getSnapshotReferenceFrame as q,clearRuntimeHintsFromApp as K,handleCloseCommand as B,clearAppLogFiles as H,readSessionNetworkCapture as W,cleanupRetainedMaterializedPaths as z,IOS_DEVICECTL_DEFAULT_HINT as J,buildSnapshotState as X,context_contextFromFlags as Y,listDeviceInventory as Z,SessionStore as Q,formatScriptStringLiteral as ee,formatScriptActionSummary as et,isRequestCanceled as er,resolveRequestTrackingId as en,retainMaterializedPaths as ea,runAppLogDoctor as ei,resolvePayloadInput as eo,prepareUploadedArtifact as es,stopAppLog as el,markRequestCanceled as eu,ensureDeviceReady as ec,prewarmIosRunnerSession as ed,clearRequestCanceled as ep,resolveAndroidEmulatorAvdName as ef,buildSimctlArgsForDevice as em,parseReplaySeriesFlags as eh,parseXmlDocumentSync as ew,resolveFrontmostMacOsApp as eg,runAppleToolCommand as ey,listIosDeviceApps as ev,isCommandSupportedOnDevice as eA,isApplePlatform as eb,listIosDeviceProcesses as eS,normalizePlatformSelector as eI,getRequestSignal as e_,startAppLog as eN,markAndroidSnapshotFreshness as eM,emitRequestProgress as ex}from"./2415.js";import{withSuccessText as eD,successText as ek}from"./1998.js";import{resolveDeployResultTarget as eO,resolveInstallFromSourceResultTarget as eR}from"./6232.js";import{parseSessionSurface as eL,MAESTRO_COMPAT_TRACKER_URL as eP,MAESTRO_NEW_ISSUE_URL as e$}from"./1352.js";import{resolveAndroidAdbExecutor as eF}from"./9639.js";import{splitNonEmptyTrimmedLines as eC}from"./7455.js";import{resolveIosSimulatorDeviceSetPath as eE,classifyAndroidAppTarget as eV,resolveIosDeviceDeepLinkBundleId as eU,isInfrastructureBootFailureReason as eT,isWebUrl as eG,resolveAndroidSerialAllowlist as ej,isDeepLinkTarget as eq,formatAndroidInstalledPackageRequiredMessage as eK,listAndroidApps as eB}from"./8806.js";import{runBatch as eH,mergeParentFlags as eW}from"./1231.js";import{assertResolvedAppsFilter as ez}from"./1393.js";import{listIosApps as eJ,readInfoPlistString as eX}from"./apps.js";import{readScreenshotScriptFlag as eY}from"./5310.js";import{runCmdSync as eZ}from"./9818.js";import{emitDiagnostic as eQ}from"./7599.js";import{splitSelectorFromArgs as e0,extractNodeText as e1,findSnapshotAncestor as e2,isDescendantOfSnapshotNode as e3,splitIsSelectorArgs as e5,tryParseSelectorChain as e6,parseSelectorChain as e8,resolveSelectorChain as e9,buildSelectorChainForNode as e4,buildSnapshotNodeByIndex as e7,matchesSelector as te,normalizeType as tt}from"./940.js";import{normalizeText as tr}from"./7556.js";import{pointFromPercent as tn,buildSwipeGesturePlan as ta,clampToRange as ti,interiorCoordinate as to,evaluateIsPredicate as ts,pointInsideRect as tl,readReactNativeOverlayActionNodes as tu,detectReactNativeOverlay as tc,clampGesturePoint as td}from"./9533.js";import{sleep as tp}from"./4829.js";import{INTERNAL_COMMANDS as tf,DAEMON_COMMAND_GROUPS as tm,PUBLIC_COMMANDS as th}from"./5792.js";import{trimRuntimeValue as tw}from"./8656.js";var tg={};async function ty(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 d("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await ec(e.session.device),e.session.device}if(!r)throw new d("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let n=await U(e.flags??{});return await ec(n),n}async function tv(e){let{prepared:t,retention:r,req:n,session:a,sessionName:i}=e;if(r.enabled)return await ea({archivePath:t.archivePath,installablePath:t.installablePath,tenantId:n.meta?.tenantId,sessionName:a?i:void 0,ttlMs:r.ttlMs})}function tA(e){return e?{...e.archivePath?{archivePath:e.archivePath}:{},installablePath:e.installablePath,materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}}async function tb(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);try{let e,i,o=(e=function(e){let t=e.meta?.installSource;if(!t)throw new d("INVALID_ARGS","install_from_source requires a source payload");switch(t.kind){case"url":if(!t.url||0===t.url.trim().length)throw new d("INVALID_ARGS","install_from_source url source requires a non-empty url");return t;case"path":if(!t.path||0===t.path.trim().length)throw new d("INVALID_ARGS","install_from_source path source requires a non-empty path");return t;case"github-actions-artifact":throw new d("UNSUPPORTED_OPERATION","install_from_source github-actions-artifact sources require a compatible remote daemon");default:throw new d("UNSUPPORTED_OPERATION",`install_from_source ${String(t.kind)} sources require a compatible remote daemon`)}}(t),(i=t.meta?.uploadedArtifactId)&&"path"===e.kind?{source:{kind:"path",path:es(i,t.meta?.tenantId)},cleanup:()=>{N(i)}}:{source:e,cleanup:()=>{}}),s=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new d("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),l=await ty({session:a,flags:t.flags});if(!eA("install",l))return R("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=e_(t.meta?.requestId),c=async(e,i)=>{let l;try{var u;l=await tv({prepared:e,retention:s,req:t,session:a,sessionName:r});let o=await i(l),c=eD(o,(u=o,`Installed: ${eR(u)}`));return!function(e){let{session:t,sessionStore:r,req:n,data:a}=e;t&&r.recordAction(t,{command:"install_source",positionals:[],flags:n.flags??{},result:a})}({session:a,sessionStore:n,req:t,data:c}),{ok:!0,data:c}}catch(e){throw l&&await z(l.materializationId,t.meta?.tenantId).catch(()=>{}),e}finally{await e.cleanup(),o.cleanup()}};if("ios"===l.platform){let{installIosInstallablePath:e}=await import("./apps.js"),{prepareIosInstallArtifact:t}=await import("./apps.js"),r=await t(o.source,{signal:u});return await c(r,async t=>{if(await e(l,r.installablePath),!r.bundleId)throw new d("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");return{...tA(t),bundleId:r.bundleId,...r.appName?{appName:r.appName}:{},launchTarget:r.bundleId}})}let{prepareAndroidInstallArtifact:p}=await import("./8806.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./8806.js"),m=await p(o.source,{signal:u});return await c(m,async e=>{let t=await f(l,m.installablePath,m.packageName);if(!t)throw new d("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:r}=await import("./8806.js"),n=r(t);return{...tA(e),packageName:t,...n?{appName:n}:{},launchTarget:t}})}catch(e){return{ok:!1,error:c(e)}}}async function tS(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new d("INVALID_ARGS","release_materialized_paths requires a materializationId");return await z(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:c(e)}}}e.r(tg),e.d(tg,{SESSION_COMMAND_HANDLERS:()=>iB,handleSessionCommands:()=>iz});let tI=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function t_(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function tN(e,t){if(void 0!==e){if("string"!=typeof e)throw new d("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return tw(e)}}function tM(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new d("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function tx(e){if("ios"===e||"android"===e)return e}async function tD(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:n,session:a}=e;!t||!a?.appBundleId||!v(r)||v(n)||await K({device:a.device,appId:a.appBundleId})}async function tk(e){var t,r;let{req:n,sessionName:a,sessionStore:i}=e,o=(n.positionals?.[0]??"show").toLowerCase(),s=i.get(a),l=i.getRuntimeHints(a);if(!["set","show","clear"].includes(o))return R("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){v(l)&&s?.appBundleId&&await K({device:s.device,appId:s.appBundleId});let e=i.clearRuntimeHints(a);return{ok:!0,data:{session:a,cleared:e}}}if("show"===o)return{ok:!0,data:{session:a,configured:!!l,runtime:l}};let u=tx(eI(n.flags?.platform)??l?.platform??s?.device.platform);if(!u)return R("INVALID_ARGS","runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first.");if(s&&s.device.platform!==u)return R("INVALID_ARGS",`runtime set targets ${u}, but session "${a}" is already bound to ${s.device.platform}.`);let c={platform:(t=n.flags,r={platform:u,metroHost:tw(t?.metroHost),metroPort:tM(t?.metroPort),bundleUrl:tw(t?.bundleUrl),launchUrl:tw(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===t_(c)?R("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(i.setRuntimeHints(a,c),{ok:!0,data:{session:a,configured:!0,runtime:c}})}let tO="open-command-roundtrip",tR="Not implemented for this platform in this release.",tL=new Set(["app","desktop","frontmost-app"]);async function tP(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eg();return{appBundleId:t.bundleId,appName:t.appName}}function t$(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}function tF(e){return Math.round(10*e)/10}function tC(e){return Math.round(10*e)/10}let tE="adb-shell-dumpsys-gfxinfo-framestats";function tV(e,t,r){let n=t.get(r);if(void 0===n)return null;let a=Number(e[n]);return Number.isFinite(a)?a:null}function tU(e){return 0===e.length?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function tT(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function tG(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=e.match(RegExp(`^\\s*${r}:\\s*([0-9][0-9,]*)`,"im"));if(!n)return;let a=n[1];return void 0===a?void 0:t$(a)??void 0}async function tj(e,t,r={}){var n,a,i,o,s,l,u,c;let p=eF(e,r.adb);try{let u,c,f,m,h,w,g,y,v,A,b,S=(n=(await p(["shell","dumpsys","gfxinfo",t,"framestats"],{timeoutMs:15e3})).stdout,a=new Date().toISOString(),function(e,t){if(/no process found for:/i.test(e))throw new d("COMMAND_FAILED",`Android gfxinfo did not find a running process for ${t}`,{metric:"fps",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect."})}(n,t),f=function(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??"",r=tG(t,"Total frames rendered"),n=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(void 0===r||!n)return;let a=n[1],i=n[2];if(void 0===a||void 0===i)return;let o=t$(a)??void 0,s=Number(i);if(void 0===o||!Number.isFinite(s)||r<0)return;let l=tG(t,"Uptime"),u=tG(t,"Stats since");return{droppedFramePercent:tF(s),droppedFrameCount:o,totalFrameCount:r,sampleWindowMs:function(e){let{uptimeMs:t,statsSinceNs:r}=e;if(void 0===t||void 0===r)return;let n=t-Math.round(r/1e6);return n>=0?n:void 0}({uptimeMs:l,statsSinceNs:u}),uptimeMs:l,statsSinceNs:u}}(n),m=function(e){let t=[],r=null;for(let a of e.split("\n")){var n;let e=a.trim();if(0===e.length||"---PROFILEDATA---"===e)continue;let i=e.split(",").map(e=>e.trim());if((n=i).includes("IntendedVsync")&&n.includes("FrameCompleted")){r=new Map(i.map((e,t)=>[e,t]));continue}let o=function(e,t){if(!t||e.length<t.size)return;let r=tV(e,t,"Flags"),n=tV(e,t,"IntendedVsync"),a=tV(e,t,"FrameCompleted");if(0===r&&null!==n&&null!==a&&!(n<=0)&&!(a<=n))return{intendedVsyncNs:n,frameCompletedNs:a,durationNs:a-n}}(i,r);o&&t.push(o)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}(n),h=function(e,t,r){let n=function(e){var t;let r=(t=e.map(e=>e.intendedVsyncNs),[...new Set(t.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)),n=[];for(let e=1;e<r.length;e+=1){let t=r[e]-r[e-1];t>=4e6&&t<=5e7&&n.push(t)}if(0!==n.length){let e,t;return e=[...n].sort((e,t)=>e-t),t=Math.floor(e.length/2),e.length%2==1?e[t]:(e[t-1]+e[t])/2}}(e);if(t||0!==e.length||function(e){throw new d("COMMAND_FAILED",`Failed to parse Android framestats output for ${e}`,{metric:"fps",package:e,hint:"Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging."})}(r),t||void 0!==n)return n;throw new d("COMMAND_FAILED",`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:"fps",package:r,hint:"Retry perf after a longer interaction window so consecutive Android frame timestamps are available."})}(m,f,t),w=Date.parse(a),g=function(e){let{frames:t,measuredAtMs:r,summary:n}=e,a=tU(t),i=n?.statsSinceNs,o=i??a.firstFrameNs,s=tT(o,a.lastFrameNs),l=n?.sampleWindowMs??s;if(!Number.isFinite(r)||n?.uptimeMs===void 0||void 0===o)return{sampleWindowMs:l,windowStartNs:o};let u=r-n.uptimeMs;return{sampleWindowMs:l,windowStartNs:o,windowStartedAt:new Date(u+o/1e6).toISOString(),windowEndedAt:function(e){let{deviceBootWallClockMs:t,measuredAtMs:r,summaryStartNs:n,lastFrameNs:a}=e;return void 0!==n?new Date(r).toISOString():void 0===a?void 0:new Date(t+a/1e6).toISOString()}({deviceBootWallClockMs:u,measuredAtMs:r,summaryStartNs:i,lastFrameNs:a.lastFrameNs}),timestampSource:"estimated-from-device-uptime"}}({frames:m,measuredAtMs:w,summary:f}),y=function(e){let{frames:t,frameDeadlineNs:r,summaryDroppedFrameCount:n}=e;return void 0!==n?n<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,n).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs):void 0===r?[]:t.filter(e=>e.durationNs>r)}({frames:m,frameDeadlineNs:h,summaryDroppedFrameCount:f?.droppedFrameCount}),v=f?.sampleWindowMs??g.sampleWindowMs??function(e){if(0===e.length)return;let t=tU(e);return tT(t.firstFrameNs,t.lastFrameNs)}(m),i=f,o=m,s=y,u=i?.totalFrameCount??o.length,c=i?.droppedFrameCount??s.length,A={totalFrameCount:u,droppedFrameCount:c,droppedFramePercent:i?.droppedFramePercent??(u>0?tF(c/u*100):0)},b=function(e){let{droppedFrames:t,timing:r,measuredAtMs:n,summary:a}=e;if(0===t.length)return;let i=function(e){let{frames:t,windowStartNs:r,measuredAtMs:n,uptimeMs:a}=e;if(0===t.length||void 0===r)return[];let i=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}i.push(o),o=[e]}return o.length>0&&i.push(o),i.map(e=>(function(e){let{frames:t,windowStartNs:r,measuredAtMs:n,uptimeMs:a}=e,i=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((i-r)/1e6)),l=Math.max(s,Math.round((o-r)/1e6)),u=void 0!==a&&Number.isFinite(n)?n-a:void 0;return{startOffsetMs:s,endOffsetMs:l,startAt:void 0===u?void 0:new Date(u+i/1e6).toISOString(),endAt:void 0===u?void 0:new Date(u+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:tC(Math.max(...t.map(e=>e.durationNs))/1e6)}})({frames:e,windowStartNs:r,measuredAtMs:n,uptimeMs:a})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}({frames:t,windowStartNs:r.windowStartNs,measuredAtMs:n,uptimeMs:a?.uptimeMs});return i.length>0?i:void 0}({droppedFrames:y,timing:g,measuredAtMs:w,summary:f}),{...A,sampleWindowMs:v,...(l=h,{frameDeadlineMs:void 0===l?void 0:tC(l/1e6),refreshRateHz:void 0===l?void 0:tC(1e9/l)}),windowStartedAt:g.windowStartedAt,windowEndedAt:g.windowEndedAt,timestampSource:g.timestampSource,measuredAt:a,method:tE,source:f?"android-gfxinfo-summary":"framestats-rows",worstWindows:b&&b.length>0?b:void 0});return await tq(e,t,r),S}catch(e){throw u=t,(c=e)instanceof d?new d(c.code,c.message,{...c.details??{},metric:"fps",package:u},c):new d("COMMAND_FAILED",`Failed to sample Android fps for ${u}`,{metric:"fps",package:u},c)}}async function tq(e,t,r={}){let n=eF(e,r.adb);try{await n(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let tK="adb-shell-dumpsys-cpuinfo",tB="adb-shell-dumpsys-meminfo";async function tH(e,t,r={}){let n=eF(e,r.adb);try{let e=await n(["shell","dumpsys","cpuinfo"],{timeoutMs:15e3});return function(e,t,r){let n=new Set,a=0;for(let r of eC(e)){var i,o;let e=r.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!e)continue;let s=e[1],l=e[2];if(void 0===s||void 0===l)continue;let u=Number(s);Number.isFinite(u)&&(i=l,o=t,i===o||i.startsWith(`${o}:`))&&(a+=u,n.add(l))}return{usagePercent:tF(a),measuredAt:r,method:tK,matchedProcesses:[...n]}}(e.stdout,t,new Date().toISOString())}catch(e){throw tz("cpu",t,e)}}async function tW(e,t,r={}){let n=eF(e,r.adb);try{let e=await n(["shell","dumpsys","meminfo",t],{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new d("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let n=tJ(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!==t$(e));if(!r)break;return t$(r)??void 0}}(e);if(void 0===n)throw new d("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:n,totalRssKb:tJ(e,"TOTAL RSS"),measuredAt:r,method:tB}}(e.stdout,t,new Date().toISOString())}catch(e){throw tz("memory",t,e)}}function tz(e,t,r){return r instanceof d?new d(r.code,r.message,{...r.details??{},metric:e,package:t},r):new d("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function tJ(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(!n)return;let a=n[1];return void 0===a?void 0:t$(a)??void 0}async function tX(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return eq(t)?"macos"===e.platform?void 0:"device"===e.kind?eU(r,t):eG(t)?void 0:r??await tY(e,t):await tZ(e,t)}async function tY(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function tZ(e,t){try{let{resolveIosApp:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function tQ(e,t){if(!("android"!==e.platform||!t||eq(t)))try{let{resolveAndroidApp:r}=await import("./8806.js"),n=await r(e,t);return"package"===n.type?n.value:void 0}catch{return}}async function t0(e,t,r){if(r||"android"!==e.platform||!t||!eq(t))return r;try{let{getAndroidAppState:t}=await import("./8806.js"),n=await t(e);return n.package?.trim()||r}catch{return r}}async function t1(e,t,r,n){return await tX(e,t,r)??await n(e,t)??("android"===e.platform&&t&&eq(t)?r:void 0)}function t2(e){return R("INVALID_ARGS",e)}function t3(e,t,r,n){try{return function(e){let{device:t,surfaceFlag:r,openTarget:n,existingSurface:a}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return a??"app";if("linux"===t.platform){if(!r)return"app";let e=eL(r);if(!tL.has(e))throw new d("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&n)throw new d("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new d("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let i=r?eL(r):"app";if("app"!==i&&"menubar"!==i&&n)throw new d("INVALID_ARGS",`open --surface ${i} does not accept an app target`);return i}({device:e,surfaceFlag:t,openTarget:r,existingSurface:n})}catch(e){return R(e instanceof d?e.code:"INVALID_ARGS",String(e.message))}}function t5(e){let{shouldRelaunch:t,openTarget:r,surface:n,device:a}=e;return t?r&&eq(r)?t2("open --relaunch does not support URL targets."):"app"!==n?t2("open --relaunch is supported only for app surfaces."):"android"===a.platform&&r&&"binary"===eV(r)?t2(eK(r)):null:null}async function t6(e){let{req:t,sessionName:r,sessionStore:n,device:a,surface:i,openTarget:o,existingSession:s}=e;await ec(a);let{appBundleId:l,appName:c}=await t8({device:a,surface:i,openTarget:o,existingAppBundleId:s?.appBundleId}),p=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:n,device:a}=e,i=r.getRuntimeHints(n),o=function(e){let{runtime:t,sessionName:r,platform:n}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new d("INVALID_ARGS","open runtime must be an object.");let a=Object.keys(t).find(e=>!tI.includes(e));if(a)throw new d("INVALID_ARGS",`Invalid open runtime field: ${a}. Supported fields are ${tI.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new d("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new d("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,n),metroHost:tN(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new d("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return tM(e)}}(t.metroPort),bundleUrl:tN(t.bundleUrl,"bundleUrl"),launchUrl:tN(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:n,platform:tx(a.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let n=e.getRuntimeHints(t);if(!n)return;let a=r?.platform,i=tx(a);if(n.platform&&r&&!i)throw new d("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${a}.`);if(n.platform&&i&&n.platform!==i)throw new d("INVALID_ARGS",`Session runtime hints target ${n.platform}, but session "${t}" is bound to ${a}. Clear the runtime hints or use a different session.`);return i&&n.platform!==i?{...n,platform:i}:n}(r,n,a),previousRuntime:i,replacedStoredRuntime:!1}:{runtime:o&&t_(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=u(t);return R(e.code,e.message,e.details)}}({req:t,sessionStore:n,sessionName:r,device:a});if(!p.ok)return{type:"response",response:p};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=p.data;await tD({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:c,runtime:p.data.runtime}}}async function t8(e){let{device:t,surface:r,openTarget:n,existingAppBundleId:a}=e,i=await tP(r);return{appBundleId:i.appBundleId??await t1(t,n,a,tQ),appName:i.appName??n}}let t9=new Map;async function t4(e){let{device:t,closeTarget:r,outFlag:n,context:a}=e;"android"!==t.platform&&await S(t.id),await m(t,"close",[r],n,a),await F(t,$)}async function t7(e){var t,r;let n,{runtime:a,device:i,req:o,logPath:s,appBundleId:l,traceLogPath:u,openPositionals:c}=e,d=a?.launchUrl;if(!d||0===c.length||c.length>1)return;let p=c[0]?.trim();!p||eq(p)||await m(i,"open",[d],o.flags?.out,{...(t=s,r=o.flags,n=Y(t,r,l,u),delete n.launchConsole,delete n.launchArgs,n)})}async function re(e){var t,r,n,a;let i,{req:o,sessionName:s,sessionStore:l,logPath:u,device:c,openTarget:d,openPositionals:p,appName:f,surface:h,appBundleId:w,runtime:g,existingSession:y}=e,v=o.flags?.relaunch===!0,A=y?.trace?.outPath,b=w,S=Date.now(),I={};if(v&&d){let e=b??d,t=Date.now();await t4({device:c,closeTarget:e,outFlag:o.flags?.out,context:{...Y(u,o.flags,b??y?.appBundleId,A)}}),I.relaunchCloseDurationMs=Math.max(0,Date.now()-t)}let _=Date.now();await E({device:c,appId:b,runtime:g}),I.runtimeHintsDurationMs=Math.max(0,Date.now()-_);let N="ios"===c.platform&&"app"===h&&p.length>0,M={verbose:o.flags?.verbose,logPath:u,traceLogPath:A,requestId:o.meta?.requestId};if(N&&b&&(I.runnerPrewarmKind="session",I.runnerPrewarmScheduled=!0,i=ed(c,M)),i&&o.flags?.maestro?.prewarmRunnerBeforeOpen===!0){let e=Date.now();await i,I.runnerPrewarmWaited=!0,I.runnerPrewarmDurationMs=Math.max(0,Date.now()-e)}let x=Date.now();await m(c,"open",p,o.flags?.out,{...Y(u,o.flags,b)}),I.openDispatchDurationMs=Math.max(0,Date.now()-x);let k=Date.now();if(await t7({runtime:g,device:c,req:o,logPath:u,appBundleId:b,traceLogPath:A,openPositionals:p}),I.launchUrlDurationMs=Math.max(0,Date.now()-k),v&&i&&!0!==I.runnerPrewarmWaited){let e=Date.now();await i,I.runnerPrewarmWaited=!0,I.runnerPrewarmDurationMs=Math.max(0,Date.now()-e)}else i&&!0!==I.runnerPrewarmWaited&&(I.runnerPrewarmWaited=!1);b=await t0(c,d,b),"android"===c.platform&&b&&await tq(c,b);let O=d?(t=b,{durationMs:Math.max(0,Date.now()-x),measuredAt:new Date().toISOString(),method:tO,appTarget:d,appBundleId:t}):void 0,P=Date.now();if(await F(c,L),I.postOpenSettleDurationMs=Math.max(0,Date.now()-P),er(o.meta?.requestId)){let e=D();return R(e.code,e.message,e.details)}y&&eM(y,"open",y.snapshot);let $=function(e){let{existingSession:t,sessionName:r,device:n,surface:a,appBundleId:i,appName:o,saveScript:s}=e;return t?{...t,device:n,surface:a,appBundleId:i,appName:o,recordSession:t.recordSession||s,snapshot:void 0}:{name:r,device:n,createdAt:Date.now(),surface:a,appBundleId:i,appName:o,recordSession:s,actions:[]}}({existingSession:y,sessionName:s,device:c,surface:h,appBundleId:b,appName:f,saveScript:!!o.flags?.saveScript});void 0!==o.runtime&&(r=l,n=s,(a=g)&&(0===t_(a)?r.clearRuntimeHints(n):r.setRuntimeHints(n,a))),I.totalDurationMs=Math.max(0,Date.now()-S);let C=function(e){let{sessionName:t,appName:r,appBundleId:n,surface:a,startup:i,timing:o,device:s,runtime:l,runtimeHintCount:u}=e,c={session:t,surface:a};return r&&(c.appName=r),n&&(c.appBundleId=n),i&&(c.startup=i),o&&(c.timing=o),l&&u(l)>0&&(c.runtime=l),s&&(c.platform=s.platform,c.target=s.target??"mobile",c.device=s.name,c.id=s.id,c.kind=s.kind,"android"===s.platform&&(c.serial=s.id)),s?.platform==="ios"&&(c.device_udid=s.id,c.ios_simulator_device_set=s.simulatorSetPath??null),{...c,...ek(`Opened: ${r??n??t}`)}}({sessionName:s,appName:f,appBundleId:b,surface:h,startup:O,timing:I,device:c,runtime:g,runtimeHintCount:t_});return l.recordAction($,{command:"open",positionals:p,flags:o.flags??{},runtime:void 0!==o.runtime?g:void 0,result:C}),l.set(s,$),{ok:!0,data:C}}async function rt(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e;if(a.has(r)){let e=a.get(r);if(!e)return R("SESSION_NOT_FOUND",`Session "${r}" not found.`);let i=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(i?e.appName:void 0),l=t3(e.device,t.flags?.surface,s,e.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return i?t2("open --relaunch requires an app name or an active session app."):t2("Session already active. Close it first or pass a new --session name.");let u=t5({shouldRelaunch:i,openTarget:s,surface:l,device:e.device});if(u)return u;let c=await x(e.device),d=await t6({req:t,sessionName:r,sessionStore:a,device:c,surface:l,openTarget:s,existingSession:e});return"response"===d.type?d.response:await re({req:t,sessionName:r,sessionStore:a,logPath:n,device:c,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:d.details.appBundleId,appName:d.details.appName,runtime:d.details.runtime,surface:l,existingSession:e})}let i=t.flags?.relaunch===!0,o=t.positionals?.[0];if(i&&!o)return t2("open --relaunch requires an app argument.");let s=function(e){let{shouldRelaunch:t,openTarget:r,platform:n}=e;return t?r&&eq(r)?t2("open --relaunch does not support URL targets."):"android"===n&&r&&"binary"===eV(r)?t2(eK(r)):null:null}({shouldRelaunch:i,openTarget:o,platform:t.flags?.platform==="android"?"android":void 0});if(s)return s;let l=await U(t.flags??{}),u=t3(l,t.flags?.surface,o);if("string"!=typeof u)return u;let c=t5({shouldRelaunch:i,openTarget:o,surface:u,device:l});return c||await V(t9,l.id,async()=>{let e=a.toArray().find(e=>e.device.id===l.id);if(e)return R("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:l.id,deviceName:l.name,hint:`Run agent-device session list and reuse --session ${e.name}, or close that session before opening a new one on this device.`});let i=await t6({req:t,sessionName:r,sessionStore:a,device:l,surface:u,openTarget:o});return"response"===i.type?i.response:await re({req:t,sessionName:r,sessionStore:a,logPath:n,device:l,openTarget:o,openPositionals:t.positionals??[],appBundleId:i.details.appBundleId,appName:i.details.appName,runtime:i.details.runtime,surface:u})})}let rr={ios:async(e,t,r)=>{let{reinstallIosApp:n}=await import("./apps.js");return await n(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:n}=await import("./8806.js");return await n(e,t,r)}},rn={ios:async(e,t,r)=>{let{installIosApp:n}=await import("./apps.js"),a=await n(e,r,{appIdentifierHint:t});return{bundleId:a.bundleId,appName:a.appName,launchTarget:a.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:n}=await import("./8806.js"),a=await n(e,r);return{package:a.packageName,appName:a.appName,launchTarget:a.launchTarget}}};async function ra(e){let{req:r,command:n,sessionName:a,sessionStore:i,deployOps:o}=e,s=i.get(a),l=r.flags??{},u=I(n,s,l);if(u)return u;let c=r.positionals?.[0]?.trim(),d=r.positionals?.[1]?.trim();if(!c||!d)return R("INVALID_ARGS",`${n} requires: ${n} <app> <path-to-app-binary>`);let p=r.meta?.uploadedArtifactId;try{var f;let e,a=p?es(p,r.meta?.tenantId):Q.expandHome(d);if(!t.existsSync(a))return R("INVALID_ARGS",`App binary not found: ${a}`);let u=await g({session:s,flags:l,ensureReady:!1});if(!eA(n,u))return R("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);if("ios"===u.platform){let t=await o.ios(u,c,a),r=t.bundleId;e=r?{app:c,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:c,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(u,c,a),r=t.package;e=r?{app:c,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:c,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=eD(e,(f=e,`Installed: ${f.appName??eO(f)}`));return s&&i.recordAction(s,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&N(p)}}async function ri(e,t,r){return await eH(e,t,r)}async function ro(e){let{req:t,sessionName:r,sessionStore:n}=e;if("session_list"===t.command)return{ok:!0,data:{sessions:n.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("devices"===t.command)try{let e=ej(t.flags?.androidDeviceAllowlist),r=eI(t.flags?.platform),n=f({simulatorSetPath:eE(t.flags?.iosSimulatorDeviceSet),platform:r,target:t.flags?.target}),a=await Z({platform:r,target:t.flags?.target,deviceName:t.flags?.device,udid:t.flags?.udid,serial:t.flags?.serial,iosSimulatorSetPath:n,androidSerialAllowlist:e?Array.from(e).sort():void 0}),i=r?a.filter(e=>{var t,n;return t=e,!(n=r)||("apple"===n?eb(t.platform):t.platform===n)}):a,o=(t.flags?.target?i.filter(e=>(e.target??"mobile")===t.flags?.target):i).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=u(t);return R(e.code,e.message,e.details)}if("apps"===t.command){let e=n.get(r),a=t.flags??{},i=I(t.command,e,a);if(i)return i;let o=await g({session:e,flags:a,ensureReady:!0});if(!eA("apps",o))return R("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=ez(t.flags?.appsFilter);return eb(o.platform)?{ok:!0,data:{apps:(await eJ(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}:{ok:!0,data:{apps:(await eB(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function rs(e){let{ensureAndroidEmulatorBooted:t}=await import("./8806.js");return await t(e)}let rl='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',ru='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function rc(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r),i=t.flags??{},o=eI(i.platform);if(!a&&y(i))return R("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=I("appstate",a,i);if(s)return s;let l=eb(a?.device.platform)&&w(i,a);if("ios"===o&&!l)return R("SESSION_NOT_FOUND",rl);if("macos"===o&&!l)return R("SESSION_NOT_FOUND",ru);if(l&&a){let e=a.appName??a.appBundleId;if(!a.appName&&!a.appBundleId){if("macos"===a.device.platform&&a.surface&&"app"!==a.surface&&"frontmost-app"!==a.surface)return{ok:!0,data:{platform:a.device.platform,appName:a.surface,appBundleId:a.appBundleId,source:"session",surface:a.surface}};let e="macos"===a.device.platform?"macOS":"iOS";return R("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:a.device.platform,appName:e??"unknown",appBundleId:a.appBundleId,source:"session",surface:a.surface??"app",..."ios"===a.device.platform?{device_udid:a.device.id,ios_simulator_device_set:a.device.simulatorSetPath??null}:{}}}}let u=await g({session:a,flags:i,ensureReady:!0});if("ios"===u.platform)return R("SESSION_NOT_FOUND",rl);if("macos"===u.platform)return R("SESSION_NOT_FOUND",ru);let{getAndroidAppState:c}=await import("./8806.js"),d=await c(u);return{ok:!0,data:{platform:"android",package:d.package,activity:d.activity}}}async function rd(e){let{req:t,sessionName:r,sessionStore:n}=e;if("boot"===t.command){let e,a=n.get(r),i=t.flags??{},o=I(t.command,a,i);if(o)return o;let s="android"===(eI(i.platform)??a?.device.platform),l=!0===i.headless;if(l&&!s)return R("INVALID_ARGS","boot --headless is supported only for Android emulators.");let c=ef({flags:i,sessionDevice:a?.device}),d=s&&!!c,p=!1;try{e=await g({session:a,flags:i,ensureReady:!1})}catch(r){let t=u(r);if(s&&l&&!c&&"DEVICE_NOT_FOUND"===t.code)return R("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!d||"DEVICE_NOT_FOUND"!==t.code||!c)throw r;e=await rs({avdName:c,serial:i.serial,headless:l}),p=!0}if(i.target&&(e.target??"mobile")!==i.target)return R("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${i.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return R("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!p){let t=ef({flags:i,sessionDevice:a?.device,resolvedDevice:e});if(!t)return R("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await rs({avdName:t,serial:i.serial,headless:!0})}await ec(e)}else("android"!==e.platform||!0!==e.booted)&&await ec(e);return eA("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:R("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await rc({req:t,sessionName:r,sessionStore:n}):null}function rp(e,t){for(let r of e){if(t(r))return r;let e=rp(r.children,t);if(e)return e}}function rf(e,t){let r=[];for(let n of e)t(n)&&r.push(n),r.push(...rf(n.children,t));return r}function rm(e,t){let r=rp(e,e=>"schema"===e.name&&e.attributes.name===t);return r?r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}):[]}function rh(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 rw(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:rh(e):null}let rg="xctrace-animation-hitches";function ry(e,t){let r=ew(e),n=rm(r,t);return{rows:0===n.length?[]:rf(r,e=>"row"===e.name),schema:n}}function rv(e,t){for(let r of e)rv(r.children,t),r.attributes.id&&t.set(r.attributes.id,{numberValue:rh(r),process:rA(r)})}function rA(e){if(!e||e.children.some(e=>"sentinel"===e.name))return null;let t=rh(rp(e.children,e=>"pid"===e.name)),r=(e.attributes.fmt??"").replace(/\s+\(\d+\)$/,"").trim();return null===t&&0===r.length?null:{pid:t??void 0,name:r.length>0?r:void 0}}let rb="ps-process-snapshot",rS="ps-process-snapshot",rI="xctrace-activity-monitor",r_="xctrace-activity-monitor";async function rN(e,t){if("ios"===e.platform&&"device"===e.kind)return await rF(e,t);let r=await r$(e,t),n=await rG(e,r);if(0===n.length)throw new d("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let a=new Date().toISOString();return rj({usagePercent:n.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:n.reduce((e,t)=>e+t.rssKb,0),measuredAt:a,matchedProcesses:[r.executableName],cpuMethod:rb,memoryMethod:rS})}async function rM(e,t){var r;let n,o,s,l,u,c;if("ios"!==e.platform||"device"!==e.kind)throw new d("COMMAND_FAILED","Apple frame-health sampling is currently available only on connected iOS devices.",{metric:"fps",platform:e.platform,deviceKind:e.kind});let p=await rC(e,t),f=await rx(e,t,p);return n=ry((r={hitchesXml:f.hitchesXml,frameLifetimesXml:f.frameLifetimesXml,displayInfoXml:f.displayInfoXml,processIds:p.map(e=>e.pid),processNames:C(p.map(e=>a.basename(i(e.executable)))),windowStartedAt:f.windowStartedAt,windowEndedAt:f.windowEndedAt,measuredAt:f.windowEndedAt}).frameLifetimesXml,"hitches-frame-lifetimes").rows.length,o=function(e){if(!e)return;let{rows:t,schema:r}=ry(e,"device-display-info"),n=r.indexOf("max-refresh-rate");if(n<0)return;let a=new Map;for(let e of t){rv(e.children,a);let t=rw(e.children[n],a);if(null!==t&&t>0)return t}}(r.displayInfoXml),l=(s=(function(e){let t,r,n=ew(e),a=Object.values(r={start:(t=rm(n,"hitches")).indexOf("start"),duration:t.indexOf("duration"),process:t.indexOf("process"),isSystem:t.indexOf("is-system")}).every(e=>e>=0)?r:null;if(!a)return[];let i=new Map;return rf(n,e=>"row"===e.name).map(e=>(function(e,t,r){var n,a,i;let o;if(rv(e.children,r),!0===(n=e.children[t.isSystem],null===(o=rw(n,r))?null:0!==o))return null;let s=rw(e.children[t.start],r),l=rw(e.children[t.duration],r);if(null===s||null===l)return null;let u=(a=e.children[t.process],i=r,a?a.attributes.ref?i.get(a.attributes.ref)?.process??null:rA(a):null);return{startNs:s,durationNs:l,pid:u?.pid,processName:u?.name}})(e,a,i)).filter(e=>!!e)})(r.hitchesXml).filter(e=>{var t,n,a;return t=e,n=r.processIds,a=r.processNames,!!(void 0!==t.pid&&n.includes(t.pid))||!!t.processName&&a.includes(t.processName)})).length,u=Math.max(0,Math.round(Date.parse(r.windowEndedAt)-Date.parse(r.windowStartedAt))),c=function(e,t){if(0===e.length)return[];let r=[...e].sort((e,t)=>e.startNs-t.startNs),n=[],a=[];for(let e of r){let t=a.at(-1);if(!t||e.startNs-(t.startNs+t.durationNs)<=5e8){a.push(e);continue}n.push(a),a=[e]}return a.length>0&&n.push(a),n.map(e=>{var r,n;let a,i,o,s;return r=e,n=t,a=Math.min(...r.map(e=>e.startNs)),i=Math.max(...r.map(e=>e.startNs+e.durationNs)),s=Math.max(o=Math.max(0,Math.round(a/1e6)),Math.round(i/1e6)),{startOffsetMs:o,endOffsetMs:s,startAt:new Date(n+o).toISOString(),endAt:new Date(n+s).toISOString(),missedDeadlineFrameCount:r.length,worstFrameMs:tF(Math.max(...r.map(e=>e.durationNs))/1e6)}}).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}(s,Date.parse(r.windowStartedAt)),{droppedFramePercent:n>0?tF(l/n*100):0,droppedFrameCount:l,totalFrameCount:n,sampleWindowMs:u,windowStartedAt:r.windowStartedAt,windowEndedAt:r.windowEndedAt,measuredAt:r.measuredAt,method:rg,matchedProcesses:[...new Set(s.map(e=>e.processName).filter(e=>"string"==typeof e&&e.length>0))],frameDeadlineMs:void 0===o?void 0:tF(1e3/o),refreshRateHz:o,worstWindows:c.length>0?c:void 0}}async function rx(e,t,i){let o=await r.mkdtemp(a.join(n.tmpdir(),"agent-device-ios-frame-perf-")),s=a.join(o,"animation-hitches.trace"),l=a.join(o,"hitches.xml"),u=a.join(o,"frame-lifetimes.xml"),c=a.join(o,"display-info.xml");try{let n=await rD({device:e,appBundleId:t,tracePath:s,template:"Animation Hitches",duration:"2s",targetPids:i.map(e=>e.pid),validateTraceOutput:!0,failureMessage:`Failed to record iOS frame-health sample for ${t}`});await rR(e,t,s,"hitches",l),await rR(e,t,s,"hitches-frame-lifetimes",u);let a=await rL(e,t,s,"device-display-info",c);return{windowStartedAt:n.startedAt,windowEndedAt:n.endedAt,hitchesXml:await r.readFile(l,"utf8"),frameLifetimesXml:await r.readFile(u,"utf8"),displayInfoXml:a?await r.readFile(c,"utf8"):void 0}}finally{await r.rm(o,{recursive:!0,force:!0}).catch(()=>{})}}async function rD(e){let{device:t,appBundleId:r,tracePath:n,template:a,duration:i}=e,o=e.allProcesses?["--all-processes"]:(e.targetPids??[]).flatMap(e=>["--attach",String(e)]),s=["xctrace","record","--template",a,"--device",t.id,...o,"--time-limit",i,"--output",n,"--quiet","--no-prompt"],l=await rk(s,e.tracePath);if(0===l.result.exitCode)return e.validateTraceOutput&&await rO(e,l.result.stdout,l.result.stderr),{startedAt:l.startedAt,endedAt:l.endedAt,capturedAtMs:l.capturedAtMs};throw new d("COMMAND_FAILED",e.failureMessage,{cmd:"xcrun",args:s,exitCode:l.result.exitCode,stdout:l.result.stdout,stderr:l.result.stderr,appBundleId:r,deviceId:t.id,hint:rK(l.result.stdout,l.result.stderr)})}async function rk(e,t){let n;for(let a=1;a<=3;a+=1){a>1&&(await r.rm(t,{recursive:!0,force:!0}).catch(()=>{}),await new Promise(e=>setTimeout(e,1500)));let i=new Date().toISOString(),o=await p(e,{allowFailure:!0,timeoutMs:6e4});if(n={result:o,startedAt:i,endedAt:new Date().toISOString(),capturedAtMs:Date.now()},0===o.exitCode||!function(e){let t=`${e.stdout}
2
- ${e.stderr}`.toLowerCase();return t.includes("_lockkperf")||t.includes("could not lock kperf")||t.includes("likely another session just started")}(o))break}return n}async function rO(e,t,n){let a=await r.stat(e.tracePath).catch(()=>null);if(!(a?.isDirectory()===!0?(await r.readdir(e.tracePath).catch(()=>[])).length>0:(a?.size??0)>0))throw new d("COMMAND_FAILED",`${e.failureMessage}: xctrace produced no trace data`,{tracePath:e.tracePath,appBundleId:e.appBundleId,deviceId:e.device.id,stdout:t,stderr:n,hint:"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf."})}async function rR(e,t,r,n,a){let i=["xctrace","export","--input",r,"--xpath",`/trace-toc/run/data/table[@schema="${n}"]`,"--output",a],o=await p(i,{allowFailure:!0,timeoutMs:15e3});if(0!==o.exitCode)throw new d("COMMAND_FAILED",`Failed to export iOS device ${n} data`,{cmd:"xcrun",args:i,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:rK(o.stdout,o.stderr)})}async function rL(e,t,r,n,a){try{return await rR(e,t,r,n,a),!0}catch{return!1}}async function rP(e){let t=ew(e),r=rm(t,"activity-monitor-process-live");if(0===r.length)throw new d("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let n=r.indexOf("pid"),a=r.indexOf("process"),i=r.indexOf("cpu-total"),o=r.indexOf("memory-real");if(n<0||a<0||i<0||o<0)throw new d("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let s=rf(t,e=>"row"===e.name),l=[],u=new Map;for(let e of s){var c,p;let t=e.children;if(0===t.length)continue;for(let e of t){let t=rp(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:rh(e),processName:rq(e)})}let r=rw(t[n],u),s=(c=t[a],p=u,c?c.attributes.ref?p.get(c.attributes.ref)?.processName??null:rq(c):null);null!==r&&Number.isFinite(r)&&s&&l.push({pid:r,processName:s,cpuTimeNs:rw(t[i],u),residentMemoryBytes:rw(t[o],u)})}return l}async function r$(e,t){let r="macos"===e.platform?await rU(t):await rT(e,t),n="macos"===e.platform?a.join(r,"Contents","Info.plist"):a.join(r,"Info.plist"),i=await eX(n,"CFBundleExecutable");if(!i)throw new d("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?a.join(r,"Contents","MacOS",i):a.join(r,i)}}async function rF(e,t){let r=await rC(e,t),n=await rE(e,t),a=await rE(e,t),i=rV(await rP(n.xml),r,t,e),o=rV(await rP(a.xml),r,t,e),s=a.capturedAtMs-n.capturedAtMs;if(s<=0)throw new d("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===i.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new d("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 rj({usagePercent:Math.max(0,o.cpuTimeNs-i.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(a.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:rI,memoryMethod:r_})}async function rC(e,t){let r=(await ev(e,"all")).find(e=>e.bundleId===t);if(!r)throw new d("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new d("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let n=r.url.replace(/\/$/,""),a=i(n),o=(await eS(e)).filter(e=>e.executable.startsWith(`${n}/`));if(0===o.length)throw new d("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:a,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return o}async function rE(e,t){let i=await r.mkdtemp(a.join(n.tmpdir(),"agent-device-ios-perf-")),o=a.join(i,"sample.trace"),s=a.join(i,"activity-monitor-process-live.xml");try{let n=await rD({device:e,appBundleId:t,tracePath:o,template:"Activity Monitor",duration:"1s",allProcesses:!0,failureMessage:`Failed to record iOS device Activity Monitor sample for ${t}`});return await rR(e,t,o,"activity-monitor-process-live",s),{capturedAtMs:n.capturedAtMs,xml:await r.readFile(s,"utf8")}}finally{await r.rm(i,{recursive:!0,force:!0}).catch(()=>{})}}function rV(e,t,r,n){let o=new Set(t.map(e=>e.pid)),s=new Set(t.map(e=>a.basename(i(e.executable)))),l=e.filter(e=>o.has(e.pid)||s.has(e.processName));if(0===l.length)throw new d("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:n.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let u=new Map;for(let e of l){let t=u.get(e.pid);if(!t){u.set(e.pid,e);continue}u.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:rB(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:rB(t.residentMemoryBytes,e.residentMemoryBytes)})}let c=[...u.values()],p=c.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=c.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:p.length>0?p.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:C(c.map(e=>e.processName))}}async function rU(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await ey("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new d("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let n=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!n)throw new d("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return n}async function rT(e,t){let r=em(e,["get_app_container",e.id,t,"app"]),n=await p(r,{allowFailure:!0,timeoutMs:15e3});if(0!==n.exitCode)throw new d("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let a=n.stdout.trim();if(0===a.length)throw new d("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return a}async function rG(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:em(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of eC(e)){let e=r.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!e)continue;let[n,a,i,o]=e.slice(1);if(void 0===n||void 0===a||void 0===i||void 0===o)continue;let s=Number(n),l=Number(a),u=Number(i),c=o.trim();Number.isFinite(s)&&Number.isFinite(l)&&Number.isFinite(u)&&t.push({pid:s,cpuPercent:l,rssKb:u,command:c})}return t})(("macos"===e.platform?await ey("ps",r,{timeoutMs:15e3}):await p(r,{timeoutMs:15e3})).stdout).filter(e=>{var r,n;let i;return r=e.command,n=t,i=function(e){let[t=""]=e.trim().split(/\s+/,1);return t}(r),!!(n.executablePath&&(r===n.executablePath||i===n.executablePath||r.startsWith(`${n.executablePath} `)))||a.basename(i)===n.executableName})}function rj(e){return{cpu:{usagePercent:tF(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 rq(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function rK(e,t){let r=k(e,t);if(r)return r;let n=`${e}
3
- ${t}`.toLowerCase();return n.includes("no device matched")||n.includes("failed to find device")?J:n.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function rB(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function rH(e,t={}){var r,n,a;let i,o,s,l,u=(s=(o=(i=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===tO&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:tO,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}((r=e).actions)).at(-1))?{available:!0,lastDurationMs:o.durationMs,lastMeasuredAt:o.measuredAt,method:tO,sampleCount:i.length,samples:i}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:tO},{session:r.name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{startup:s,fps:{available:!1,reason:"Dropped-frame sampling is currently available only on Android."},memory:{available:!1,reason:tR},cpu:{available:!1,reason:tR}},sampling:{startup:{method:tO,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:tB,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:tK,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:tE,description:"Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.",unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}};var t=e.device;let r="ios"===t.platform&&"device"===t.kind?{method:rg,description:"Rendered-frame hitch health from xctrace Animation Hitches on connected iOS devices. Dropped frames are counted from native hitch rows for the attached app process, with total frames from the same trace frame-lifetime table.",unit:"percent",primaryField:"droppedFramePercent",window:"short 2s xctrace Animation Hitches record of the active app process",resetsAfterRead:!1}:{method:rg,description:"Unavailable on iOS simulators and macOS because local Apple tooling does not expose reliable app frame hitches for these targets.",unit:"percent",primaryField:"droppedFramePercent"};if("ios"===t.platform&&"device"===t.kind)return{fps:r,memory:{method:r_,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:rI,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let n="macos"===t.platform?"host ps for the running macOS app executable resolved from the bundle ID.":"xcrun simctl spawn ps for the running iOS simulator app executable resolved from the bundle ID.";return{fps:r,memory:{method:rS,description:`Resident memory snapshot from ${n}`,unit:"kB"},cpu:{method:rb,description:`Recent CPU usage snapshot from ${n}`,unit:"percent"}}}(r)}});return"android"!==(n=e).device.platform&&"ios"!==n.device.platform&&"macos"!==n.device.platform||(e.appBundleId?"android"===e.device.platform?await rW(u,e,t):await rz(u,e):(a=u,l="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.",a.metrics.fps={available:!1,reason:l},a.metrics.memory={available:!1,reason:l},a.metrics.cpu={available:!1,reason:l})),u}async function rW(e,t,r){let n=await rJ(t,r);e.metrics.memory=rZ(n.memory),e.metrics.cpu=rZ(n.cpu),e.metrics.fps=rQ(rZ(n.fps),t)}async function rz(e,t){let r=await rX(t);e.metrics.memory=rZ(r.memory),e.metrics.cpu=rZ(r.cpu),e.metrics.fps=rQ(rZ(r.fps),t)}async function rJ(e,t){let r=e.appBundleId,n={adb:t.androidAdb},[a,i,o]=await Promise.allSettled([tW(e.device,r,n),tH(e.device,r,n),tj(e.device,r,n)]);return{memory:a,cpu:i,fps:o}}async function rX(e){let t=e.appBundleId,r=await rY(rM(e.device,t)),n=await rY(rN(e.device,t));if("fulfilled"===n.status){let e=n.value;return{memory:{status:"fulfilled",value:e.memory},cpu:{status:"fulfilled",value:e.cpu},fps:r}}return{memory:{status:"rejected",reason:n.reason},cpu:{status:"rejected",reason:n.reason},fps:r}}async function rY(e){try{return{status:"fulfilled",value:await e}}catch(e){return{status:"rejected",reason:e}}}function rZ(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=c(e.reason);return{available:!1,reason:t.message,error:t}}function rQ(e,t){var r,n;let a,i;if(!0!==e.available)return e;let o=(r=t.actions,a=r0((n=e).windowStartedAt),i=r0(n.windowEndedAt)??r0(n.measuredAt),void 0===a||void 0===i?[]:r.filter(e=>e.ts>=a&&e.ts<=i).map(e=>({command:e.command,at:new Date(e.ts).toISOString(),offsetMs:Math.max(0,Math.round(e.ts-a)),target:function(e){let t=e.result;if(t)for(let e of["refLabel","ref","appName","appBundleId"]){let r=t[e];if("string"==typeof r&&r.length>0)return r}}(e)})).slice(-12));return 0===o.length?e:{...e,relatedActions:o}}function r0(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let r1=["path","start","stop","doctor","mark","clear"],r2=`logs requires ${r1.slice(0,-1).join(", ")}, or ${r1.at(-1)}`,r3=["dump","log"],r5=`network requires ${r3.join(" or ")}`,r6=["summary","headers","body","all"],r8=`network include mode must be one of: ${r6.join(", ")}`;async function r9(e){let{req:t}=e;return"perf"===t.command?r4(e):"logs"===t.command?r7(e):"network"===t.command?na(e):null}async function r4(e){let{sessionName:t,sessionStore:r,androidAdbExecutor:n}=e,a=r.get(t);if(!a)return R("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await rH(a,{androidAdb:n})}}catch(e){return{ok:!1,error:c(e)}}}async function r7(e){var t,r,n;let a,i,{req:o,sessionName:s,sessionStore:l}=e,u=l.get(s);if(!u)return R("SESSION_NOT_FOUND","logs requires an active session");if(!eA("logs",u.device))return R("UNSUPPORTED_OPERATION","logs is not supported on this device");let c=(o.positionals?.[0]??"path").toLowerCase(),d=!!o.flags?.restart;return r1.includes(c)?d&&"clear"!==c?R("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===c?function(e,t,r){let n=r.resolveAppLogPath(t),a=T(n);return{ok:!0,data:{path:n,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:a.sizeBytes,modifiedAt:a.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(u,s,l):"doctor"===c?ne(u,s,l):"mark"===c?(t=o,r=s,n=l,a=t.positionals?.slice(1).join(" ")??"",h(i=n.resolveAppLogPath(r),a),{ok:!0,data:{path:i,marked:!0}}):"clear"===c?nt(u,s,l,d):"start"===c?nr(u,s,l):"stop"===c?nn(u,s,l):R("INVALID_ARGS",r2):R("INVALID_ARGS",r2)}async function ne(e,t,r){let n=r.resolveAppLogPath(t),a=await ei(e.device,e.appBundleId);return{ok:!0,data:{path:n,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:a.checks,notes:a.notes}}}async function nt(e,t,r,n){if(e.appLog&&!n)return R("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(n&&!e.appBundleId)return R("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let a=r.resolveAppLogPath(t);if(!n)return{ok:!0,data:H(a)};e.appLog&&await el(e.appLog);let i=H(a),o=r.resolveAppLogPidPath(t);try{let n=await eN(e.device,e.appBundleId,a,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{...i,restarted:!0}}}catch(n){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:c(n)}}}async function nr(e,t,r){if(e.appLog)return R("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return R("INVALID_ARGS","logs start requires an app session; run open <app> first");let n=r.resolveAppLogPath(t),a=r.resolveAppLogPidPath(t);try{let i=await eN(e.device,e.appBundleId,n,a);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:n,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}}),{ok:!0,data:{path:n,started:!0}}}catch(e){return{ok:!1,error:c(e)}}}async function nn(e,t,r){if(!e.appLog)return R("INVALID_ARGS","no app log stream active");let n=e.appLog.outPath;return await el(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:n,stopped:!0}}}async function na(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return R("SESSION_NOT_FOUND","network requires an active session");if(!eA("network",a.device))return R("UNSUPPORTED_OPERATION","network is not supported on this device");let i=(t.positionals?.[0]??"dump").toLowerCase();if(!r3.includes(i))return R("INVALID_ARGS",r5);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return R("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 R("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let n=(r??t??"summary").toLowerCase();return r6.includes(n)?{ok:!0,include:n}:R("INVALID_ARGS",r8)}(t);if(!s.ok)return s;let{include:l}=s,u=await W({device:a.device,appBundleId:a.appBundleId,appLogState:a.appLog?.getState(),appLogStartedAt:a.appLog?.startedAt,appLogPath:n.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...u.dump,active:!!a.appLog,state:a.appLog?.getState()??"inactive",backend:u.backend,notes:u.notes}}}let ni=/^[A-Z_][A-Z0-9_]*$/,no=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,ns="AD_VAR_";function nl(e){return e.startsWith("AD_")}function nu(e){return new d("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function nc(e){let t={};for(let[r,n]of Object.entries(e)){if("string"!=typeof n||!r.startsWith(ns))continue;let e=r.slice(ns.length);0!==e.length&&ni.test(e)&&(nl(e)||(t[e]=n))}return t}function nd(e){let t={};for(let r of e){let e=r.indexOf("=");if(e<=0)throw new d("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let n=r.slice(0,e);if(!ni.test(n))throw new d("INVALID_ARGS",`Invalid -e key "${n}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(nl(n))throw nu(n);t[n]=r.slice(e+1)}return t}function np(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function nf(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[r,n]of Object.entries(e))"string"==typeof n&&(t[r]=n);return t}return process.env}function nm(e,t,r){return e.replace(no,(e,n,a,i)=>{if(n)return"${";if(!a)return e;if(Object.prototype.hasOwnProperty.call(t.values,a))return String(t.values[a]);if(void 0!==i)return i.replace(/\\(.)/g,"$1");throw new d("INVALID_ARGS",`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function nh(e,t,r){return e?function e(t,r,n){return"string"==typeof t?nm(t,r,n):Array.isArray(t)?t.map(t=>e(t,r,n)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,a])=>[t,e(a,r,n)])):t}(e,t,r):e}let nw=new Set(["ios","android","macos","linux"]),ng=new Set(["mobile","tv","desktop"]);function ny(e){let t=e.split(/\r?\n/),r={};for(let[e,n]of t.entries()){let t=n.trim();if(0===t.length||t.startsWith("#"))continue;if(nv(t)){!function(e,t,r){let{key:n,value:a}=function(e,t){let r=e.slice(3).replace(/^[\s]+/,""),n=r.indexOf("=");if(n<=0)throw new d("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let a=r.slice(0,n);if(!ni.test(a))throw new d("INVALID_ARGS",`Invalid env key "${a}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(a.startsWith("AD_"))throw new d("INVALID_ARGS",`Invalid env key "${a}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${a} to avoid the AD_ prefix.`);return{key:a,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new d("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(r.slice(n+1),t)}}(t,r),i=e.env??{};if(Object.prototype.hasOwnProperty.call(i,n))throw new d("INVALID_ARGS",`Duplicate env directive "${n}" on line ${r}.`);i[n]=a,e.env=i}(r,t,e+1);continue}if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&nw.has(e)&&nA(r,"platform",e)}let i=t.match(/(?:^|\s)target=([^\s]+)/);if(i){let e=i[1];e&&ng.has(e)&&nA(r,"target",e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&nA(r,"timeoutMs",Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&nA(r,"retries",Math.floor(e))}}return r}function nv(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function nA(e,t,r){let n=e[t];if(void 0!==n)throw new d("INVALID_ARGS",n===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(n)} vs ${String(r)}.`);e[t]=r}function nb(e){return!!e&&!Number.isNaN(Number(e))}function nS(e,t=[],r){return{ts:Date.now(),command:e,positionals:t,flags:r??{}}}function nI(e,t,r){let n=new Set(r),a=Object.keys(e).filter(e=>!n.has(e));if(a.length>0)throw nL(`Maestro ${t} field "${a[0]}" is not supported yet.`)}function n_(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function nN(e){return e.map((e,t)=>{if("string"==typeof e||n_(e))return e;throw new d("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function nM(e,t){if(null==e)return{};if(!n_(e))throw new d("INVALID_ARGS",`${t} expects a map.`);let r={};for(let[t,n]of Object.entries(e))("string"==typeof n||"number"==typeof n||"boolean"==typeof n)&&(r[t]=String(n));return r}function nx(e,t){return n_(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function nD(e,t){if(e.appId)return e.appId;throw new d("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function nk(e,t){if("string"==typeof t)return t;throw new d("INVALID_ARGS",`${e} expects a string value.`)}function nO(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,r)=>Object.prototype.hasOwnProperty.call(t.env,r)?String(t.env[r]):e)}function nR(e){throw nL(`Maestro command "${e}" is not supported yet.`)}function nL(e){throw new d("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${eP}. If this syntax matters for your flows, comment there or open a focused issue at ${e$}.`)}function nP(e,t,r){var n,a;if(null==e)return nS("open",[nO(nD(t,"launchApp"),r)]);if("string"==typeof e)return nS("open",[nO(e,r)]);if(!n_(e))throw new d("INVALID_ARGS","launchApp expects a string or map.");nI(e,"launchApp",["appId","stopApp","clearState","clearKeychain","arguments","permissions","launchArguments"]),nE(e,"permissions"),nE(e,"clearKeychain");let i=nO("string"==typeof e.appId?e.appId:nD(t,"launchApp"),r),o=(n=e,a=r,[...nF(n.arguments,"launchApp.arguments",a),...nF(n.launchArguments,"launchApp.launchArguments",a)]),s=!0===e.clearState;return nS("open",[i],{...!s&&(!0===e.stopApp||o.length>0)?{relaunch:!0}:{},...s?{clearAppState:!0}:{},...o.length>0?{launchArgs:o}:{}})}function n$(e,t,r){if(null==e)return nS("close",[nO(nD(t,"stopApp"),r)]);if("string"==typeof e)return nS("close",[nO(e,r)]);throw new d("INVALID_ARGS","stopApp expects a string appId or no value.")}function nF(e,t,r){if(null==e)return[];if("string"==typeof e)return[nO(e,r)];if(Array.isArray(e))return e.map((e,n)=>nC(e,`${t}[${n}]`,r));if(n_(e))return Object.entries(e).flatMap(([e,n])=>[nO(e,r),nC(n,`${t}.${e}`,r)]);throw new d("INVALID_ARGS",`${t} expects a string, list, or map.`)}function nC(e,t,r){if("string"==typeof e)return nO(e,r);if("number"==typeof e||"boolean"==typeof e)return String(e);throw new d("INVALID_ARGS",`${t} must be a string, number, or boolean.`)}function nE(e,t){if(void 0!==e[t])throw nL(`Maestro launchApp field "${t}" is not supported yet.`)}function nV(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw nL('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function nU(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:"absolute",x:Number(t[1]),y:Number(t[2])};let r=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(r)return{kind:"percent",x:Number(r[1]),y:Number(r[2])};throw nL('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}let nT="__maestroRunScript",nG="__maestroAssertVisible",nj="__maestroAssertNotVisible",nq="__maestroPressEnter",nK="__maestroWaitForAnimationToEnd",nB="__maestroScrollUntilVisible",nH="__maestroSwipeScreen",nW="__maestroSwipeOn",nz="__maestroTapOn",nJ="__maestroTapPointPercent";function nX(e){if(null==e)return nS("type",["\b".repeat(50)]);if("number"==typeof e&&Number.isInteger(e)&&e>0)return nS("type",["\b".repeat(e)]);if(!n_(e))throw new d("INVALID_ARGS","eraseText expects empty, a positive count, or a map.");if(nI(e,"eraseText",["charactersToErase"]),void 0===e.charactersToErase)return nS("type",["\b".repeat(50)]);if("number"!=typeof e.charactersToErase||!Number.isInteger(e.charactersToErase)||e.charactersToErase<=0)throw new d("INVALID_ARGS","eraseText.charactersToErase must be a positive integer.");return nS("type",["\b".repeat(e.charactersToErase)])}function nY(e){return"number"==typeof e&&Number.isFinite(e)?String(Math.max(16,Math.floor(e))):void 0}function nZ(e,t){let r=e.toLowerCase();switch(r){case"up":case"down":case"left":case"right":return r;default:throw nL(`Maestro ${t} must be UP, DOWN, LEFT, or RIGHT.`)}}function nQ(e){return nZ(e,"swipe direction")}function n0(e,t,r=[],n){if("string"==typeof e)return n1(nO(e,n));if(!n_(e))throw new d("INVALID_ARGS",`${t} expects a string or selector map.`);nI(e,t,["id","text","enabled","selected",...r]);let a=[],i=[];if("boolean"==typeof e.enabled&&i.push(n3("enabled",String(e.enabled))),"boolean"==typeof e.selected&&i.push(n3("selected",String(e.selected))),"string"==typeof e.id&&a.push(n3("id",nO(e.id,n)),...i),"string"==typeof e.text&&0===a.length)return n1(nO(e.text,n),i);if("string"==typeof e.label&&0===a.length&&a.push(n3("label",nO(e.label,n)),...i),0===a.length&&i.length>0&&a.push(...i),0===a.length)throw new d("INVALID_ARGS",`${t} selector map must include one of id, text, label, enabled, or selected.`);return a.join(" ")}function n1(e,t=[]){return[[n3("label",e),...t].join(" "),[n3("text",e),...t].join(" "),[n3("id",e),...t].join(" ")].join(" || ")}function n2(e){let t=nY(e.duration);return t?[t]:[]}function n3(e,t){return`${e}=${JSON.stringify(t)}`}function n5(e){var t,r;if(!n_(e))return;let n={},a="number"==typeof(t=e.repeat)&&Number.isInteger(t)&&t>0?t:void 0,i="number"==typeof(r=e.delay)&&Number.isInteger(r)&&r>=0?r:void 0;return a&&a>1&&(n.count=a),void 0!==i&&(n.intervalMs=i),!0===e.optional&&(n.maestro={optional:!0}),Object.keys(n).length>0?n:void 0}function n6(e){let t=n5(e)??{};return{...t,maestro:{...t.maestro??{},allowNonHittableCoordinateFallback:!0}}}function n8(e){let t={doubleTap:!0};return n_(e)&&"number"==typeof e.delay&&Number.isInteger(e.delay)&&(t.intervalMs=Math.max(0,e.delay)),t}class n9{index=0;tokens;context;constructor(e,t){this.tokens=e,this.context=t}parse(){let e=this.parseOr();if(this.peek())throw new d("INVALID_ARGS","Unsupported trailing runFlow.when.true expression.");return e}parseOr(){let e=this.parseAnd();for(;this.consumeOperator("||");)e=this.parseAnd()||e;return e}parseAnd(){let e=this.parsePrimary();for(;this.consumeOperator("&&");)e=this.parsePrimary()&&e;return e}parsePrimary(){let e=this.peek();if(!e)throw new d("INVALID_ARGS","Incomplete runFlow.when.true expression.");if("boolean"===e.type)return this.index+=1,e.value;if("paren"===e.type&&"("===e.value){this.index+=1;let e=this.parseOr();if(!this.consumeParen(")"))throw new d("INVALID_ARGS","Unclosed runFlow.when.true parenthesis.");return e}return this.parsePlatformComparison()}parsePlatformComparison(){this.expectPlatform();let e=this.expectEqualityOperator(),t=this.expectString().toLowerCase(),r=this.context.platform;return"=="===e?r===t:r!==t}expectPlatform(){if(this.peek()?.type!=="platform")throw new d("INVALID_ARGS","runFlow.when.true supports maestro.platform comparisons.");this.index+=1}expectEqualityOperator(){let e=this.peek();if(e?.type==="operator"&&("=="===e.value||"!="===e.value))return this.index+=1,e.value;throw new d("INVALID_ARGS","runFlow.when.true comparison requires == or !=.")}expectString(){let e=this.peek();if(e?.type==="string")return this.index+=1,e.value;throw new d("INVALID_ARGS","runFlow.when.true comparison requires a string literal.")}consumeOperator(e){let t=this.peek();return t?.type==="operator"&&t.value===e&&(this.index+=1,!0)}consumeParen(e){let t=this.peek();return t?.type==="paren"&&t.value===e&&(this.index+=1,!0)}peek(){return this.tokens[this.index]}}function n4(e,t,r){return{...nS(e,t),replayControl:r}}function n7(e,t,r){let n="string"==typeof e?nO(e,t):e,a="number"==typeof n?n:"string"==typeof n&&/^\d+$/.test(n)?Number(n):void 0;if(void 0===a||!Number.isInteger(a)||a<0)throw new d("INVALID_ARGS",`${r} must be a non-negative integer or \${VAR} resolving to one.`);return a}let ae=`
1
+ import{__webpack_require__ as e}from"./rslib-runtime.js";import t,{promises as r}from"node:fs";import n from"node:os";import a from"node:path";import{fileURLToPath as i}from"node:url";import{parseAllDocuments as o}from"yaml";import s from"node:vm";import{setTimeout as l}from"node:timers/promises";import{asAppError as u,normalizeError as c,AppError as d}from"./9152.js";import{runXcrun as p,resolveAppleSimulatorSetPathForSelector as f,dispatchCommand as m,sessionMatchesScope as h,selectorTargetsSessionDevice as w,appendAppLogMarker as g,resolveCommandDevice as y,hasRuntimeTransportHints as v,inferFillText as A,formatPortableActionLine as b,stopIosRunnerSession as S,resolvePublicSessionName as I,requireSessionOrExplicitSelector as _,isTouchTargetCommand as N,cleanupUploadedArtifact as M,isClickLikeCommand as x,refreshSessionDeviceIfNeeded as k,createRequestCanceledError as D,resolveIosDevicectlHint as O,registerRequestAbort as R,errorResponse as L,IOS_SIMULATOR_POST_OPEN_SETTLE_MS as P,IOS_SIMULATOR_POST_CLOSE_SETTLE_MS as $,parseReplayOpenFlags as F,settleIosSimulator as C,uniqueStrings as E,applyRuntimeHintsToApp as V,withKeyedLock as U,getAppLogPathMetadata as T,buildSessionRecoveryHint as G,resolveTargetDevice as q,parseReplayRuntimeFlags as j,setSessionSnapshot as K,getSnapshotReferenceFrame as H,clearRuntimeHintsFromApp as B,handleCloseCommand as W,clearAppLogFiles as z,session_device_utils_hasExplicitSessionFlag as J,readSessionNetworkCapture as X,cleanupRetainedMaterializedPaths as Y,isImplicitSessionScopeConflict as Z,IOS_DEVICECTL_DEFAULT_HINT as Q,buildSnapshotState as ee,context_contextFromFlags as et,listDeviceInventory as er,SessionStore as en,formatScriptStringLiteral as ea,formatScriptActionSummary as ei,isRequestCanceled as eo,resolveRequestTrackingId as es,retainMaterializedPaths as el,runAppLogDoctor as eu,resolvePayloadInput as ec,prepareUploadedArtifact as ed,markRequestCanceled as ep,stopAppLog as ef,runIosRunnerCommand as em,resolveImplicitSessionScope as eh,ensureDeviceReady as ew,prewarmIosRunnerSession as eg,clearRequestCanceled as ey,buildSimctlArgsForDevice as ev,resolveAndroidEmulatorAvdName as eA,parseReplaySeriesFlags as eb,parseXmlDocumentSync as eS,resolveFrontmostMacOsApp as eI,runAppleToolCommand as e_,listIosDeviceApps as eN,isCommandSupportedOnDevice as eM,isApplePlatform as ex,listIosDeviceProcesses as ek,normalizePlatformSelector as eD,getRequestSignal as eO,markAndroidSnapshotFreshness as eR,startAppLog as eL,emitRequestProgress as eP}from"./2415.js";import{withSuccessText as e$,successText as eF}from"./1998.js";import{resolveDeployResultTarget as eC,resolveInstallFromSourceResultTarget as eE}from"./6232.js";import{parseSessionSurface as eV,MAESTRO_COMPAT_TRACKER_URL as eU,MAESTRO_NEW_ISSUE_URL as eT}from"./1352.js";import{resolveAndroidAdbExecutor as eG}from"./9639.js";import{splitNonEmptyTrimmedLines as eq}from"./7455.js";import{resolveIosSimulatorDeviceSetPath as ej,classifyAndroidAppTarget as eK,resolveIosDeviceDeepLinkBundleId as eH,isInfrastructureBootFailureReason as eB,isWebUrl as eW,resolveAndroidSerialAllowlist as ez,isDeepLinkTarget as eJ,formatAndroidInstalledPackageRequiredMessage as eX,listAndroidApps as eY}from"./8806.js";import{runBatch as eZ,mergeParentFlags as eQ}from"./1231.js";import{assertResolvedAppsFilter as e0}from"./1393.js";import{listIosApps as e1,readInfoPlistString as e2}from"./apps.js";import{readScreenshotScriptFlag as e3}from"./5310.js";import{runCmdSync as e5}from"./9818.js";import{emitDiagnostic as e6}from"./7599.js";import{splitSelectorFromArgs as e8,extractNodeText as e9,findSnapshotAncestor as e4,isDescendantOfSnapshotNode as e7,splitIsSelectorArgs as te,tryParseSelectorChain as tt,parseSelectorChain as tr,resolveSelectorChain as tn,buildSelectorChainForNode as ta,buildSnapshotNodeByIndex as ti,matchesSelector as to,normalizeType as ts}from"./940.js";import{normalizeText as tl}from"./7556.js";import{pointFromPercent as tu,buildSwipeGesturePlan as tc,clampToRange as td,interiorCoordinate as tp,evaluateIsPredicate as tf,pointInsideRect as tm,readReactNativeOverlayActionNodes as th,detectReactNativeOverlay as tw,clampGesturePoint as tg}from"./9533.js";import{sleep as ty}from"./4829.js";import{INTERNAL_COMMANDS as tv,DAEMON_COMMAND_GROUPS as tA,PUBLIC_COMMANDS as tb}from"./5792.js";import{trimRuntimeValue as tS}from"./8656.js";var tI={};async function t_(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 d("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 d("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let n=await q(e.flags??{});return await ew(n),n}async function tN(e){let{prepared:t,retention:r,req:n,session:a,sessionName:i}=e;if(r.enabled)return await el({archivePath:t.archivePath,installablePath:t.installablePath,tenantId:n.meta?.tenantId,sessionName:a?i:void 0,ttlMs:r.ttlMs})}function tM(e){return e?{...e.archivePath?{archivePath:e.archivePath}:{},installablePath:e.installablePath,materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}}async function tx(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);try{let e,i,o=(e=function(e){let t=e.meta?.installSource;if(!t)throw new d("INVALID_ARGS","install_from_source requires a source payload");switch(t.kind){case"url":if(!t.url||0===t.url.trim().length)throw new d("INVALID_ARGS","install_from_source url source requires a non-empty url");return t;case"path":if(!t.path||0===t.path.trim().length)throw new d("INVALID_ARGS","install_from_source path source requires a non-empty path");return t;case"github-actions-artifact":throw new d("UNSUPPORTED_OPERATION","install_from_source github-actions-artifact sources require a compatible remote daemon");default:throw new d("UNSUPPORTED_OPERATION",`install_from_source ${String(t.kind)} sources require a compatible remote daemon`)}}(t),(i=t.meta?.uploadedArtifactId)&&"path"===e.kind?{source:{kind:"path",path:ed(i,t.meta?.tenantId)},cleanup:()=>{M(i)}}:{source:e,cleanup:()=>{}}),s=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new d("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),l=await t_({session:a,flags:t.flags});if(!eM("install",l))return L("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=eO(t.meta?.requestId),c=async(e,i)=>{let l;try{var u;l=await tN({prepared:e,retention:s,req:t,session:a,sessionName:r});let o=await i(l),c=e$(o,(u=o,`Installed: ${eE(u)}`));return!function(e){let{session:t,sessionStore:r,req:n,data:a}=e;t&&r.recordAction(t,{command:"install_source",positionals:[],flags:n.flags??{},result:a})}({session:a,sessionStore:n,req:t,data:c}),{ok:!0,data:c}}catch(e){throw l&&await Y(l.materializationId,t.meta?.tenantId).catch(()=>{}),e}finally{await e.cleanup(),o.cleanup()}};if("ios"===l.platform){let{installIosInstallablePath:e}=await import("./apps.js"),{prepareIosInstallArtifact:t}=await import("./apps.js"),r=await t(o.source,{signal:u});return await c(r,async t=>{if(await e(l,r.installablePath),!r.bundleId)throw new d("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");return{...tM(t),bundleId:r.bundleId,...r.appName?{appName:r.appName}:{},launchTarget:r.bundleId}})}let{prepareAndroidInstallArtifact:p}=await import("./8806.js"),{installAndroidInstallablePathAndResolvePackageName:f}=await import("./8806.js"),m=await p(o.source,{signal:u});return await c(m,async e=>{let t=await f(l,m.installablePath,m.packageName);if(!t)throw new d("COMMAND_FAILED","Installed Android app identity could not be resolved from the artifact or device state");let{inferAndroidAppName:r}=await import("./8806.js"),n=r(t);return{...tM(e),packageName:t,...n?{appName:n}:{},launchTarget:t}})}catch(e){return{ok:!1,error:c(e)}}}async function tk(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new d("INVALID_ARGS","release_materialized_paths requires a materializationId");return await Y(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:c(e)}}}e.r(tI),e.d(tI,{SESSION_COMMAND_HANDLERS:()=>i0,handleSessionCommands:()=>i5});let tD=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function tO(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function tR(e,t){if(void 0!==e){if("string"!=typeof e)throw new d("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return tS(e)}}function tL(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new d("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function tP(e){if("ios"===e||"android"===e)return e}async function t$(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:n,session:a}=e;!t||!a?.appBundleId||!v(r)||v(n)||await B({device:a.device,appId:a.appBundleId})}async function tF(e){var t,r;let{req:n,sessionName:a,sessionStore:i}=e,o=(n.positionals?.[0]??"show").toLowerCase(),s=i.get(a),l=i.getRuntimeHints(a);if(!["set","show","clear"].includes(o))return L("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){v(l)&&s?.appBundleId&&await B({device:s.device,appId:s.appBundleId});let e=i.clearRuntimeHints(a);return{ok:!0,data:{session:a,cleared:e}}}if("show"===o)return{ok:!0,data:{session:a,configured:!!l,runtime:l}};let u=tP(eD(n.flags?.platform)??l?.platform??s?.device.platform);if(!u)return L("INVALID_ARGS","runtime set only supports iOS and Android sessions. Pass --platform ios|android or open an iOS/Android session first.");if(s&&s.device.platform!==u)return L("INVALID_ARGS",`runtime set targets ${u}, but session "${a}" is already bound to ${s.device.platform}.`);let c={platform:(t=n.flags,r={platform:u,metroHost:tS(t?.metroHost),metroPort:tL(t?.metroPort),bundleUrl:tS(t?.bundleUrl),launchUrl:tS(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===tO(c)?L("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(i.setRuntimeHints(a,c),{ok:!0,data:{session:a,configured:!0,runtime:c}})}let tC="open-command-roundtrip",tE="Not implemented for this platform in this release.",tV=new Set(["app","desktop","frontmost-app"]);async function tU(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eI();return{appBundleId:t.bundleId,appName:t.appName}}function tT(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}function tG(e){return Math.round(10*e)/10}function tq(e){return Math.round(10*e)/10}let tj="adb-shell-dumpsys-gfxinfo-framestats";function tK(e,t,r){let n=t.get(r);if(void 0===n)return null;let a=Number(e[n]);return Number.isFinite(a)?a:null}function tH(e){return 0===e.length?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function tB(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function tW(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=e.match(RegExp(`^\\s*${r}:\\s*([0-9][0-9,]*)`,"im"));if(!n)return;let a=n[1];return void 0===a?void 0:tT(a)??void 0}async function tz(e,t,r={}){var n,a,i,o,s,l,u,c;let p=eG(e,r.adb);try{let u,c,f,m,h,w,g,y,v,A,b,S=(n=(await p(["shell","dumpsys","gfxinfo",t,"framestats"],{timeoutMs:15e3})).stdout,a=new Date().toISOString(),function(e,t){if(/no process found for:/i.test(e))throw new d("COMMAND_FAILED",`Android gfxinfo did not find a running process for ${t}`,{metric:"fps",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect."})}(n,t),f=function(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??"",r=tW(t,"Total frames rendered"),n=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(void 0===r||!n)return;let a=n[1],i=n[2];if(void 0===a||void 0===i)return;let o=tT(a)??void 0,s=Number(i);if(void 0===o||!Number.isFinite(s)||r<0)return;let l=tW(t,"Uptime"),u=tW(t,"Stats since");return{droppedFramePercent:tG(s),droppedFrameCount:o,totalFrameCount:r,sampleWindowMs:function(e){let{uptimeMs:t,statsSinceNs:r}=e;if(void 0===t||void 0===r)return;let n=t-Math.round(r/1e6);return n>=0?n:void 0}({uptimeMs:l,statsSinceNs:u}),uptimeMs:l,statsSinceNs:u}}(n),m=function(e){let t=[],r=null;for(let a of e.split("\n")){var n;let e=a.trim();if(0===e.length||"---PROFILEDATA---"===e)continue;let i=e.split(",").map(e=>e.trim());if((n=i).includes("IntendedVsync")&&n.includes("FrameCompleted")){r=new Map(i.map((e,t)=>[e,t]));continue}let o=function(e,t){if(!t||e.length<t.size)return;let r=tK(e,t,"Flags"),n=tK(e,t,"IntendedVsync"),a=tK(e,t,"FrameCompleted");if(0===r&&null!==n&&null!==a&&!(n<=0)&&!(a<=n))return{intendedVsyncNs:n,frameCompletedNs:a,durationNs:a-n}}(i,r);o&&t.push(o)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}(n),h=function(e,t,r){let n=function(e){var t;let r=(t=e.map(e=>e.intendedVsyncNs),[...new Set(t.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)),n=[];for(let e=1;e<r.length;e+=1){let t=r[e]-r[e-1];t>=4e6&&t<=5e7&&n.push(t)}if(0!==n.length){let e,t;return e=[...n].sort((e,t)=>e-t),t=Math.floor(e.length/2),e.length%2==1?e[t]:(e[t-1]+e[t])/2}}(e);if(t||0!==e.length||function(e){throw new d("COMMAND_FAILED",`Failed to parse Android framestats output for ${e}`,{metric:"fps",package:e,hint:"Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging."})}(r),t||void 0!==n)return n;throw new d("COMMAND_FAILED",`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:"fps",package:r,hint:"Retry perf after a longer interaction window so consecutive Android frame timestamps are available."})}(m,f,t),w=Date.parse(a),g=function(e){let{frames:t,measuredAtMs:r,summary:n}=e,a=tH(t),i=n?.statsSinceNs,o=i??a.firstFrameNs,s=tB(o,a.lastFrameNs),l=n?.sampleWindowMs??s;if(!Number.isFinite(r)||n?.uptimeMs===void 0||void 0===o)return{sampleWindowMs:l,windowStartNs:o};let u=r-n.uptimeMs;return{sampleWindowMs:l,windowStartNs:o,windowStartedAt:new Date(u+o/1e6).toISOString(),windowEndedAt:function(e){let{deviceBootWallClockMs:t,measuredAtMs:r,summaryStartNs:n,lastFrameNs:a}=e;return void 0!==n?new Date(r).toISOString():void 0===a?void 0:new Date(t+a/1e6).toISOString()}({deviceBootWallClockMs:u,measuredAtMs:r,summaryStartNs:i,lastFrameNs:a.lastFrameNs}),timestampSource:"estimated-from-device-uptime"}}({frames:m,measuredAtMs:w,summary:f}),y=function(e){let{frames:t,frameDeadlineNs:r,summaryDroppedFrameCount:n}=e;return void 0!==n?n<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,n).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs):void 0===r?[]:t.filter(e=>e.durationNs>r)}({frames:m,frameDeadlineNs:h,summaryDroppedFrameCount:f?.droppedFrameCount}),v=f?.sampleWindowMs??g.sampleWindowMs??function(e){if(0===e.length)return;let t=tH(e);return tB(t.firstFrameNs,t.lastFrameNs)}(m),i=f,o=m,s=y,u=i?.totalFrameCount??o.length,c=i?.droppedFrameCount??s.length,A={totalFrameCount:u,droppedFrameCount:c,droppedFramePercent:i?.droppedFramePercent??(u>0?tG(c/u*100):0)},b=function(e){let{droppedFrames:t,timing:r,measuredAtMs:n,summary:a}=e;if(0===t.length)return;let i=function(e){let{frames:t,windowStartNs:r,measuredAtMs:n,uptimeMs:a}=e;if(0===t.length||void 0===r)return[];let i=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}i.push(o),o=[e]}return o.length>0&&i.push(o),i.map(e=>(function(e){let{frames:t,windowStartNs:r,measuredAtMs:n,uptimeMs:a}=e,i=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((i-r)/1e6)),l=Math.max(s,Math.round((o-r)/1e6)),u=void 0!==a&&Number.isFinite(n)?n-a:void 0;return{startOffsetMs:s,endOffsetMs:l,startAt:void 0===u?void 0:new Date(u+i/1e6).toISOString(),endAt:void 0===u?void 0:new Date(u+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:tq(Math.max(...t.map(e=>e.durationNs))/1e6)}})({frames:e,windowStartNs:r,measuredAtMs:n,uptimeMs:a})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}({frames:t,windowStartNs:r.windowStartNs,measuredAtMs:n,uptimeMs:a?.uptimeMs});return i.length>0?i:void 0}({droppedFrames:y,timing:g,measuredAtMs:w,summary:f}),{...A,sampleWindowMs:v,...(l=h,{frameDeadlineMs:void 0===l?void 0:tq(l/1e6),refreshRateHz:void 0===l?void 0:tq(1e9/l)}),windowStartedAt:g.windowStartedAt,windowEndedAt:g.windowEndedAt,timestampSource:g.timestampSource,measuredAt:a,method:tj,source:f?"android-gfxinfo-summary":"framestats-rows",worstWindows:b&&b.length>0?b:void 0});return await tJ(e,t,r),S}catch(e){throw u=t,(c=e)instanceof d?new d(c.code,c.message,{...c.details??{},metric:"fps",package:u},c):new d("COMMAND_FAILED",`Failed to sample Android fps for ${u}`,{metric:"fps",package:u},c)}}async function tJ(e,t,r={}){let n=eG(e,r.adb);try{await n(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let tX="adb-shell-dumpsys-cpuinfo",tY="adb-shell-dumpsys-meminfo";async function tZ(e,t,r={}){let n=eG(e,r.adb);try{let e=await n(["shell","dumpsys","cpuinfo"],{timeoutMs:15e3});return function(e,t,r){let n=new Set,a=0;for(let r of eq(e)){var i,o;let e=r.match(/^([0-9]+(?:\.[0-9]+)?)%\s+\d+\/([^\s]+):\s/);if(!e)continue;let s=e[1],l=e[2];if(void 0===s||void 0===l)continue;let u=Number(s);Number.isFinite(u)&&(i=l,o=t,i===o||i.startsWith(`${o}:`))&&(a+=u,n.add(l))}return{usagePercent:tG(a),measuredAt:r,method:tX,matchedProcesses:[...n]}}(e.stdout,t,new Date().toISOString())}catch(e){throw t0("cpu",t,e)}}async function tQ(e,t,r={}){let n=eG(e,r.adb);try{let e=await n(["shell","dumpsys","meminfo",t],{timeoutMs:15e3});return function(e,t,r){if(/no process found for:/i.test(e))throw new d("COMMAND_FAILED",`Android meminfo did not find a running process for ${t}`,{metric:"memory",package:t,hint:"Run open <app> for this session again to ensure the Android app is active, then retry perf."});let n=t1(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!==tT(e));if(!r)break;return tT(r)??void 0}}(e);if(void 0===n)throw new d("COMMAND_FAILED",`Failed to parse Android meminfo output for ${t}`,{metric:"memory",package:t,hint:"Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging."});return{totalPssKb:n,totalRssKb:t1(e,"TOTAL RSS"),measuredAt:r,method:tY}}(e.stdout,t,new Date().toISOString())}catch(e){throw t0("memory",t,e)}}function t0(e,t,r){return r instanceof d?new d(r.code,r.message,{...r.details??{},metric:e,package:t},r):new d("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function t1(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=e.match(RegExp(`${r}:\\s*([0-9][0-9,]*)`,"i"));if(!n)return;let a=n[1];return void 0===a?void 0:tT(a)??void 0}async function t2(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return eJ(t)?"macos"===e.platform?void 0:"device"===e.kind?eH(r,t):eW(t)?void 0:r??await t3(e,t):await t5(e,t)}async function t3(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function t5(e,t){try{let{resolveIosApp:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function t6(e,t){if(!("android"!==e.platform||!t||eJ(t)))try{let{resolveAndroidApp:r}=await import("./8806.js"),n=await r(e,t);return"package"===n.type?n.value:void 0}catch{return}}async function t8(e,t,r){if(r||"android"!==e.platform||!t||!eJ(t))return r;try{let{getAndroidAppState:t}=await import("./8806.js"),n=await t(e);return n.package?.trim()||r}catch{return r}}async function t9(e,t,r,n){return await t2(e,t,r)??await n(e,t)??("android"===e.platform&&t&&eJ(t)?r:void 0)}function t4(e){return L("INVALID_ARGS",e)}function t7(e,t,r,n){try{return function(e){let{device:t,surfaceFlag:r,openTarget:n,existingSurface:a}=e;if(("macos"===t.platform||"linux"===t.platform)&&!r)return a??"app";if("linux"===t.platform){if(!r)return"app";let e=eV(r);if(!tV.has(e))throw new d("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&n)throw new d("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new d("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let i=r?eV(r):"app";if("app"!==i&&"menubar"!==i&&n)throw new d("INVALID_ARGS",`open --surface ${i} does not accept an app target`);return i}({device:e,surfaceFlag:t,openTarget:r,existingSurface:n})}catch(e){return L(e instanceof d?e.code:"INVALID_ARGS",String(e.message))}}function re(e){let{shouldRelaunch:t,openTarget:r,surface:n,device:a}=e;return t?r&&eJ(r)?t4("open --relaunch does not support URL targets."):"app"!==n?t4("open --relaunch is supported only for app surfaces."):"android"===a.platform&&r&&"binary"===eK(r)?t4(eX(r)):null:null}async function rt(e){let{req:t,sessionName:r,sessionStore:n,device:a,surface:i,openTarget:o,existingSession:s}=e;await ew(a);let{appBundleId:l,appName:c}=await rr({device:a,surface:i,openTarget:o,existingAppBundleId:s?.appBundleId}),p=function(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:n,device:a}=e,i=r.getRuntimeHints(n),o=function(e){let{runtime:t,sessionName:r,platform:n}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new d("INVALID_ARGS","open runtime must be an object.");let a=Object.keys(t).find(e=>!tD.includes(e));if(a)throw new d("INVALID_ARGS",`Invalid open runtime field: ${a}. Supported fields are ${tD.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new d("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new d("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,n),metroHost:tR(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new d("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return tL(e)}}(t.metroPort),bundleUrl:tR(t.bundleUrl,"bundleUrl"),launchUrl:tR(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:n,platform:tP(a.platform)});return void 0===t.runtime?{runtime:function(e,t,r){let n=e.getRuntimeHints(t);if(!n)return;let a=r?.platform,i=tP(a);if(n.platform&&r&&!i)throw new d("INVALID_ARGS",`Session runtime hints are only supported on iOS and Android sessions, but session "${t}" is bound to ${a}.`);if(n.platform&&i&&n.platform!==i)throw new d("INVALID_ARGS",`Session runtime hints target ${n.platform}, but session "${t}" is bound to ${a}. Clear the runtime hints or use a different session.`);return i&&n.platform!==i?{...n,platform:i}:n}(r,n,a),previousRuntime:i,replacedStoredRuntime:!1}:{runtime:o&&tO(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=u(t);return L(e.code,e.message,e.details)}}({req:t,sessionStore:n,sessionName:r,device:a});if(!p.ok)return{type:"response",response:p};if(s){let{runtime:e,previousRuntime:t,replacedStoredRuntime:r}=p.data;await t$({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:c,runtime:p.data.runtime}}}async function rr(e){let{device:t,surface:r,openTarget:n,existingAppBundleId:a}=e,i=await tU(r);return{appBundleId:i.appBundleId??await t9(t,n,a,t6),appName:i.appName??n}}let rn=new Map;async function ra(e){let{device:t,closeTarget:r,outFlag:n,context:a}=e;"android"!==t.platform&&await S(t.id),await m(t,"close",[r],n,a),await C(t,$)}async function ri(e){var t,r;let n,{runtime:a,device:i,req:o,logPath:s,appBundleId:l,traceLogPath:u,openPositionals:c}=e,d=a?.launchUrl;if(!d||0===c.length||c.length>1)return;let p=c[0]?.trim();!p||eJ(p)||await m(i,"open",[d],o.flags?.out,{...(t=s,r=o.flags,n=et(t,r,l,u),delete n.launchConsole,delete n.launchArgs,n)})}async function ro(e){var t,r,n,a;let i,{req:o,sessionName:s,sessionStore:l,logPath:u,device:c,openTarget:d,openPositionals:p,appName:f,surface:h,appBundleId:w,runtime:g,existingSession:y}=e,v=o.flags?.relaunch===!0,A=y?.trace?.outPath,b=w,S=Date.now(),_={};if(v&&d){let e=b??d,t=Date.now();await ra({device:c,closeTarget:e,outFlag:o.flags?.out,context:{...et(u,o.flags,b??y?.appBundleId,A)}}),_.relaunchCloseDurationMs=Math.max(0,Date.now()-t)}let N=Date.now();await V({device:c,appId:b,runtime:g}),_.runtimeHintsDurationMs=Math.max(0,Date.now()-N);let M="ios"===c.platform&&"app"===h&&p.length>0,x={verbose:o.flags?.verbose,logPath:u,traceLogPath:A,requestId:o.meta?.requestId};if(M&&b&&(_.runnerPrewarmKind="session",_.runnerPrewarmScheduled=!0,i=eg(c,x)),i&&o.flags?.maestro?.prewarmRunnerBeforeOpen===!0){let e=Date.now();await i,_.runnerPrewarmWaited=!0,_.runnerPrewarmDurationMs=Math.max(0,Date.now()-e)}let k=Date.now();await m(c,"open",p,o.flags?.out,{...et(u,o.flags,b)}),_.openDispatchDurationMs=Math.max(0,Date.now()-k);let O=Date.now();if(await ri({runtime:g,device:c,req:o,logPath:u,appBundleId:b,traceLogPath:A,openPositionals:p}),_.launchUrlDurationMs=Math.max(0,Date.now()-O),v&&i&&!0!==_.runnerPrewarmWaited){let e=Date.now();await i,_.runnerPrewarmWaited=!0,_.runnerPrewarmDurationMs=Math.max(0,Date.now()-e)}else i&&!0!==_.runnerPrewarmWaited&&(_.runnerPrewarmWaited=!1);b=await t8(c,d,b),"android"===c.platform&&b&&await tJ(c,b);let R=d?(t=b,{durationMs:Math.max(0,Date.now()-k),measuredAt:new Date().toISOString(),method:tC,appTarget:d,appBundleId:t}):void 0,$=Date.now();if(await C(c,P),_.postOpenSettleDurationMs=Math.max(0,Date.now()-$),eo(o.meta?.requestId)){let e=D();return L(e.code,e.message,e.details)}y&&eR(y,"open",y.snapshot);let F=function(e){let{existingSession:t,sessionName:r,sessionScope:n,device:a,surface:i,appBundleId:o,appName:s,saveScript:l}=e;return t?{...t,device:a,surface:i,appBundleId:o,appName:s,recordSession:t.recordSession||l,snapshot:void 0}:{name:r,sessionScope:n,device:a,createdAt:Date.now(),surface:i,appBundleId:o,appName:s,recordSession:l,actions:[]}}({existingSession:y,sessionName:y?.name??I(o),sessionScope:y?.sessionScope??eh(o),device:c,surface:h,appBundleId:b,appName:f,saveScript:!!o.flags?.saveScript});void 0!==o.runtime&&(r=l,n=s,(a=g)&&(0===tO(a)?r.clearRuntimeHints(n):r.setRuntimeHints(n,a)));let E=l.ensureSessionDir(s);_.totalDurationMs=Math.max(0,Date.now()-S);let U=function(e){let{sessionName:t,sessionStateDir:r,appName:n,appBundleId:a,surface:i,startup:o,timing:s,device:l,runtime:u,runtimeHintCount:c}=e,d={session:t,surface:i};return r&&(d.sessionStateDir=r),n&&(d.appName=n),a&&(d.appBundleId=a),o&&(d.startup=o),s&&(d.timing=s),u&&c(u)>0&&(d.runtime=u),l&&(d.platform=l.platform,d.target=l.target??"mobile",d.device=l.name,d.id=l.id,d.kind=l.kind,"android"===l.platform&&(d.serial=l.id)),l?.platform==="ios"&&(d.device_udid=l.id,d.ios_simulator_device_set=l.simulatorSetPath??null),{...d,...eF(`Opened: ${n??a??t}`)}}({sessionName:F.name,sessionStateDir:E,appName:f,appBundleId:b,surface:h,startup:R,timing:_,device:c,runtime:g,runtimeHintCount:tO});return l.recordAction(F,{command:"open",positionals:p,flags:o.flags??{},runtime:void 0!==o.runtime?g:void 0,result:U}),l.set(s,F),{ok:!0,data:U}}async function rs(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,i=a.get(r);if(i){let e=t.flags?.relaunch===!0,o=t.positionals?.[0],s=o??(e?i.appName:void 0),l=t7(i.device,t.flags?.surface,s,i.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return e?t4("open --relaunch requires an app name or an active session app."):t4("Session already active. Close it first or pass a new --session name.");let u=re({shouldRelaunch:e,openTarget:s,surface:l,device:i.device});if(u)return u;let c=await k(i.device),d=await rt({req:t,sessionName:r,sessionStore:a,device:c,surface:l,openTarget:s,existingSession:i});return"response"===d.type?d.response:await ro({req:t,sessionName:r,sessionStore:a,logPath:n,device:c,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:d.details.appBundleId,appName:d.details.appName,runtime:d.details.runtime,surface:l,existingSession:i})}let o=t.flags?.relaunch===!0,s=t.positionals?.[0];if(o&&!s)return t4("open --relaunch requires an app argument.");let l=function(e){let{shouldRelaunch:t,openTarget:r,platform:n}=e;return t?r&&eJ(r)?t4("open --relaunch does not support URL targets."):"android"===n&&r&&"binary"===eK(r)?t4(eX(r)):null:null}({shouldRelaunch:o,openTarget:s,platform:t.flags?.platform==="android"?"android":void 0});if(l)return l;let u=await q(t.flags??{}),c=t7(u,t.flags?.surface,s);if("string"!=typeof c)return c;let d=re({shouldRelaunch:o,openTarget:s,surface:c,device:u});return d||await U(rn,u.id,async()=>{let e=a.toArray().find(e=>e.device.id===u.id);if(e)return Z(t,e)?L("DEVICE_IN_USE","Device is already in use by another workspace session.",{deviceId:u.id,deviceName:u.name,hint:"Use a different device selector, wait for the other workspace to close its session, or run agent-device devices to choose another target."}):L("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:u.id,deviceName:u.name,hint:G(e,"device-in-use")});let i=await rt({req:t,sessionName:r,sessionStore:a,device:u,surface:c,openTarget:s});return"response"===i.type?i.response:await ro({req:t,sessionName:r,sessionStore:a,logPath:n,device:u,openTarget:s,openPositionals:t.positionals??[],appBundleId:i.details.appBundleId,appName:i.details.appName,runtime:i.details.runtime,surface:c})})}let rl={ios:async(e,t,r)=>{let{reinstallIosApp:n}=await import("./apps.js");return await n(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:n}=await import("./8806.js");return await n(e,t,r)}},ru={ios:async(e,t,r)=>{let{installIosApp:n}=await import("./apps.js"),a=await n(e,r,{appIdentifierHint:t});return{bundleId:a.bundleId,appName:a.appName,launchTarget:a.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:n}=await import("./8806.js"),a=await n(e,r);return{package:a.packageName,appName:a.appName,launchTarget:a.launchTarget}}};async function rc(e){let{req:r,command:n,sessionName:a,sessionStore:i,deployOps:o}=e,s=i.get(a),l=r.flags??{},u=_(n,s,l);if(u)return u;let c=r.positionals?.[0]?.trim(),d=r.positionals?.[1]?.trim();if(!c||!d)return L("INVALID_ARGS",`${n} requires: ${n} <app> <path-to-app-binary>`);let p=r.meta?.uploadedArtifactId;try{var f;let e,a=p?ed(p,r.meta?.tenantId):en.expandHome(d);if(!t.existsSync(a))return L("INVALID_ARGS",`App binary not found: ${a}`);let u=await y({session:s,flags:l,ensureReady:!1});if(!eM(n,u))return L("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);if("ios"===u.platform){let t=await o.ios(u,c,a),r=t.bundleId;e=r?{app:c,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:c,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(u,c,a),r=t.package;e=r?{app:c,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:c,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=e$(e,(f=e,`Installed: ${f.appName??eC(f)}`));return s&&i.recordAction(s,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&M(p)}}async function rd(e,t,r){return await eZ(e,t,r)}async function rp(e){let{req:t,sessionName:r,sessionStore:n}=e;if("session_list"===t.command){let e=eh(t);return{ok:!0,data:{sessions:n.toArray().filter(t=>h(t,e)).map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",surface:e.surface??"app",device:e.device.name,id:e.device.id,device_id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}}}if("devices"===t.command)try{let e=ez(t.flags?.androidDeviceAllowlist),r=eD(t.flags?.platform),n=f({simulatorSetPath:ej(t.flags?.iosSimulatorDeviceSet),platform:r,target:t.flags?.target}),a=await er({platform:r,target:t.flags?.target,deviceName:t.flags?.device,udid:t.flags?.udid,serial:t.flags?.serial,iosSimulatorSetPath:n,androidSerialAllowlist:e?Array.from(e).sort():void 0}),i=r?a.filter(e=>{var t,n;return t=e,!(n=r)||("apple"===n?ex(t.platform):t.platform===n)}):a,o=(t.flags?.target?i.filter(e=>(e.target??"mobile")===t.flags?.target):i).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:o}}}catch(t){let e=u(t);return L(e.code,e.message,e.details)}if("apps"===t.command){let e=n.get(r),a=t.flags??{},i=_(t.command,e,a);if(i)return i;let o=await y({session:e,flags:a,ensureReady:!0});if(!eM("apps",o))return L("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=e0(t.flags?.appsFilter);return ex(o.platform)?{ok:!0,data:{apps:(await e1(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}:{ok:!0,data:{apps:(await eY(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function rf(e){let{ensureAndroidEmulatorBooted:t}=await import("./8806.js");return await t(e)}let rm='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',rh='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function rw(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r),i=t.flags??{},o=eD(i.platform);if(!a&&J(i))return L("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=_("appstate",a,i);if(s)return s;let l=ex(a?.device.platform)&&w(i,a);if("ios"===o&&!l)return L("SESSION_NOT_FOUND",rm);if("macos"===o&&!l)return L("SESSION_NOT_FOUND",rh);if(l&&a){let e=a.appName??a.appBundleId;if(!a.appName&&!a.appBundleId){if("macos"===a.device.platform&&a.surface&&"app"!==a.surface&&"frontmost-app"!==a.surface)return{ok:!0,data:{platform:a.device.platform,appName:a.surface,appBundleId:a.appBundleId,source:"session",surface:a.surface}};let e="macos"===a.device.platform?"macOS":"iOS";return L("COMMAND_FAILED",`No foreground app is tracked for this ${e} session. Open an app in the session, then retry appstate.`)}return{ok:!0,data:{platform:a.device.platform,appName:e??"unknown",appBundleId:a.appBundleId,source:"session",surface:a.surface??"app",..."ios"===a.device.platform?{device_udid:a.device.id,ios_simulator_device_set:a.device.simulatorSetPath??null}:{}}}}let u=await y({session:a,flags:i,ensureReady:!0});if("ios"===u.platform)return L("SESSION_NOT_FOUND",rm);if("macos"===u.platform)return L("SESSION_NOT_FOUND",rh);let{getAndroidAppState:c}=await import("./8806.js"),d=await c(u);return{ok:!0,data:{platform:"android",package:d.package,activity:d.activity}}}async function rg(e){let{req:t,sessionName:r,sessionStore:n}=e;if("boot"===t.command){let e,a=n.get(r),i=t.flags??{},o=_(t.command,a,i);if(o)return o;let s="android"===(eD(i.platform)??a?.device.platform),l=!0===i.headless;if(l&&!s)return L("INVALID_ARGS","boot --headless is supported only for Android emulators.");let c=eA({flags:i,sessionDevice:a?.device}),d=s&&!!c,p=!1;try{e=await y({session:a,flags:i,ensureReady:!1})}catch(r){let t=u(r);if(s&&l&&!c&&"DEVICE_NOT_FOUND"===t.code)return L("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!d||"DEVICE_NOT_FOUND"!==t.code||!c)throw r;e=await rf({avdName:c,serial:i.serial,headless:l}),p=!0}if(i.target&&(e.target??"mobile")!==i.target)return L("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${i.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return L("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!p){let t=eA({flags:i,sessionDevice:a?.device,resolvedDevice:e});if(!t)return L("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await rf({avdName:t,serial:i.serial,headless:!0})}await ew(e)}else("android"!==e.platform||!0!==e.booted)&&await ew(e);return eM("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:L("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await rw({req:t,sessionName:r,sessionStore:n}):null}function ry(e,t){for(let r of e){if(t(r))return r;let e=ry(r.children,t);if(e)return e}}function rv(e,t){let r=[];for(let n of e)t(n)&&r.push(n),r.push(...rv(n.children,t));return r}function rA(e,t){let r=ry(e,e=>"schema"===e.name&&e.attributes.name===t);return r?r.children.filter(e=>"col"===e.name).map(e=>{let t;return t=e.children.find(e=>"mnemonic"===e.name),t?.text??null??""}):[]}function rb(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 rS(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:rb(e):null}let rI="xctrace-animation-hitches";function r_(e,t){let r=eS(e),n=rA(r,t);return{rows:0===n.length?[]:rv(r,e=>"row"===e.name),schema:n}}function rN(e,t){for(let r of e)rN(r.children,t),r.attributes.id&&t.set(r.attributes.id,{numberValue:rb(r),process:rM(r)})}function rM(e){if(!e||e.children.some(e=>"sentinel"===e.name))return null;let t=rb(ry(e.children,e=>"pid"===e.name)),r=(e.attributes.fmt??"").replace(/\s+\(\d+\)$/,"").trim();return null===t&&0===r.length?null:{pid:t??void 0,name:r.length>0?r:void 0}}let rx="ps-process-snapshot",rk="ps-process-snapshot",rD="xctrace-activity-monitor",rO="xctrace-activity-monitor";async function rR(e,t){if("ios"===e.platform&&"device"===e.kind)return await rG(e,t);let r=await rT(e,t),n=await rW(e,r);if(0===n.length)throw new d("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,hint:"Run open <app> for this session again to ensure the Apple app is active, then retry perf."});let a=new Date().toISOString();return rz({usagePercent:n.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:n.reduce((e,t)=>e+t.rssKb,0),measuredAt:a,matchedProcesses:[r.executableName],cpuMethod:rx,memoryMethod:rk})}async function rL(e,t){var r;let n,o,s,l,u,c;if("ios"!==e.platform||"device"!==e.kind)throw new d("COMMAND_FAILED","Apple frame-health sampling is currently available only on connected iOS devices.",{metric:"fps",platform:e.platform,deviceKind:e.kind});let p=await rq(e,t),f=await rP(e,t,p);return n=r_((r={hitchesXml:f.hitchesXml,frameLifetimesXml:f.frameLifetimesXml,displayInfoXml:f.displayInfoXml,processIds:p.map(e=>e.pid),processNames:E(p.map(e=>a.basename(i(e.executable)))),windowStartedAt:f.windowStartedAt,windowEndedAt:f.windowEndedAt,measuredAt:f.windowEndedAt}).frameLifetimesXml,"hitches-frame-lifetimes").rows.length,o=function(e){if(!e)return;let{rows:t,schema:r}=r_(e,"device-display-info"),n=r.indexOf("max-refresh-rate");if(n<0)return;let a=new Map;for(let e of t){rN(e.children,a);let t=rS(e.children[n],a);if(null!==t&&t>0)return t}}(r.displayInfoXml),l=(s=(function(e){let t,r,n=eS(e),a=Object.values(r={start:(t=rA(n,"hitches")).indexOf("start"),duration:t.indexOf("duration"),process:t.indexOf("process"),isSystem:t.indexOf("is-system")}).every(e=>e>=0)?r:null;if(!a)return[];let i=new Map;return rv(n,e=>"row"===e.name).map(e=>(function(e,t,r){var n,a,i;let o;if(rN(e.children,r),!0===(n=e.children[t.isSystem],null===(o=rS(n,r))?null:0!==o))return null;let s=rS(e.children[t.start],r),l=rS(e.children[t.duration],r);if(null===s||null===l)return null;let u=(a=e.children[t.process],i=r,a?a.attributes.ref?i.get(a.attributes.ref)?.process??null:rM(a):null);return{startNs:s,durationNs:l,pid:u?.pid,processName:u?.name}})(e,a,i)).filter(e=>!!e)})(r.hitchesXml).filter(e=>{var t,n,a;return t=e,n=r.processIds,a=r.processNames,!!(void 0!==t.pid&&n.includes(t.pid))||!!t.processName&&a.includes(t.processName)})).length,u=Math.max(0,Math.round(Date.parse(r.windowEndedAt)-Date.parse(r.windowStartedAt))),c=function(e,t){if(0===e.length)return[];let r=[...e].sort((e,t)=>e.startNs-t.startNs),n=[],a=[];for(let e of r){let t=a.at(-1);if(!t||e.startNs-(t.startNs+t.durationNs)<=5e8){a.push(e);continue}n.push(a),a=[e]}return a.length>0&&n.push(a),n.map(e=>{var r,n;let a,i,o,s;return r=e,n=t,a=Math.min(...r.map(e=>e.startNs)),i=Math.max(...r.map(e=>e.startNs+e.durationNs)),s=Math.max(o=Math.max(0,Math.round(a/1e6)),Math.round(i/1e6)),{startOffsetMs:o,endOffsetMs:s,startAt:new Date(n+o).toISOString(),endAt:new Date(n+s).toISOString(),missedDeadlineFrameCount:r.length,worstFrameMs:tG(Math.max(...r.map(e=>e.durationNs))/1e6)}}).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}(s,Date.parse(r.windowStartedAt)),{droppedFramePercent:n>0?tG(l/n*100):0,droppedFrameCount:l,totalFrameCount:n,sampleWindowMs:u,windowStartedAt:r.windowStartedAt,windowEndedAt:r.windowEndedAt,measuredAt:r.measuredAt,method:rI,matchedProcesses:[...new Set(s.map(e=>e.processName).filter(e=>"string"==typeof e&&e.length>0))],frameDeadlineMs:void 0===o?void 0:tG(1e3/o),refreshRateHz:o,worstWindows:c.length>0?c:void 0}}async function rP(e,t,i){let o=await r.mkdtemp(a.join(n.tmpdir(),"agent-device-ios-frame-perf-")),s=a.join(o,"animation-hitches.trace"),l=a.join(o,"hitches.xml"),u=a.join(o,"frame-lifetimes.xml"),c=a.join(o,"display-info.xml");try{let n=await r$({device:e,appBundleId:t,tracePath:s,template:"Animation Hitches",duration:"2s",targetPids:i.map(e=>e.pid),validateTraceOutput:!0,failureMessage:`Failed to record iOS frame-health sample for ${t}`});await rE(e,t,s,"hitches",l),await rE(e,t,s,"hitches-frame-lifetimes",u);let a=await rV(e,t,s,"device-display-info",c);return{windowStartedAt:n.startedAt,windowEndedAt:n.endedAt,hitchesXml:await r.readFile(l,"utf8"),frameLifetimesXml:await r.readFile(u,"utf8"),displayInfoXml:a?await r.readFile(c,"utf8"):void 0}}finally{await r.rm(o,{recursive:!0,force:!0}).catch(()=>{})}}async function r$(e){let{device:t,appBundleId:r,tracePath:n,template:a,duration:i}=e,o=e.allProcesses?["--all-processes"]:(e.targetPids??[]).flatMap(e=>["--attach",String(e)]),s=["xctrace","record","--template",a,"--device",t.id,...o,"--time-limit",i,"--output",n,"--quiet","--no-prompt"],l=await rF(s,e.tracePath);if(0===l.result.exitCode)return e.validateTraceOutput&&await rC(e,l.result.stdout,l.result.stderr),{startedAt:l.startedAt,endedAt:l.endedAt,capturedAtMs:l.capturedAtMs};throw new d("COMMAND_FAILED",e.failureMessage,{cmd:"xcrun",args:s,exitCode:l.result.exitCode,stdout:l.result.stdout,stderr:l.result.stderr,appBundleId:r,deviceId:t.id,hint:rX(l.result.stdout,l.result.stderr)})}async function rF(e,t){let n;for(let a=1;a<=3;a+=1){a>1&&(await r.rm(t,{recursive:!0,force:!0}).catch(()=>{}),await new Promise(e=>setTimeout(e,1500)));let i=new Date().toISOString(),o=await p(e,{allowFailure:!0,timeoutMs:6e4});if(n={result:o,startedAt:i,endedAt:new Date().toISOString(),capturedAtMs:Date.now()},0===o.exitCode||!function(e){let t=`${e.stdout}
2
+ ${e.stderr}`.toLowerCase();return t.includes("_lockkperf")||t.includes("could not lock kperf")||t.includes("likely another session just started")}(o))break}return n}async function rC(e,t,n){let a=await r.stat(e.tracePath).catch(()=>null);if(!(a?.isDirectory()===!0?(await r.readdir(e.tracePath).catch(()=>[])).length>0:(a?.size??0)>0))throw new d("COMMAND_FAILED",`${e.failureMessage}: xctrace produced no trace data`,{tracePath:e.tracePath,appBundleId:e.appBundleId,deviceId:e.device.id,stdout:t,stderr:n,hint:"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf."})}async function rE(e,t,r,n,a){let i=["xctrace","export","--input",r,"--xpath",`/trace-toc/run/data/table[@schema="${n}"]`,"--output",a],o=await p(i,{allowFailure:!0,timeoutMs:15e3});if(0!==o.exitCode)throw new d("COMMAND_FAILED",`Failed to export iOS device ${n} data`,{cmd:"xcrun",args:i,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,appBundleId:t,deviceId:e.id,hint:rX(o.stdout,o.stderr)})}async function rV(e,t,r,n,a){try{return await rE(e,t,r,n,a),!0}catch{return!1}}async function rU(e){let t=eS(e),r=rA(t,"activity-monitor-process-live");if(0===r.length)throw new d("COMMAND_FAILED","Failed to parse xctrace activity-monitor-process-live schema");let n=r.indexOf("pid"),a=r.indexOf("process"),i=r.indexOf("cpu-total"),o=r.indexOf("memory-real");if(n<0||a<0||i<0||o<0)throw new d("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let s=rv(t,e=>"row"===e.name),l=[],u=new Map;for(let e of s){var c,p;let t=e.children;if(0===t.length)continue;for(let e of t){let t=ry(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:rb(e),processName:rJ(e)})}let r=rS(t[n],u),s=(c=t[a],p=u,c?c.attributes.ref?p.get(c.attributes.ref)?.processName??null:rJ(c):null);null!==r&&Number.isFinite(r)&&s&&l.push({pid:r,processName:s,cpuTimeNs:rS(t[i],u),residentMemoryBytes:rS(t[o],u)})}return l}async function rT(e,t){let r="macos"===e.platform?await rH(t):await rB(e,t),n="macos"===e.platform?a.join(r,"Contents","Info.plist"):a.join(r,"Info.plist"),i=await e2(n,"CFBundleExecutable");if(!i)throw new d("COMMAND_FAILED",`Failed to resolve executable for ${t}`,{appBundleId:t,appPath:r});return{executableName:i,executablePath:"macos"===e.platform?a.join(r,"Contents","MacOS",i):a.join(r,i)}}async function rG(e,t){let r=await rq(e,t),n=await rj(e,t),a=await rj(e,t),i=rK(await rU(n.xml),r,t,e),o=rK(await rU(a.xml),r,t,e),s=a.capturedAtMs-n.capturedAtMs;if(s<=0)throw new d("COMMAND_FAILED",`Invalid Activity Monitor sample window for ${t}`,{appBundleId:t,deviceId:e.id});if(null===i.cpuTimeNs||null===o.cpuTimeNs||null===o.residentMemoryBytes)throw new d("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 rz({usagePercent:Math.max(0,o.cpuTimeNs-i.cpuTimeNs)/(1e6*s)*100,residentMemoryKb:o.residentMemoryBytes/1024,measuredAt:new Date(a.capturedAtMs).toISOString(),matchedProcesses:o.matchedProcesses,cpuMethod:rD,memoryMethod:rO})}async function rq(e,t){let r=(await eN(e,"all")).find(e=>e.bundleId===t);if(!r)throw new d("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new d("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let n=r.url.replace(/\/$/,""),a=i(n),o=(await ek(e)).filter(e=>e.executable.startsWith(`${n}/`));if(0===o.length)throw new d("COMMAND_FAILED",`No running process found for ${t}`,{appBundleId:t,deviceId:e.id,appBundlePath:a,hint:"Run open <app> for this session again to ensure the iOS app is active, then retry perf."});return o}async function rj(e,t){let i=await r.mkdtemp(a.join(n.tmpdir(),"agent-device-ios-perf-")),o=a.join(i,"sample.trace"),s=a.join(i,"activity-monitor-process-live.xml");try{let n=await r$({device:e,appBundleId:t,tracePath:o,template:"Activity Monitor",duration:"1s",allProcesses:!0,failureMessage:`Failed to record iOS device Activity Monitor sample for ${t}`});return await rE(e,t,o,"activity-monitor-process-live",s),{capturedAtMs:n.capturedAtMs,xml:await r.readFile(s,"utf8")}}finally{await r.rm(i,{recursive:!0,force:!0}).catch(()=>{})}}function rK(e,t,r,n){let o=new Set(t.map(e=>e.pid)),s=new Set(t.map(e=>a.basename(i(e.executable)))),l=e.filter(e=>o.has(e.pid)||s.has(e.processName));if(0===l.length)throw new d("COMMAND_FAILED",`No Activity Monitor sample found for ${r}`,{appBundleId:r,deviceId:n.id,hint:"Keep the app running in the foreground while perf samples the device, then retry."});let u=new Map;for(let e of l){let t=u.get(e.pid);if(!t){u.set(e.pid,e);continue}u.set(e.pid,{pid:e.pid,processName:e.processName||t.processName,cpuTimeNs:rY(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:rY(t.residentMemoryBytes,e.residentMemoryBytes)})}let c=[...u.values()],p=c.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=c.map(e=>e.residentMemoryBytes).filter(e=>null!==e);return{cpuTimeNs:p.length>0?p.reduce((e,t)=>e+t,0):null,residentMemoryBytes:f.length>0?f.reduce((e,t)=>e+t,0):null,matchedProcesses:E(c.map(e=>e.processName))}}async function rH(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await e_("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new d("COMMAND_FAILED",`Failed to resolve macOS app bundle for ${e}`,{appBundleId:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let n=r.stdout.split("\n").map(e=>e.trim()).find(e=>e.endsWith(".app"));if(!n)throw new d("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return n}async function rB(e,t){let r=ev(e,["get_app_container",e.id,t,"app"]),n=await p(r,{allowFailure:!0,timeoutMs:15e3});if(0!==n.exitCode)throw new d("COMMAND_FAILED",`Failed to resolve iOS simulator app container for ${t}`,{appBundleId:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:"Ensure the iOS simulator app is installed and booted, then retry perf."});let a=n.stdout.trim();if(0===a.length)throw new d("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return a}async function rW(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:ev(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of eq(e)){let e=r.match(/^(\d+)\s+([0-9]+(?:\.[0-9]+)?)\s+(\d+)\s+(.+)$/);if(!e)continue;let[n,a,i,o]=e.slice(1);if(void 0===n||void 0===a||void 0===i||void 0===o)continue;let s=Number(n),l=Number(a),u=Number(i),c=o.trim();Number.isFinite(s)&&Number.isFinite(l)&&Number.isFinite(u)&&t.push({pid:s,cpuPercent:l,rssKb:u,command:c})}return t})(("macos"===e.platform?await e_("ps",r,{timeoutMs:15e3}):await p(r,{timeoutMs:15e3})).stdout).filter(e=>{var r,n;let i;return r=e.command,n=t,i=function(e){let[t=""]=e.trim().split(/\s+/,1);return t}(r),!!(n.executablePath&&(r===n.executablePath||i===n.executablePath||r.startsWith(`${n.executablePath} `)))||a.basename(i)===n.executableName})}function rz(e){return{cpu:{usagePercent:tG(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 rJ(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function rX(e,t){let r=O(e,t);if(r)return r;let n=`${e}
3
+ ${t}`.toLowerCase();return n.includes("no device matched")||n.includes("failed to find device")?Q:n.includes("timed out")?"Keep the iOS device unlocked and connected by cable, keep the app active, then retry perf.":"Ensure the iOS device is unlocked, trusted, visible to xctrace, and the target app stays active while perf samples it."}function rY(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function rZ(e,t={}){var r,n,a;let i,o,s,l,u=(s=(o=(i=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===tC&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:tC,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}((r=e).actions)).at(-1))?{available:!0,lastDurationMs:o.durationMs,lastMeasuredAt:o.measuredAt,method:tC,sampleCount:i.length,samples:i}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:tC},{session:r.name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{startup:s,fps:{available:!1,reason:"Dropped-frame sampling is currently available only on Android."},memory:{available:!1,reason:tE},cpu:{available:!1,reason:tE}},sampling:{startup:{method:tC,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:tY,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:tX,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:tj,description:"Rendered-frame health from the current adb shell dumpsys gfxinfo <package> framestats window. Dropped frames use Android gfxinfo janky-frame/frame-deadline data when available; this is not video recording FPS.",unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}};var t=e.device;let r="ios"===t.platform&&"device"===t.kind?{method:rI,description:"Rendered-frame hitch health from xctrace Animation Hitches on connected iOS devices. Dropped frames are counted from native hitch rows for the attached app process, with total frames from the same trace frame-lifetime table.",unit:"percent",primaryField:"droppedFramePercent",window:"short 2s xctrace Animation Hitches record of the active app process",resetsAfterRead:!1}:{method:rI,description:"Unavailable on iOS simulators and macOS because local Apple tooling does not expose reliable app frame hitches for these targets.",unit:"percent",primaryField:"droppedFramePercent"};if("ios"===t.platform&&"device"===t.kind)return{fps:r,memory:{method:rO,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:rD,description:"Recent CPU usage snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"percent"}};let n="macos"===t.platform?"host ps for the running macOS app executable resolved from the bundle ID.":"xcrun simctl spawn ps for the running iOS simulator app executable resolved from the bundle ID.";return{fps:r,memory:{method:rk,description:`Resident memory snapshot from ${n}`,unit:"kB"},cpu:{method:rx,description:`Recent CPU usage snapshot from ${n}`,unit:"percent"}}}(r)}});return"android"!==(n=e).device.platform&&"ios"!==n.device.platform&&"macos"!==n.device.platform||(e.appBundleId?"android"===e.device.platform?await rQ(u,e,t):await r0(u,e):(a=u,l="android"===e.device.platform?"No Android app package is associated with this session. Run open <app> first.":"No Apple app bundle ID is associated with this session. Run open <app> first.",a.metrics.fps={available:!1,reason:l},a.metrics.memory={available:!1,reason:l},a.metrics.cpu={available:!1,reason:l})),u}async function rQ(e,t,r){let n=await r1(t,r);e.metrics.memory=r5(n.memory),e.metrics.cpu=r5(n.cpu),e.metrics.fps=r6(r5(n.fps),t)}async function r0(e,t){let r=await r2(t);e.metrics.memory=r5(r.memory),e.metrics.cpu=r5(r.cpu),e.metrics.fps=r6(r5(r.fps),t)}async function r1(e,t){let r=e.appBundleId,n={adb:t.androidAdb},[a,i,o]=await Promise.allSettled([tQ(e.device,r,n),tZ(e.device,r,n),tz(e.device,r,n)]);return{memory:a,cpu:i,fps:o}}async function r2(e){let t=e.appBundleId,r=await r3(rL(e.device,t)),n=await r3(rR(e.device,t));if("fulfilled"===n.status){let e=n.value;return{memory:{status:"fulfilled",value:e.memory},cpu:{status:"fulfilled",value:e.cpu},fps:r}}return{memory:{status:"rejected",reason:n.reason},cpu:{status:"rejected",reason:n.reason},fps:r}}async function r3(e){try{return{status:"fulfilled",value:await e}}catch(e){return{status:"rejected",reason:e}}}function r5(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=c(e.reason);return{available:!1,reason:t.message,error:t}}function r6(e,t){var r,n;let a,i;if(!0!==e.available)return e;let o=(r=t.actions,a=r8((n=e).windowStartedAt),i=r8(n.windowEndedAt)??r8(n.measuredAt),void 0===a||void 0===i?[]:r.filter(e=>e.ts>=a&&e.ts<=i).map(e=>({command:e.command,at:new Date(e.ts).toISOString(),offsetMs:Math.max(0,Math.round(e.ts-a)),target:function(e){let t=e.result;if(t)for(let e of["refLabel","ref","appName","appBundleId"]){let r=t[e];if("string"==typeof r&&r.length>0)return r}}(e)})).slice(-12));return 0===o.length?e:{...e,relatedActions:o}}function r8(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let r9=["path","start","stop","doctor","mark","clear"],r4=`logs requires ${r9.slice(0,-1).join(", ")}, or ${r9.at(-1)}`,r7=["dump","log"],ne=`network requires ${r7.join(" or ")}`,nt=["summary","headers","body","all"],nr=`network include mode must be one of: ${nt.join(", ")}`;async function nn(e){let{req:t}=e;return"perf"===t.command?na(e):"logs"===t.command?ni(e):"network"===t.command?nc(e):null}async function na(e){let{sessionName:t,sessionStore:r,androidAdbExecutor:n}=e,a=r.get(t);if(!a)return L("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await rZ(a,{androidAdb:n})}}catch(e){return{ok:!1,error:c(e)}}}async function ni(e){var t,r,n;let a,i,{req:o,sessionName:s,sessionStore:l}=e,u=l.get(s);if(!u)return L("SESSION_NOT_FOUND","logs requires an active session");if(!eM("logs",u.device))return L("UNSUPPORTED_OPERATION","logs is not supported on this device");let c=(o.positionals?.[0]??"path").toLowerCase(),d=!!o.flags?.restart;return r9.includes(c)?d&&"clear"!==c?L("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===c?function(e,t,r){let n=r.resolveAppLogPath(t),a=T(n);return{ok:!0,data:{path:n,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:e.appLog?e.appLog.backend:"macos"===e.device.platform?"macos":"ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android",sizeBytes:a.sizeBytes,modifiedAt:a.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}(u,s,l):"doctor"===c?no(u,s,l):"mark"===c?(t=o,r=s,n=l,a=t.positionals?.slice(1).join(" ")??"",g(i=n.resolveAppLogPath(r),a),{ok:!0,data:{path:i,marked:!0}}):"clear"===c?ns(u,s,l,d):"start"===c?nl(u,s,l):"stop"===c?nu(u,s,l):L("INVALID_ARGS",r4):L("INVALID_ARGS",r4)}async function no(e,t,r){let n=r.resolveAppLogPath(t),a=await eu(e.device,e.appBundleId);return{ok:!0,data:{path:n,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:a.checks,notes:a.notes}}}async function ns(e,t,r,n){if(e.appLog&&!n)return L("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(n&&!e.appBundleId)return L("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let a=r.resolveAppLogPath(t);if(!n)return{ok:!0,data:z(a)};e.appLog&&await ef(e.appLog);let i=z(a),o=r.resolveAppLogPidPath(t);try{let n=await eL(e.device,e.appBundleId,a,o);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:a,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}}),{ok:!0,data:{...i,restarted:!0}}}catch(n){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:c(n)}}}async function nl(e,t,r){if(e.appLog)return L("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return L("INVALID_ARGS","logs start requires an app session; run open <app> first");let n=r.resolveAppLogPath(t),a=r.resolveAppLogPidPath(t);try{let i=await eL(e.device,e.appBundleId,n,a);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:n,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}}),{ok:!0,data:{path:n,started:!0}}}catch(e){return{ok:!1,error:c(e)}}}async function nu(e,t,r){if(!e.appLog)return L("INVALID_ARGS","no app log stream active");let n=e.appLog.outPath;return await ef(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:n,stopped:!0}}}async function nc(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return L("SESSION_NOT_FOUND","network requires an active session");if(!eM("network",a.device))return L("UNSUPPORTED_OPERATION","network is not supported on this device");let i=(t.positionals?.[0]??"dump").toLowerCase();if(!r7.includes(i))return L("INVALID_ARGS",ne);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return L("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 L("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let n=(r??t??"summary").toLowerCase();return nt.includes(n)?{ok:!0,include:n}:L("INVALID_ARGS",nr)}(t);if(!s.ok)return s;let{include:l}=s,u=await X({device:a.device,appBundleId:a.appBundleId,appLogState:a.appLog?.getState(),appLogStartedAt:a.appLog?.startedAt,appLogPath:n.resolveAppLogPath(r),maxEntries:o,include:l,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...u.dump,active:!!a.appLog,state:a.appLog?.getState()??"inactive",backend:u.backend,notes:u.notes}}}let nd=/^[A-Z_][A-Z0-9_]*$/,np=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,nf="AD_VAR_";function nm(e){return e.startsWith("AD_")}function nh(e){return new d("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function nw(e){let t={};for(let[r,n]of Object.entries(e)){if("string"!=typeof n||!r.startsWith(nf))continue;let e=r.slice(nf.length);0!==e.length&&nd.test(e)&&(nm(e)||(t[e]=n))}return t}function ng(e){let t={};for(let r of e){let e=r.indexOf("=");if(e<=0)throw new d("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let n=r.slice(0,e);if(!nd.test(n))throw new d("INVALID_ARGS",`Invalid -e key "${n}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(nm(n))throw nh(n);t[n]=r.slice(e+1)}return t}function ny(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function nv(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[r,n]of Object.entries(e))"string"==typeof n&&(t[r]=n);return t}return process.env}function nA(e,t,r){return e.replace(np,(e,n,a,i)=>{if(n)return"${";if(!a)return e;if(Object.prototype.hasOwnProperty.call(t.values,a))return String(t.values[a]);if(void 0!==i)return i.replace(/\\(.)/g,"$1");throw new d("INVALID_ARGS",`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function nb(e,t,r){return e?function e(t,r,n){return"string"==typeof t?nA(t,r,n):Array.isArray(t)?t.map(t=>e(t,r,n)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,a])=>[t,e(a,r,n)])):t}(e,t,r):e}let nS=new Set(["ios","android","macos","linux"]),nI=new Set(["mobile","tv","desktop"]);function n_(e){let t=e.split(/\r?\n/),r={};for(let[e,n]of t.entries()){let t=n.trim();if(0===t.length||t.startsWith("#"))continue;if(nN(t)){!function(e,t,r){let{key:n,value:a}=function(e,t){let r=e.slice(3).replace(/^[\s]+/,""),n=r.indexOf("=");if(n<=0)throw new d("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let a=r.slice(0,n);if(!nd.test(a))throw new d("INVALID_ARGS",`Invalid env key "${a}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(a.startsWith("AD_"))throw new d("INVALID_ARGS",`Invalid env key "${a}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${a} to avoid the AD_ prefix.`);return{key:a,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new d("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(r.slice(n+1),t)}}(t,r),i=e.env??{};if(Object.prototype.hasOwnProperty.call(i,n))throw new d("INVALID_ARGS",`Duplicate env directive "${n}" on line ${r}.`);i[n]=a,e.env=i}(r,t,e+1);continue}if(!t.startsWith("context "))break;let a=t.match(/(?:^|\s)platform=([^\s]+)/);if(a){let e=a[1];e&&nS.has(e)&&nM(r,"platform",e)}let i=t.match(/(?:^|\s)target=([^\s]+)/);if(i){let e=i[1];e&&nI.has(e)&&nM(r,"target",e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&nM(r,"timeoutMs",Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&nM(r,"retries",Math.floor(e))}}return r}function nN(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function nM(e,t,r){let n=e[t];if(void 0!==n)throw new d("INVALID_ARGS",n===r?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(n)} vs ${String(r)}.`);e[t]=r}function nx(e){return!!e&&!Number.isNaN(Number(e))}function nk(e,t=[],r){return{ts:Date.now(),command:e,positionals:t,flags:r??{}}}function nD(e,t,r){let n=new Set(r),a=Object.keys(e).filter(e=>!n.has(e));if(a.length>0)throw nV(`Maestro ${t} field "${a[0]}" is not supported yet.`)}function nO(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function nR(e){return e.map((e,t)=>{if("string"==typeof e||nO(e))return e;throw new d("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function nL(e,t){if(null==e)return{};if(!nO(e))throw new d("INVALID_ARGS",`${t} expects a map.`);let r={};for(let[t,n]of Object.entries(e))("string"==typeof n||"number"==typeof n||"boolean"==typeof n)&&(r[t]=String(n));return r}function nP(e,t){return nO(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function n$(e,t){if(e.appId)return e.appId;throw new d("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function nF(e,t){if("string"==typeof t)return t;throw new d("INVALID_ARGS",`${e} expects a string value.`)}function nC(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,r)=>Object.prototype.hasOwnProperty.call(t.env,r)?String(t.env[r]):e)}function nE(e){throw nV(`Maestro command "${e}" is not supported yet.`)}function nV(e){throw new d("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${eU}. If this syntax matters for your flows, comment there or open a focused issue at ${eT}.`)}function nU(e,t,r){var n,a;if(null==e)return nk("open",[nC(n$(t,"launchApp"),r)]);if("string"==typeof e)return nk("open",[nC(e,r)]);if(!nO(e))throw new d("INVALID_ARGS","launchApp expects a string or map.");nD(e,"launchApp",["appId","stopApp","clearState","clearKeychain","arguments","permissions","launchArguments"]),nj(e,"permissions"),nj(e,"clearKeychain");let i=nC("string"==typeof e.appId?e.appId:n$(t,"launchApp"),r),o=(n=e,a=r,[...nG(n.arguments,"launchApp.arguments",a),...nG(n.launchArguments,"launchApp.launchArguments",a)]),s=!0===e.clearState;return nk("open",[i],{...!s&&(!0===e.stopApp||o.length>0)?{relaunch:!0}:{},...s?{clearAppState:!0}:{},...o.length>0?{launchArgs:o}:{}})}function nT(e,t,r){if(null==e)return nk("close",[nC(n$(t,"stopApp"),r)]);if("string"==typeof e)return nk("close",[nC(e,r)]);throw new d("INVALID_ARGS","stopApp expects a string appId or no value.")}function nG(e,t,r){if(null==e)return[];if("string"==typeof e)return[nC(e,r)];if(Array.isArray(e))return e.map((e,n)=>nq(e,`${t}[${n}]`,r));if(nO(e))return Object.entries(e).flatMap(([e,n])=>[nC(e,r),nq(n,`${t}.${e}`,r)]);throw new d("INVALID_ARGS",`${t} expects a string, list, or map.`)}function nq(e,t,r){if("string"==typeof e)return nC(e,r);if("number"==typeof e||"boolean"==typeof e)return String(e);throw new d("INVALID_ARGS",`${t} must be a string, number, or boolean.`)}function nj(e,t){if(void 0!==e[t])throw nV(`Maestro launchApp field "${t}" is not supported yet.`)}function nK(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw nV('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function nH(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:"absolute",x:Number(t[1]),y:Number(t[2])};let r=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(r)return{kind:"percent",x:Number(r[1]),y:Number(r[2])};throw nV('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}let nB="__maestroRunScript",nW="__maestroAssertVisible",nz="__maestroAssertNotVisible",nJ="__maestroPressEnter",nX="__maestroWaitForAnimationToEnd",nY="__maestroScrollUntilVisible",nZ="__maestroSwipeScreen",nQ="__maestroSwipeOn",n0="__maestroTapOn",n1="__maestroTapPointPercent";function n2(e){if(null==e)return nk("type",["\b".repeat(50)]);if("number"==typeof e&&Number.isInteger(e)&&e>0)return nk("type",["\b".repeat(e)]);if(!nO(e))throw new d("INVALID_ARGS","eraseText expects empty, a positive count, or a map.");if(nD(e,"eraseText",["charactersToErase"]),void 0===e.charactersToErase)return nk("type",["\b".repeat(50)]);if("number"!=typeof e.charactersToErase||!Number.isInteger(e.charactersToErase)||e.charactersToErase<=0)throw new d("INVALID_ARGS","eraseText.charactersToErase must be a positive integer.");return nk("type",["\b".repeat(e.charactersToErase)])}function n3(e){return"number"==typeof e&&Number.isFinite(e)?String(Math.max(16,Math.floor(e))):void 0}function n5(e,t){let r=e.toLowerCase();switch(r){case"up":case"down":case"left":case"right":return r;default:throw nV(`Maestro ${t} must be UP, DOWN, LEFT, or RIGHT.`)}}function n6(e){return n5(e,"swipe direction")}function n8(e,t,r=[],n){if("string"==typeof e)return n9(nC(e,n));if(!nO(e))throw new d("INVALID_ARGS",`${t} expects a string or selector map.`);nD(e,t,["id","text","enabled","selected",...r]);let a=[],i=[];if("boolean"==typeof e.enabled&&i.push(n7("enabled",String(e.enabled))),"boolean"==typeof e.selected&&i.push(n7("selected",String(e.selected))),"string"==typeof e.id&&a.push(n7("id",nC(e.id,n)),...i),"string"==typeof e.text&&0===a.length)return n9(nC(e.text,n),i);if("string"==typeof e.label&&0===a.length&&a.push(n7("label",nC(e.label,n)),...i),0===a.length&&i.length>0&&a.push(...i),0===a.length)throw new d("INVALID_ARGS",`${t} selector map must include one of id, text, label, enabled, or selected.`);return a.join(" ")}function n9(e,t=[]){return[[n7("label",e),...t].join(" "),[n7("text",e),...t].join(" "),[n7("id",e),...t].join(" ")].join(" || ")}function n4(e){let t=n3(e.duration);return t?[t]:[]}function n7(e,t){return`${e}=${JSON.stringify(t)}`}function ae(e){var t,r;if(!nO(e))return;let n={},a="number"==typeof(t=e.repeat)&&Number.isInteger(t)&&t>0?t:void 0,i="number"==typeof(r=e.delay)&&Number.isInteger(r)&&r>=0?r:void 0;return a&&a>1&&(n.count=a),void 0!==i&&(n.intervalMs=i),!0===e.optional&&(n.maestro={optional:!0}),Object.keys(n).length>0?n:void 0}function at(e){let t=ae(e)??{};return{...t,maestro:{...t.maestro??{},allowNonHittableCoordinateFallback:!0}}}function ar(e){let t={doubleTap:!0};return nO(e)&&"number"==typeof e.delay&&Number.isInteger(e.delay)&&(t.intervalMs=Math.max(0,e.delay)),t}class an{index=0;tokens;context;constructor(e,t){this.tokens=e,this.context=t}parse(){let e=this.parseOr();if(this.peek())throw new d("INVALID_ARGS","Unsupported trailing runFlow.when.true expression.");return e}parseOr(){let e=this.parseAnd();for(;this.consumeOperator("||");)e=this.parseAnd()||e;return e}parseAnd(){let e=this.parsePrimary();for(;this.consumeOperator("&&");)e=this.parsePrimary()&&e;return e}parsePrimary(){let e=this.peek();if(!e)throw new d("INVALID_ARGS","Incomplete runFlow.when.true expression.");if("boolean"===e.type)return this.index+=1,e.value;if("paren"===e.type&&"("===e.value){this.index+=1;let e=this.parseOr();if(!this.consumeParen(")"))throw new d("INVALID_ARGS","Unclosed runFlow.when.true parenthesis.");return e}return this.parsePlatformComparison()}parsePlatformComparison(){this.expectPlatform();let e=this.expectEqualityOperator(),t=this.expectString().toLowerCase(),r=this.context.platform;return"=="===e?r===t:r!==t}expectPlatform(){if(this.peek()?.type!=="platform")throw new d("INVALID_ARGS","runFlow.when.true supports maestro.platform comparisons.");this.index+=1}expectEqualityOperator(){let e=this.peek();if(e?.type==="operator"&&("=="===e.value||"!="===e.value))return this.index+=1,e.value;throw new d("INVALID_ARGS","runFlow.when.true comparison requires == or !=.")}expectString(){let e=this.peek();if(e?.type==="string")return this.index+=1,e.value;throw new d("INVALID_ARGS","runFlow.when.true comparison requires a string literal.")}consumeOperator(e){let t=this.peek();return t?.type==="operator"&&t.value===e&&(this.index+=1,!0)}consumeParen(e){let t=this.peek();return t?.type==="paren"&&t.value===e&&(this.index+=1,!0)}peek(){return this.tokens[this.index]}}function aa(e,t,r){return{...nk(e,t),replayControl:r}}function ai(e,t,r){let n="string"==typeof e?nC(e,t):e,a="number"==typeof n?n:"string"==typeof n&&/^\d+$/.test(n)?Number(n):void 0;if(void 0===a||!Number.isInteger(a)||a<0)throw new d("INVALID_ARGS",`${r} must be a non-negative integer or \${VAR} resolving to one.`);return a}let ao=`
4
4
  const fs = require('node:fs');
5
5
  const input = JSON.parse(fs.readFileSync(0, 'utf8'));
6
6
  if (typeof fetch !== 'function') {
@@ -21,9 +21,9 @@ fetch(input.url, {
21
21
  console.error(error && error.stack ? error.stack : String(error));
22
22
  process.exit(1);
23
23
  });
24
- `;function at(e){if("string"!=typeof e)throw new d("COMMAND_FAILED",`Maestro runScript json() expected a string body, received ${typeof e}.`);if(0===e.trim().length)throw new d("COMMAND_FAILED","Maestro runScript json() received an empty body. Check the preceding http response status and setup server output.");try{return JSON.parse(e,ar)}catch(t){throw new d("COMMAND_FAILED",`Maestro runScript json() could not parse response body: ${t instanceof Error?t.message:String(t)}`,{bodyPreview:e.slice(0,1e3)},t instanceof Error?t:void 0)}}function ar(e,t){return"__proto__"===e||"constructor"===e||"prototype"===e?void 0:t}let an={launchApp:({value:e,config:t,context:r})=>[nP(e,t,r)],tapOn:({value:e,context:t})=>[function(e,t){if("string"==typeof e)return nS(nz,[n1(nO(e,t))],n6(e));if(n_(e)&&"string"==typeof e.point){nI(e,"tapOn",["point","repeat","delay","optional","label"]);let t=nU(e.point);return"percent"===t.kind?nS(nJ,[String(t.x),String(t.y)],n5(e)):nS("click",[String(t.x),String(t.y)],n5(e))}n_(e)&&nI(e,"tapOn",["id","text","childOf","enabled","index","selected","repeat","delay","optional","label"]);let r=n6(e);return nS(nz,[n0(e,"tapOn",["repeat","delay","optional","label","index","childOf"],t),...function(e,t){if(!n_(e))return[];let r={};if(void 0!==e.index){if("number"!=typeof e.index||!Number.isInteger(e.index)||e.index<0)throw new d("INVALID_ARGS","tapOn.index must be a non-negative integer.");r.index=e.index}return void 0!==e.childOf&&(r.childOf=n0(e.childOf,"tapOn.childOf",[],t)),Object.keys(r).length>0?[JSON.stringify(r)]:[]}(e,t)],r)}(e,t)],doubleTapOn:({value:e,context:t})=>[function(e,t){if(n_(e)&&"string"==typeof e.point){nI(e,"doubleTapOn",["point","delay"]);let t=nV(e.point);return nS("click",[String(t.x),String(t.y)],n8(e))}return n_(e)&&nI(e,"doubleTapOn",["id","text","enabled","selected","delay"]),nS("click",[n0(e,"doubleTapOn",["delay"],t)],n8(e))}(e,t)],longPressOn:({value:e,context:t})=>[function(e,t){if(n_(e)&&"string"==typeof e.point){nI(e,"longPressOn",["point"]);let t=nV(e.point);return nS("longpress",[String(t.x),String(t.y),"3000"])}return n_(e)&&nI(e,"longPressOn",["id","text","enabled","selected"]),nS("click",[n0(e,"longPressOn",[],t)],{holdMs:3e3})}(e,t)],inputText:({value:e,context:t})=>[nS("type",[nO(function(e){if("string"==typeof e)return e;if(!n_(e))throw new d("INVALID_ARGS","inputText expects a string or map.");if(nI(e,"inputText",["text","label"]),"string"!=typeof e.text)throw new d("INVALID_ARGS","inputText map requires a string text field.");return e.text}(e),t)])],eraseText:({value:e})=>[nX(e)],pasteText:({value:e,context:t,name:r})=>[nS("type",[nO(nk(r,e),t)])],openLink:({value:e,config:t,context:r,name:n})=>{var a,i,o,s,l,u;let c;return[(a=e,i=t,o=r,s=n,c=nO((l=a,u=s,"string"==typeof l?l:n_(l)?(nI(l,u,["link"]),nk(`${u}.link`,l.link)):nk(u,l)),o),("ios"===o.platform||"android"===o.platform)&&i.appId?nS("open",[nO(nD(i,s),o),c],"ios"===o.platform?{maestro:{prewarmRunnerBeforeOpen:!0}}:void 0):nS("open",[c]))]},assertVisible:({value:e,context:t,name:r})=>[nS(nG,[n0(e,r,[],t),"7000"])],assertNotVisible:({value:e,context:t,name:r})=>[nS(nj,[n0(e,r,[],t)])],extendedWaitUntil:({value:e,context:t})=>(function(e,t){if(!n_(e))throw new d("INVALID_ARGS","extendedWaitUntil expects a map.");nI(e,"extendedWaitUntil",["visible","notVisible","timeout"]);let r=e.visible??e.notVisible;if(void 0===r)throw nL("Only Maestro extendedWaitUntil.visible/notVisible is supported.");let n=n0(r,"extendedWaitUntil",[],t),a=String(nx(e,3e4));return void 0!==e.notVisible?[nS(nj,[n,a])]:[nS(nG,[n,a],{maestro:{allowAlreadyPastLoading:!0}})]})(e,t),takeScreenshot:({value:e,context:t,name:r})=>[nS("screenshot",[nO(nk(r,e),t)])],scroll:({value:e})=>[function(e){if(null!=e)throw nL("Maestro scroll options are not supported yet.");return nS("scroll",["down"])}(e)],scrollUntilVisible:({value:e,context:t})=>(function(e,t){if("string"==typeof e)return[nS(nB,[n1(nO(e,t)),"5000","down"])];if(!n_(e))throw new d("INVALID_ARGS","scrollUntilVisible expects a string or map.");nI(e,"scrollUntilVisible",["element","direction","timeout"]);let r=n0(e.element,"scrollUntilVisible.element",[],t),n="string"==typeof e.direction?nZ(e.direction,"scrollUntilVisible.direction"):"down";return[nS(nB,[r,String(nx(e,5e3)),n])]})(e,t),swipe:({value:e,context:t})=>[function(e,t){var r,n,a;let i;if(!n_(e))throw new d("INVALID_ARGS","swipe expects a map.");nI(e,"swipe",["start","end","direction","duration","from","label"]);let o=e.from??("string"==typeof e.label?e.label:void 0);return void 0!==o?(r=e,n=o,a=t,i=nQ("string"==typeof r.direction?r.direction:"up"),nS(nW,[n0(n,"swipe.from",[],a),i,...n2(r)])):"string"==typeof e.direction?nS(nH,["direction",nQ(e.direction),...n2(e)]):function(e){let{start:t,end:r}=function(e){if("string"==typeof e.start&&"string"==typeof e.end)return{start:nU(e.start),end:nU(e.end)};throw nL("Only Maestro swipe start/end coordinates are supported.")}(e);var n=t,a=r,i=nY(e.duration);if("absolute"===n.kind&&"absolute"===a.kind)return nS("swipe",[String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);if("percent"===n.kind&&"percent"===a.kind)return nS(nH,["percent",String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);throw nL("Maestro swipe start/end must both be absolute pixels or both be percentages.")}(e)}(e,t)],hideKeyboard:()=>[nS("keyboard",["dismiss"])],pressKey:({value:e})=>[function(e){let t=nk("pressKey",e).toLowerCase();if("back"===t)return nS("back");if("enter"===t||"return"===t)return nS(nq);if("home"===t)return nS("home");throw nL(`Maestro pressKey "${t}" is not supported yet.`)}(e)],back:()=>[nS("back")],waitForAnimationToEnd:({value:e})=>[nS(nK,[String(nx(e,15e3))])],stopApp:({value:e,config:t,context:r})=>[n$(e,t,r)],runScript:({value:e,context:t})=>{let r;return[nS(nT,[function(e,t){if(a.isAbsolute(e))return e;if(!t.baseDir)throw new d("INVALID_ARGS","runScript file paths require replay input to have a source path.");return a.resolve(t.baseDir,e)}((r=function(e,t){if("string"==typeof e)return{file:nO(e,t),env:{}};if(!n_(e))throw new d("INVALID_ARGS","runScript expects a file path string or map.");return nI(e,"runScript",["file","env"]),{file:nO(nk("runScript.file",e.file),t),env:Object.fromEntries(Object.entries(nM(e.env,"runScript.env")).map(([e,r])=>[e,nO(r,t)]))}}(e,t)).file,t)],{...Object.keys(r.env).length>0?{maestro:{runScriptEnv:r.env}}:{}})]},runFlow:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){if("string"==typeof e)return n.parseRunFlowFile(nO(e,r),r).actions;if(!n_(e))throw new d("INVALID_ARGS","runFlow expects a file path string or map.");nI(e,"runFlow",["file","commands","env","when","label"]);let i=function(e,t){var r,n;if(null==e)return{shouldRun:!0};if(!n_(e))throw new d("INVALID_ARGS","runFlow.when expects a map.");return(nI(e,"runFlow.when",["platform","visible","notVisible","true"]),!function(e,t){if(void 0!==e.true&&!function(e,t){let r;if("boolean"==typeof e)return e;if("string"!=typeof e)throw new d("INVALID_ARGS","runFlow.when.true expects a boolean or expression string.");return new n9(function(e){let t=[],r=0;for(;r<e.length;){var n,a;let i=e.slice(r),o=(n=i,/^\s+/.exec(n)?.[0].length??0);if(o>0){r+=o;continue}let s=function(e){let t="maestro.platform";return e.startsWith(t)?{token:{type:"platform"},length:t.length}:null}(a=i)??function(e){let t=/^(==|!=|&&|\|\|)/.exec(e)?.[1];return t?{token:{type:"operator",value:t},length:t.length}:null}(a)??function(e){let t=e[0];return"("===t||")"===t?{token:{type:"paren",value:t},length:1}:null}(a)??function(e){let t=/^(['"])(.*?)\1/.exec(e);return t?{token:{type:"string",value:t[2]??""},length:t[0].length}:null}(a)??function(e){let t=/^(true|false)\b/.exec(e)?.[1];return t?{token:{type:"boolean",value:"true"===t},length:t.length}:null}(a);if(s){t.push(s.token),r+=s.length;continue}throw new d("INVALID_ARGS",`Unsupported runFlow.when.true expression near "${i.slice(0,24)}".`)}return t}((r=nO(e,t).trim()).startsWith("${")&&r.endsWith("}")?r.slice(2,-1).trim():r),{platform:t.platform}).parse()}(e.true,t))return!1;if(void 0===e.platform)return!0;let r=function(e,t){if("string"!=typeof e)throw new d("INVALID_ARGS",`${t} expects Android, iOS, or Web.`);let r=e.trim().toLowerCase();if("android"===r||"ios"===r||"web"===r)return r;throw new d("INVALID_ARGS",`${t} expects Android, iOS, or Web.`)}(e.platform,"runFlow.when.platform");if(!t.platform)throw new d("INVALID_ARGS","Maestro runFlow.when.platform requires replay to be run with --platform ios|android.");return r===t.platform}(e,t))?{shouldRun:!1}:{shouldRun:!0,...(r=e,n=t,{...void 0!==r.visible?{visibleSelector:n0(r.visible,"runFlow.when.visible",[],n)}:{},...void 0!==r.notVisible?{notVisibleSelector:n0(r.notVisible,"runFlow.when.notVisible",[],n)}:{}})}}(e.when,r);if(!i.shouldRun)return[];let o={...r,env:{...r.env,...nM(e.env,"runFlow.env"),...r.envOverrides}};return function(e,t){let{visibleSelector:r,notVisibleSelector:n}=t;if(!r&&!n)return e;if(r&&n)throw nL("Maestro runFlow.when cannot combine visible and notVisible yet.");let a=r?"visible":"notVisible",i=r??n??"";return[n4("runFlow.when",[a,i],{kind:"maestroRunFlowWhen",mode:a,selector:i,actions:e})]}(function(e,t,r,n,a){if("string"==typeof e.file)return n.parseRunFlowFile(nO(e.file,r),r).actions;if(Array.isArray(e.commands))return a(nN(e.commands),t,r,n);throw new d("INVALID_ARGS","runFlow map requires either file or commands.")}(e,t,o,n,a),i)})(e,t,r,n,ao),repeat:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i;if(!n_(e))throw new d("INVALID_ARGS","repeat expects a map.");if(nI(e,"repeat",["times","commands","while"]),void 0!==e.while)throw nL("Maestro repeat.while is not supported yet. Only deterministic repeat.times is supported.");let o=(i=e.times,n7(i,r,"repeat.times"));if(!Array.isArray(e.commands))throw new d("INVALID_ARGS","repeat requires a commands list.");if(o>1e3)throw new d("INVALID_ARGS","repeat.times must be <= 1000 for deterministic replay expansion.");let s=nN(e.commands);return Array.from({length:o}).flatMap(()=>a(s,t,r,n))})(e,t,r,n,ao),retry:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i,o;if(!n_(e))throw new d("INVALID_ARGS","retry expects a map.");if(nI(e,"retry",["maxRetries","commands"]),!Array.isArray(e.commands))throw new d("INVALID_ARGS","retry requires a commands list.");let s=(i=e.maxRetries,o=r,void 0===i?1:n7(i,o,"retry.maxRetries")),l=a(nN(e.commands),t,r,n);return[n4("retry",[String(s)],{kind:"retry",maxRetries:s,actions:l})]})(e,t,r,n,ao)},aa={launchApp:(e,t)=>[nP(void 0,e,t)],scroll:()=>[nS("scroll",["down"])],hideKeyboard:()=>[nS("keyboard",["dismiss"])],eraseText:()=>[nX(void 0)],back:()=>[nS("back")],waitForAnimationToEnd:()=>[nS(nK,["15000"])],stopApp:(e,t)=>[n$(void 0,e,t)]};function ai(e,t,r,n,a){try{return function(e,t,r,n){if("string"==typeof e){var a,i,o;let n;return a=e,i=t,o=r,(n=aa[a])?n(i,o):nR(a)}let s=Object.entries(e);if(1!==s.length)throw new d("INVALID_ARGS","Maestro command maps must contain exactly one command.");let[l,u]=s[0],c=an[l];return c?c({value:u,config:t,context:r,deps:n,name:l}):nR(l)}(e,t,n,a)}catch(e){if(e instanceof d&&!/\bline \d+\b/.test(e.message))throw new d(e.code,`${e.message} (line ${r})`,e.details);throw e}}function ao(e,t,r,n){return e.flatMap((e,a)=>ai(e,t,a+1,r,n))}function as(e,t){let{config:r,commands:n}=au(al(e)),a={...t,env:{...t.env,...r.env??{},...t.envOverrides}},{actions:i,actionLines:o}=function(e){let{config:t,commands:r,commandLines:n,context:a}=e,i=[...t.onFlowStart??[],...r,...t.onFlowComplete??[]],o=[...Array.from({length:t.onFlowStart?.length??0},()=>1),...n,...Array.from({length:t.onFlowComplete?.length??0},()=>n.at(-1)??1)],s=[],l=[];for(let[e,r]of i.entries()){let n=o[e]??e+1,i=ai(r,t,n,a,{parseRunFlowFile:ac});s.push(...i),i.forEach(()=>l.push(n))}return function(e,t){let r=[],n=[];for(let a=0;a<e.length;a+=1){let i=e[a],o=function(e,t,r){var n;let a=function(e,t,r){let n=e[r],a=e[r+1],i=e[r+2];if(i?.command!==nq||n.flags?.maestro?.optional===!0)return null;let o=function(e){if(e?.command!=="type"||e.flags&&Object.keys(e.flags).length>0)return null;let[t,...r]=e.positionals??[];return r.length>0||"string"!=typeof t?null:t}(a),s=function(e){if(e?.command!==nz)return null;let[t,...r]=e.positionals??[];return r.length>0||"string"!=typeof t?null:t}(n);return a&&null!==o&&null!==s?{action:n,nextAction:a,pressEnterAction:i,tapSelector:s,typedAfterTap:o,line:t[r]??1}:null}(e,t,r);if(!a)return null;let{action:i,nextAction:o,pressEnterAction:s,tapSelector:l,typedAfterTap:u,line:c}=a;return(n=l,/\b(input|textfield|textarea|field|email|password|username|search|query)\b/i.test(n.replace(/([a-z])([A-Z])/g,"$1 $2")))?{actions:[{...i,command:"wait",positionals:[l,"30000"]},{...o,command:"fill",positionals:[l,u],flags:i.flags},s],actionLines:[c,c,t[r+2]??c],consumed:3}:{actions:[function(e){let t={...e.flags?.maestro??{}};return delete t.allowNonHittableCoordinateFallback,{...e,flags:{...e.flags??{},maestro:{...t}}}}(i)],actionLines:[c],consumed:1}}(e,t,a);if(o){r.push(...o.actions),n.push(...o.actionLines),a+=o.consumed-1;continue}r.push(i),n.push(t[a]??1)}return{actions:r,actionLines:n}}(s,l)}({config:r,commands:n,commandLines:function(e){let t=e.split(/\r?\n/),r=t.findIndex(e=>"---"===e.trim()),n=-1===r?0:r+1,a=[];for(let e=n;e<t.length;e+=1)/^-\s+/.test(t[e]??"")&&a.push(e+1);return a}(e),context:a});return{actions:i,actionLines:o,metadata:{env:r.env}}}function al(e){let t=o(e);for(let e of t)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new d("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return t.map(e=>e.toJSON()).filter(e=>null!==e)}function au(e){if(0===e.length)throw new d("INVALID_ARGS","Maestro flow is empty.");if(Array.isArray(e[0]))return{config:{},commands:nN(e[0])};let t=function(e){if(!n_(e))throw new d("INVALID_ARGS","Maestro flow config must be a YAML map.");return{..."string"==typeof e.name&&e.name.length>0?{name:e.name}:{},..."string"==typeof e.appId&&e.appId.length>0?{appId:e.appId}:{},...n_(e.env)?{env:nM(e.env,"env")}:{},...Array.isArray(e.onFlowStart)?{onFlowStart:nN(e.onFlowStart)}:{},...Array.isArray(e.onFlowComplete)?{onFlowComplete:nN(e.onFlowComplete)}:{}}}(e[0]),r=e[1];if(!Array.isArray(r))throw new d("INVALID_ARGS","Maestro flow must contain a command list after the YAML document separator.");return{config:t,commands:nN(r)}}function ac(e,r){let n=function(e,t){if(a.isAbsolute(e))return e;if(!t.baseDir)throw new d("INVALID_ARGS","runFlow file paths require replay input to have a source path.");return a.resolve(t.baseDir,e)}(e,r);if(r.visitedPaths.has(n))throw new d("INVALID_ARGS",`Maestro runFlow cycle detected at ${n}.`);let i=t.readFileSync(n,"utf8"),o=new Set(r.visitedPaths);return o.add(n),as(i,{...r,baseDir:a.dirname(n),visitedPaths:o})}let ad=/[*?[\]{}]/;function ap(e){return"maestro"===e}let af=["failed to start daemon","runner did not accept connection","xcodebuild exited early","device is offline","device offline","device unauthorized"];function am(e){var t,r,n,a;let i,o,s="ok"in(t=e)?t.ok?null:t.error:"failed"===t.status?t.error:null;return!!s&&(r=s.details,"timeout_cleanup_pending"===(i="string"==typeof r?.reason?r.reason:"")||!!i&&eT(i)||(n=s.code,a=s.message,o=`${n}
25
- ${a}`.toLowerCase(),af.some(e=>o.includes(e))))}async function ah(e){let r,n,{filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:d,artifactsDir:p,runReplay:f,cleanupSession:m}=e;O(s);let h=new Set,w=!1,g=Date.now(),y=function(e){let{artifactsDir:r,artifactPaths:n,filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:c}=e;if(!r)return;let d=a.join(r,"replay-timing.ndjson");return t.mkdirSync(a.dirname(d),{recursive:!0}),t.writeFileSync(d,""),n.add(d),ay(d,{type:"replay_test_attempt_start",ts:new Date().toISOString(),replayPath:i,session:o,requestId:s,timeoutMs:l,platform:u,target:c}),d}({artifactsDir:p,artifactPaths:h,filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:d}),v=f({filePath:i,sessionName:o,platform:u,target:d,requestId:s,artifactsDir:p,artifactPaths:h,tracePath:y}).catch(e=>({ok:!1,error:c(e)})).finally(()=>{ep(s)});try{return n="number"==typeof l?await Promise.race([v,new Promise(e=>{r=setTimeout(()=>{w=!0,eu(s),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}}}}(l,[...h]))},l)})]):await v,ay(y,{type:"replay_test_attempt_stop",ts:new Date().toISOString(),session:o,ok:n.ok,timedOut:w,durationMs:Date.now()-g,errorCode:n.ok?void 0:n.error.code}),n}finally{var A;r&&clearTimeout(r),w&&(await aw(v)||((A=n)&&!A.ok&&(A.error.details={...A.error.details??{},reason:"timeout_cleanup_pending",timeoutCleanupPending:!0}),eQ({level:"warn",phase:"test_timeout_cleanup_race",data:{session:o,requestId:s,graceMs:2e3}}),ag({replayPromise:v,cleanupSession:m,sessionName:o,requestId:s})));let e=Date.now();try{ay(y,{type:"replay_test_cleanup_start",ts:new Date().toISOString(),session:o}),await m(o),ay(y,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!0,durationMs:Date.now()-e})}catch(r){let t=c(r);ay(y,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!1,durationMs:Date.now()-e,errorCode:t.code}),eQ({level:"warn",phase:"test_cleanup_failed",data:{session:o,error:t.message}})}}}async function aw(e){return await Promise.race([e.then(()=>!0),l(2e3).then(()=>!1)])}async function ag(e){let{replayPromise:t,cleanupSession:r,sessionName:n,requestId:a}=e;try{await t}finally{try{await r(n)}catch(e){eQ({level:"warn",phase:"test_late_cleanup_failed",data:{session:n,requestId:a,error:c(e).message}})}}}function ay(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
26
- `)}async function av(e){let{req:r,sessionName:n,runReplay:i,cleanupSession:o}=e;if((r.positionals?.length??0)===0)return R("INVALID_ARGS","test requires at least one path or glob");try{var s,l,c,p,f,m;let e,u,h,w,g,y=function(e){var r,n,i,o,s,l;let{inputs:u,cwd:c,platformFilter:p,replayBackend:f}=e,m=(r=f,new Set(ap(r)?[".ad",".yaml",".yml"]:[".ad"])),h=c??process.cwd(),w=[...new Set(u.flatMap(e=>(function(e,r,n){var i,o;let s=Q.expandHome(e,r);if(t.existsSync(s)){let r=t.statSync(s);if(r.isDirectory())return[...n].map(e=>`**/*${e}`).flatMap(e=>t.globSync(e,{cwd:s}).map(e=>a.join(s,e)));if(r.isFile()){if(!n.has(a.extname(s)))throw new d("INVALID_ARGS",`test does not support this file type: ${e}`);return[s]}return[]}if(i=e,!ad.test(i)&&(o=s,!ad.test(o)))throw new d("INVALID_ARGS",`test input not found: ${e}`);let l=a.isAbsolute(s)?s:e;return t.globSync(l,{cwd:a.isAbsolute(s)?void 0:r}).map(e=>a.isAbsolute(e)?e:a.resolve(r,e)).filter(e=>n.has(a.extname(e))&&function(e){try{return t.statSync(e).isFile()}catch{return!1}}(e))})(e,h,m)))].map(e=>a.normalize(e)).sort((e,t)=>e.localeCompare(t)),g=[];for(let e of w){let r=t.readFileSync(e,"utf8"),u=ny(r),c=(n=r,i=e,o=f,ap(o)&&".ad"!==a.extname(i)?function(e){let{config:t}=au(al(e));return t.name}(n):void 0);if(!p){g.push({kind:"run",path:e,title:c,metadata:u});continue}if(!u.platform){ap(f)?g.push({kind:"run",path:e,title:c,metadata:u}):g.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${p}`});continue}s=p,l=u.platform,("apple"===s?"apple"===l||"ios"===l||"macos"===l:l===s)&&g.push({kind:"run",path:e,title:c,metadata:u})}if(0===g.filter(e=>"run"===e.kind).length){let e=p?` for --platform ${p}`:"";throw new d("INVALID_ARGS",`No replay tests matched${e}.`)}return g}({inputs:r.positionals,cwd:r.meta?.cwd,platformFilter:r.flags?.platform,replayBackend:r.flags?.replayBackend}),v=(s=r.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),A=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:n}=e,i=Q.expandHome(t??".agent-device/test-artifacts",r);return a.join(i,n)}({artifactsDir:"string"==typeof r.flags?.artifactsDir?r.flags.artifactsDir:void 0,cwd:r.meta?.cwd,suiteInvocationId:v}),b=[],S=Date.now(),I=0;for(let[e,t]of y.entries()){if("skip"===t.kind){ex({type:"replay-test",file:t.path,status:"skip",index:e+1,total:y.length,message:t.message}),b.push({file:t.path,status:"skipped",durationMs:0,reason:t.reason,message:t.message});continue}I+=1;let a=await aA({entry:t,sessionName:n,suiteInvocationId:v,caseIndex:I-1,cwd:r.meta?.cwd,requestId:r.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))}(r.flags?.retries,t.metadata.retries),timeoutMs:(l=r.flags?.timeoutMs,c=t.metadata.timeoutMs,"number"==typeof l?l:c),suiteArtifactsDir:A,suiteIndex:e+1,suiteTotal:y.length,runReplay:i,cleanupSession:o});if(b.push(a),r.flags?.failFast===!0||am(a))break}let _=(p=y.length,f=b,m=Date.now()-S,e=f.filter(e=>"passed"===e.status).length,h=(u=f.filter(e=>"failed"===e.status)).length,w=f.filter(e=>"skipped"===e.status).length,g=e+h,{total:p,executed:g,passed:e,failed:h,skipped:w,notRun:Math.max(0,p-g-w),durationMs:m,failures:u,tests:f});return{ok:!0,data:_}}catch(t){let e=u(t);return R(e.code,e.message)}}async function aA(e){var r,n;let i,o,{entry:s,sessionName:l,suiteInvocationId:u,caseIndex:c,cwd:d,requestId:p,retries:f,timeoutMs:m,suiteArtifactsDir:h,suiteIndex:w,suiteTotal:g,runReplay:y,cleanupSession:v}=e,A=Date.now(),b=a.join(h,(r=s.path,(0===(o=d?a.relative(d,r):a.basename(r)).length||o.startsWith("..")?a.basename(r):o).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),S="",I=0,_=0,N=[];for(let e=0;e<=f;e+=1){I=e+1;let r=Date.now(),o=function(e,t,r,n,i=0){let o=a.basename(r,a.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${n+1}${o?`-${o}`:""}:attempt-${i+1}`}(l,u,s.path,c,e),d=a.join(b,`attempt-${I}`);n=s.path,t.mkdirSync(d,{recursive:!0}),function(e,r){let n=a.join(r,"replay.ad");if(t.copyFileSync(e,n),!function(e){let t=a.extname(e).toLowerCase();return".yml"===t||".yaml"===t}(e))return;let i=a.join(r,a.basename(e));a.resolve(i)!==a.resolve(n)&&t.copyFileSync(e,i)}(n,d);let h=function(e){let{requestId:t,suiteInvocationId:r,filePath:n,caseIndex:i,attemptIndex:o}=e;return en(`${t??r}:test:${i+1}:${a.basename(n)}:attempt:${o+1}`,r)}({requestId:p,suiteInvocationId:u,filePath:s.path,caseIndex:c,attemptIndex:e}),A=await ah({filePath:s.path,sessionName:o,requestId:h,timeoutMs:m,platform:s.metadata.platform,target:s.metadata.target,artifactsDir:d,runReplay:y,cleanupSession:v});if(_=Date.now()-r,!function(e){let{response:r,filePath:n,sessionName:i,attempts:o,maxAttempts:s,attemptArtifactsDir:l}=e,u=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(r)];r.ok||"string"!=typeof r.error.logPath||u.push(r.error.logPath);let c=function(e,r){let n=[],i=new Map;for(let o of e){if(!function(e){try{return t.statSync(e).isFile()}catch{return!1}}(o))continue;let e=function(e,t){let r=a.extname(e),n=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${n}-${i+1}${r}`}(a.basename(o),i),s=a.join(r,e);a.resolve(o)!==a.resolve(s)&&t.copyFileSync(o,s),n.push(s)}return n}(u,l),d=[`file: ${n}`,`session: ${i}`,`attempt: ${o}/${s}`,`status: ${r.ok?"passed":"failed"}`];if(r.ok){let e="number"==typeof r.data?.replayed?r.data.replayed:0,t="number"==typeof r.data?.healed?r.data.healed:0;d.push(`replayed: ${e}`,`healed: ${t}`)}else d.push(`code: ${r.error.code}`,`message: ${r.error.message}`),r.error.hint&&d.push(`hint: ${r.error.hint}`),r.error.diagnosticId&&d.push(`diagnosticId: ${r.error.diagnosticId}`),r.error.logPath&&d.push(`logPath: ${r.error.logPath}`),r.error.details?.reason==="timeout"&&d.push("timeoutMode: cooperative");c.length>0&&d.push(`copiedArtifacts: ${c.map(e=>a.basename(e)).join(", ")}`);let p=a.join(l,"result.txt"),f=`${d.join("\n")}
27
- `;t.writeFileSync(p,f),r.ok||t.writeFileSync(a.join(l,"failure.txt"),f)}({response:A,filePath:s.path,sessionName:o,attempts:I,maxAttempts:f+1,attemptArtifactsDir:d}),i=A,S=o,A.ok||(N.push({attempt:I,message:A.error.message,durationMs:_}),am(A)||e>=f))break;ex({type:"replay-test",file:s.path,title:s.title,status:"fail",index:w,total:g,attempt:I,maxAttempts:f+1,durationMs:_,retrying:!0,message:A.error.message})}let M=Date.now()-A;if(i?.ok)return ex({type:"replay-test",file:s.path,title:s.title,status:"pass",index:w,total:g,attempt:I,maxAttempts:f+1,durationMs:M,artifactsDir:b}),{file:s.path,title:s.title,session:S,status:"passed",durationMs:M,finalAttemptDurationMs:_,attempts:I,artifactsDir:b,replayed:"number"==typeof i.data?.replayed?i.data.replayed:0,healed:"number"==typeof i.data?.healed?i.data.healed:0,...N.length>0?{attemptFailures:N}:{}};let x=i?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:i?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return ex({type:"replay-test",file:s.path,title:s.title,status:"fail",index:w,total:g,attempt:I,maxAttempts:f+1,durationMs:M,artifactsDir:b,message:x.message}),{file:s.path,title:s.title,session:S,status:"failed",durationMs:M,attempts:I,artifactsDir:b,error:x}}let ab={maestro:{parse:function(e,t={}){var r;let n;return as(e,(n=(r=t).visitedPaths??new Set,r.sourcePath&&n.add(a.resolve(r.sourcePath)),{baseDir:r.sourcePath?a.dirname(r.sourcePath):void 0,platform:function(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}(r.platform),env:{},envOverrides:r.env??{},visitedPaths:n}))}}};function aS(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=void 0!==t&&/^\d+$/.test(t)?t:null,n=e0(null!==r?e.slice(0,-1):e.slice());return!n||n.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:n.selectorExpression,selectorTimeout:r}}async function aI(e){let{action:t,sessionName:r,logPath:n,sessionStore:a}=e;if(!(_(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let i=a.get(r);if(!i)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),_(e.command)){let r=function(e){let t=e.positionals??[];if("longpress"!==e.command)return t;let r=t.at(-1);return t.length>1&&a_(r)?t.slice(0,-1):t}(e),n=r[0]??"";n&&!n.startsWith("@")&&t.push(r.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}=e5(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=aS(e.positionals??[]);r&&t.push(r)}return C(t).filter(e=>e.trim().length>0)})(t).map(e=>e6(e)).filter(e=>null!==e);if(0===o.length)return null;let s=_(t.command)||"fill"===t.command,l=_(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await aN(i,t,n,s,a);for(let e of o){let r=e9(u.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let n=e4(r.node,i.device.platform,{action:"fill"===t.command?"fill":_(t.command)?"click":"get"}).join(" || ");if(_(t.command))return{...t,positionals:"longpress"===t.command?function(e,t){let r="number"==typeof e.result?.durationMs?String(e.result.durationMs):function(e){let t=e.at(-1);return e.length>1&&a_(t)?t:void 0}(e.positionals??[]);return r?[t,r]:[t]}(t,n):[n]};if("fill"===t.command){let e=A(t);if(!e)continue;return{...t,positionals:[n,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,n]}}if("is"===t.command){let{predicate:e,split:r}=e5(t.positionals);if(!e)continue;let a=r?.rest.join(" ").trim()??"",i=[e,n];return"text"===e&&a.length>0&&i.push(a),{...t,positionals:i}}if("wait"===t.command){let{selectorTimeout:e}=aS(t.positionals??[]),r=[n];return e&&r.push(e),{...t,positionals:r}}}return null}function a_(e){return void 0!==e&&""!==e.trim()&&Number.isFinite(Number(e))}async function aN(e,t,r,n,a){let i=X(await m(e.device,"snapshot",[],t.flags?.out,{...Y(r,{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n},e.appBundleId,e.trace?.outPath)}),{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n});return j(e,i),a.set(e.name,e),i}let aM=new WeakMap,ax=new WeakMap;function aD(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}async function ak(e){var t;let r,n=await e.invoke({...e.baseReq,command:"snapshot",positionals:[],flags:{...e.baseReq.flags,noRecord:!0,snapshotRaw:!0,snapshotForceFull:!0}});return n.ok&&e.scope&&(t=e.scope,(r=q(aO(n.data)))&&aM.set(t,r)),n}function aO(e){if("object"==typeof e&&null!==e&&Array.isArray(e.nodes))return e}let aR=new Map([["button",0],["link",0],["textfield",0],["textview",0],["searchfield",0],["switch",0],["slider",0],["cell",1],["statictext",2]]);function aL(e,t,r,n){let a=aC(e,t,r,{allowLeadingCompositeLabelMatch:!1}),i=aP({nodes:e.nodes,matches:a,platform:r}),o=aU(e.nodes,i.matches,void 0,aF(t),n,!0);return o?{ok:!0,node:o.node,rect:o.rect,matches:i.matches.length}:{ok:!1,message:i.blockedByReactNativeOverlay?`React Native overlay is covering app content: ${t}`:a.length>0?`Maestro selector matched ${a.length} element(s), but none were visible: ${t}`:`Maestro selector did not match: ${t}`}}function aP(e){let t=e.matches.filter(t=>ts({predicate:"visible",node:t,nodes:e.nodes,platform:e.platform}).pass),r=function(e,t,r){let n=tc(e);if(!n.detected||!n.redBox)return{matches:t,blockedByReactNativeOverlay:!1};let a=tu(n),i=a.filter(t=>ts({predicate:"visible",node:t,nodes:e,platform:r}).pass);if(0===i.length)return 0===a.length?{matches:[],blockedByReactNativeOverlay:!0}:{matches:t,blockedByReactNativeOverlay:!1};let o=new Set(i.map(e=>e.index)),s=t.filter(e=>o.has(e.index));return{matches:s,blockedByReactNativeOverlay:t.length>0&&0===s.length}}(e.nodes,t,e.platform);return{matches:r.matches,blockedByReactNativeOverlay:r.blockedByReactNativeOverlay}}function a$(e){return e?.platform==="android"?"android":"ios"}function aF(e){let t=e8(e).selectors.flatMap(e=>e.terms);if(0===t.length||!t.some(e=>"label"===e.key||"text"===e.key)||!t.every(e=>["label","text","id"].includes(e.key)))return null;let r=t.map(e=>"string"==typeof e.value?e.value:""),n=r[0];return n&&r.every(e=>e===n)?n:null}function aC(e,t,r,n={}){for(let a of e8(t).selectors){let t=e.nodes.filter(e=>(function(e,t,r,n){return!!te(e,t,r)||t.terms.every(t=>(function(e,t,r,n){var a,i,o;return"string"!=typeof t.value||"id"!==(a=t.key)&&"label"!==a&&"text"!==a&&"value"!==a?te(e,{raw:t.key,terms:[t]},r):aE((i=e,"id"===(o=t.key)?i.identifier:"label"===o?i.label:"value"===o?i.value:e1(i)),t.value,n)})(e,t,r,n))})(e,a,r,n));if(t.length>0)return t}return[]}function aE(e,t,r={}){var n;let a=e??"",i=tr(a),o=tr(t);if(i===o||!1!==r.allowLeadingCompositeLabelMatch&&function(e,t){if(!e||!t||!e.startsWith(t))return!1;let r=e.at(t.length);return","===r||":"===r||";"===r}(i,o))return!0;if(n=t,!/(?:\.\*|\.\+|\[[^\]]+\]|\([^)]*\)|\||\^|\$|\\[dDsSwWbB])/.test(n))return!1;try{return new RegExp(t).test(a)}catch{return!1}}function aV(e,t,r){if(t.rect&&t.rect.width>0&&t.rect.height>0)return{rect:t.rect,inherited:!1};if(t.rect)return null;let n=function(e,t,r){let n=t;for(;"number"==typeof n.parentIndex&&(n=r.get(n.parentIndex)??e[n.parentIndex]);)if(n.rect)return n.rect.width>0&&n.rect.height>0?n.rect:null;return null}(e,t,r);return n?{rect:n,inherited:!0}:null}function aU(e,t,r,n,a,i=!1,o=!1,s){var l,u,c,d,p,f,m,h,w,g,y,v,A,b,S,I,_,N,M;let x,D,k,O,R=e7(e),L=(l=e,u=t,c=R,d=n,p=r,f=a,m=i,k=(D=(x=u.map(e=>{var t;let r;return(r=aV(l,t=e,c))?{node:t,rect:r.rect,inheritedRect:r.inherited}:null}).filter(e=>!!e)).filter(e=>!e.inheritedRect)).length>0?D:x,d&&void 0===p?(h=k,w=f,g=m,O=h.filter(e=>{var t,r;let n,a;return t=e.rect,r=w,n=r?.referenceWidth??1/0,a=r?.referenceHeight??1/0,t.x<n&&t.y<a&&t.x+t.width>0&&t.y+t.height>0}),g||O.length>0?O:h):x),P=function(e,t,r,n,a,i){var o,s,l,u,c,d,p;if(void 0!==r)return t[r]??null;let f=(o=e,s=t,l=n,u=a,c=i,u&&l?function(e,t,r,n){let a=t.filter(e=>0===az(e.node,r));if(a.length>=2){let t=aG(e,a,r,n);if(t)return t}let i=t.filter(e=>1===az(e.node,r));return a.length>0||i.length<2?null:aG(e,i,r,n)}(o,s,l,c)??aT(o,s,l,c):aT(o,s,l,c));return(d=f,p=n,a&&p&&d)?function(e,t,r){var n,a,i,o,s,l,u,c,d,p,f,m,h,w,g,y,v;let A,b,S,I,_,N,M,x;if(n=t,a=r,!(("other"===(A=tt(n.node.type??""))||"scrollview"===A||"scroll-area"===A)&&!(n.rect.width<120)&&!(n.rect.height<32)&&!(n.rect.height>80)&&1>=az(n.node,a)))return null;let D=(i=e,o=t,s=r,i.filter(e=>{var t,r,n,a,i;let l,u;return e.parentIndex===o.node.index&&!!e.rect&&(t=e,r=o.rect,n=s,!("button"!==(l=tt(t.type??""))&&"cell"!==l&&"other"!==l||1>=az(t,n))&&!(t.rect.width<16)&&!(t.rect.height<16)&&!!aH(r,t.rect)&&(a=r,i=t.rect,u=Math.max(a.y,i.y),Math.max(0,Math.min(a.y+a.height,i.y+i.height)-u)/Math.max(1,Math.min(a.height,i.height))>=.5))}).sort((e,t)=>e.rect.x-t.rect.x));if(0===D.length)return null;let k=(S=Math.floor((b=[...D.map(e=>e.rect.width)].sort((e,t)=>e-t)).length/2),b[S]??0),O=function(e,t){let r=[],n=e.x,a=e.x+e.width;for(let i of t){let t=Math.max(e.x,i.x),o=Math.min(a,i.x+i.width);t>n&&r.push({x:n,width:t-n}),n=Math.max(n,o)}return a>n&&r.push({x:n,width:a-n}),r}(t.rect,D.map(e=>e.rect)),R=(l=t,u=r,c=O,d=k,N=c.filter(e=>{var t,r;return t=e.width,r=d,!(t<24)&&!(r<24)&&t>=.4*r&&t<=1.6*r}),M=(p=l,f=u,I=c.find(e=>1>Math.abs(e.x-p.rect.x)),_=Math.max(48,Math.min(220,8*f.length+24)),(m=p,h=f,w=I,g=_,w&&"scrollview"===tt(m.node.type??"")&&1>=az(m.node,h)&&m.rect.width>=240&&m.rect.height>=32&&m.rect.height<=80&&w.width<=.55*m.rect.width&&w.width>=.6*g)?{x:p.rect.x,width:Math.min(_,I.width)}:null),x=N.some(e=>{var t;return t=l.rect,1>Math.abs(e.x-t.x)}),M&&!x?M:1===N.length?N[0]??null:M);return R?(y=t,v=R,{...y,rect:{x:v.x,y:y.rect.y,width:v.width,height:y.rect.height}}):null}(e,f,n)??f:f}(e,L,r,n,o,s);return y=e,v=P,A=R,b=o,S=a,v?b?(I=y,_=v,N=A,M=S,(aB(_.node)?null:e2(I,_.node,N,e=>{if(!aB(e))return null;let t=aV(I,e,N);return t&&function(e,t,r){if(!aH(t,e))return!1;let n=aq(t),a=aq(e);if(a>0&&n>30*a)return!1;if(r){let e=r.referenceWidth*r.referenceHeight;if(e>0&&n>.5*e)return!1}return!0}(_.rect,t.rect,M)?{node:e,rect:t.rect}:null}))??{node:v.node,rect:v.rect}):{node:v.node,rect:v.rect}:null}function aT(e,t,r,n){return(function(e,t,r,n){var a;let i,o,s;if(!r||t.length<2)return t;let l=t.filter(e=>0===az(e.node,r));if(l.length<2)return t;let u=e7(e),c=l.map(t=>({candidate:t,container:aj(e,t.node,u)})).filter(e=>!!e.container);if(c.length<2||c.length!==l.length)return t;let d=c.filter(e=>{var t;return t=e,c.some(e=>e!==t&&t.container.index!==e.container.index&&aW(t.container.rect,e.container.rect)>=.6)});if(d.length<2)return t;let p=(o=Math.max(...i=(a=d).map(e=>aq(e.container.rect))),(s=Math.min(...i))<=0||o<1.2*s?[]:a.filter(e=>aq(e.container.rect)===o).map(e=>e.candidate));if(p.length>0)return p;let f=function(e,t,r,n){if(!r)return[];let a=aj(e,r.node,n),i=a&&aH(a.rect,r.rect)?a:null,o=t.map(e=>({entry:e,score:function(e,t,r){if(r)return e.index===r.index?0:.6>aW(e.rect,r.rect)?1/0:Math.abs(e.index-r.index);if(aW(e.rect,t.rect)>=.6)return 0;let n=e.index-t.node.index;return n>=0?n:1e5+Math.abs(n)}(e.container,r,i)})),s=Math.min(...o.map(e=>e.score));return Number.isFinite(s)?o.filter(e=>e.score===s).map(e=>e.entry.candidate):[]}(e,d,n,u);if(f.length>0)return f;let m=Math.max(...d.map(e=>e.container.index)),h=d.filter(e=>e.container.index===m).map(e=>e.candidate);return h.length>0?h:t})(e,t,r,n).sort((e,t)=>(function(e,t,r){var n,a;let i=function(e,t,r){if(r){let n=az(e.node,r)-az(t.node,r);if(0!==n)return n}let n=aK(e.node)-aK(t.node);if(0!==n)return n;let a=Number(e.inheritedRect)-Number(t.inheritedRect);if(0!==a)return a;let i=r&&aK(e.node)===aK(t.node)?aq(t.rect)-aq(e.rect):aq(e.rect)-aq(t.rect);return 0!==i?i:0}(e,t,r);if(0!==i)return i;if(n=e.rect,a=t.rect,Math.round(n.x)!==Math.round(a.x)||Math.round(n.y)!==Math.round(a.y)||Math.round(n.width)!==Math.round(a.width)||Math.round(n.height)!==Math.round(a.height))return e.node.index-t.node.index;let o=(t.node.depth??0)-(e.node.depth??0);return 0!==o?o:t.node.index-e.node.index})(e,t,r))[0]??null}function aG(e,t,r,n){let a=e7(e),i=t.filter(r=>{var n;return(n=r).rect.width>=16&&n.rect.width<=260&&n.rect.height>=24&&n.rect.height<=80&&t.some(t=>{var n,i,o,s;return n=e,i=t,o=r,s=a,!(i.node.index===o.node.index||!aH(i.rect,o.rect)||aq(i.rect)<2*aq(o.rect))&&e3(n,o.node,i.node,s)})});return aT(e,i,r,n)}function aj(e,t,r){return e2(e,t,r,e=>{let t;return!e.rect||"scrollview"!==(t=tt(e.type??""))&&"scroll-area"!==t&&"list"!==t||e.rect.width<240||e.rect.height<320?null:e})}function aq(e){return e.width*e.height}function aK(e){return aR.get(tt(e.type??""))??3}function aB(e){let t=tt(e.type??"");return!0===e.hittable||"button"===t||"link"===t||"cell"===t||"textfield"===t||"searchfield"===t||"switch"===t||"slider"===t}function aH(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 aW(e,t){let r=Math.max(e.x,t.x),n=Math.min(e.x+e.width,t.x+t.width),a=Math.max(e.y,t.y);return Math.max(0,n-r)*Math.max(0,Math.min(e.y+e.height,t.y+t.height)-a)/Math.max(1,Math.min(aq(e),aq(t)))}function az(e,t){let r=[e.label,e1(e),e.identifier,e.value].filter(e=>!!e);return r.some(e=>e===t)?0:r.some(e=>tr(e)===tr(t))?1:r.some(e=>aE(e,t))?2:3}async function aJ(e){var t,r,n;let a=aQ(e.positionals,{command:"assertVisible",defaultTimeoutMs:7e3});if(!a.ok)return a.response;let i=(t=e.baseReq,r=a.selector,n=a.timeoutMs,t.flags?.platform!=="ios"||t.flags?.maestro?.allowAlreadyPastLoading===!0||n<3e4?null:aF(r));return i?await aX(e,a,i):await aZ(e,a)}async function aX(e,t,r){let n=Date.now(),a=await aY(e,t,r);return a.ok?a3({ok:!0,data:{selector:t.selector,nativeWait:!0,query:r,response:a.data}},t.selector,n):a}async function aY(e,t,r){return await e.invoke({...e.baseReq,command:"wait",positionals:[r,String(t.timeoutMs)]})}async function aZ(e,t){let r,n=Date.now(),a=t.timeoutMs+1e3,i=!1;for(;;){let o=Date.now(),s=await a0(e,t.selector,"assertVisible");if(s.visible)return a3(s.response,t.selector,n);r=s.response;let l=function(e,t,r,n){var a,i,o,s,l,u,c;return!(a=r.response).ok&&"COMMAND_FAILED"===a.error.code&&a.error.message.includes("React Native overlay")?{kind:"return",response:r.response}:(i=e,o=t.selector,s=r.snapshot,i.flags?.maestro?.allowAlreadyPastLoading===!0&&void 0!==s&&function(e,t){let r=a1(aF(e));if(!a2(r))return!1;let n=t.nodes.flatMap(e=>[e.label,e.value,e.identifier]).filter(e=>!!e?.trim()).map(e=>a1(e));return!n.some(e=>e.includes("something went wrong"))&&n.some(e=>e!==r&&!a2(e))}(o,s))?{kind:"return",response:(l=t.selector,u=t.timeoutMs,c=n,{ok:!0,data:{selector:l,alreadyPastLoading:!0,waitedMs:Date.now()-c,timeoutMs:u}})}:{kind:"continue"}}(e.baseReq,t,s,n);if("return"===l.kind)return l.response;let u=function(e){var t,r,n,a;return Date.now()-e.startedAt<e.deadlineMs?"wait":(t=e.capturedAfterDeadline,r=e.captureStartedAt,n=e.startedAt,a=e.deadlineMs,!t&&r-n<a)?"capture-again":"finish"}({captureStartedAt:o,capturedAfterDeadline:i,startedAt:n,deadlineMs:a});if("capture-again"===u){i=!0;continue}if("finish"===u)break;await tp(250)}return r??aD("COMMAND_FAILED",`Expected visible but did not match: ${t.selector}`,{selector:t.selector,timeoutMs:t.timeoutMs})}function aQ(e,t){let[r,n=String(t.defaultTimeoutMs)]=e;if(!r)return{ok:!1,response:aD("INVALID_ARGS",`${t.command} requires a selector.`)};let a=Number(n);return!Number.isFinite(a)||a<0?{ok:!1,response:aD("INVALID_ARGS",`${t.command} timeout must be a non-negative number.`)}:{ok:!0,selector:r,timeoutMs:a}}async function a0(e,t,r){var n;let a=await ak(e);if(!a.ok)return{visible:!1,response:a,infrastructureFailure:!0};let i=aO(a.data);if(!i)return{visible:!1,response:aD("COMMAND_FAILED",`Unable to read snapshot data for ${r}.`),infrastructureFailure:!0};let o=aL(i,t,a$(e.baseReq.flags),q(i));return o.ok?(n=e.scope,n&&ax.set(n,{selector:t}),{visible:!0,response:{ok:!0,data:{selector:t,matches:o.matches,nodeIndex:o.node.index,nodeType:o.node.type,nodeLabel:o.node.label,nodeIdentifier:o.node.identifier,rect:o.rect}}}):{visible:!1,response:aD("COMMAND_FAILED",o.message,{selector:t}),infrastructureFailure:!1,snapshot:i}}function a1(e){return e?.trim().toLowerCase().replace(/\u2026/g,"...")??""}function a2(e){return"loading"===e||"loading..."===e}function a3(e,t,r){return e.ok?{ok:!0,data:{selector:t,...e.data,waitedMs:Date.now()-r}}:e}async function a5(e){let t,r=aQ(e.positionals,{command:"assertNotVisible",defaultTimeoutMs:3e3});if(!r.ok)return r.response;let n=Date.now(),a=0;for(;Date.now()-n<=r.timeoutMs;){let i=await a0(e,r.selector,"assertNotVisible");if(!i.visible&&i.infrastructureFailure)return i.response;if(i.visible)a=0,t=i.response;else{a+=1;let e=Date.now()-n;if(a>=2||e>=r.timeoutMs)return{ok:!0,data:{pass:!0,selector:r.selector,stableSamples:a,waitedMs:e,timeoutMs:r.timeoutMs}}}await tp(250)}return a>0?{ok:!0,data:{pass:!0,selector:r.selector,stableSamples:a,waitedMs:Date.now()-n,timeoutMs:r.timeoutMs}}:aD("COMMAND_FAILED",`Expected not visible but matched: ${r.selector}`,{selector:r.selector,timeoutMs:r.timeoutMs,lastResponse:t})}async function a6(e){let t,r,n=Number(e.positionals[0]??15e3);if(!Number.isFinite(n)||n<0)return aD("INVALID_ARGS","waitForAnimationToEnd timeout must be a number.");let a=Date.now();for(;Date.now()-a<n;){let a=await ak(e),i=function(e,t,r){let n=function(e){if(!e.ok)return null;let t=aO(e.data);return t?JSON.stringify(t.nodes.map(e=>({index:e.index,parentIndex:e.parentIndex,type:e.type,identifier:e.identifier,label:e.label,value:e.value,rect:e.rect?{x:Math.round(e.rect.x),y:Math.round(e.rect.y),width:Math.round(e.rect.width),height:Math.round(e.rect.height)}:void 0}))):null}(e);return e.ok?n?t===n?{done:!0,response:{ok:!0,data:{stable:!0,timeoutMs:r}}}:{done:!1,signature:n}:{done:!0,response:e}:{done:!1}}(a,t,n);if(i.done)return i.response;t=i.signature??t,r=a,await tp(250)}return r?.ok===!1?r:{ok:!0,data:{stable:!1,timeoutMs:n}}}let a8=.35,a9=120,a4=360,a7=8,ie=120,it=70,ir=200,ia=168,ii=48;function io(e,t){return Math.round(Math.min(a4,Math.max(a9,"number"==typeof e?e*a8:0,1.5*t)))}async function is(e){var t,r,n;let[a,i="5000",o="down"]=e.positionals;if(!a)return aD("INVALID_ARGS","scrollUntilVisible requires a selector.");let s=Number(i);if(!Number.isFinite(s)||s<=0)return aD("INVALID_ARGS","scrollUntilVisible timeout must be a positive number.");let l=aF(a),u=Math.max(1,Math.ceil(s/500)),c=null;for(let t=0;t<u;t+=1){let r=await ig(e,a,l,Math.min(500,Math.max(1,s-500*t)));if(r.ok)return r;if(c=r,t===u-1)break;let n=await e.invoke({...e.baseReq,command:"scroll",positionals:[o]});if(!n.ok)return n}return t=c,r=a,n=s,t?{ok:!1,error:{...t.error,message:`scrollUntilVisible timed out after ${n}ms for selector: ${r}. Last wait: ${t.error.message}`}}:aD("COMMAND_FAILED",`scrollUntilVisible timed out after ${n}ms for selector: ${r}`)}async function il(e){let[t,r]=e.positionals,n=Number(t),a=Number(r);if(!Number.isFinite(n)||!Number.isFinite(a))return aD("INVALID_ARGS","tapOn percentage point requires numeric x/y values.");let i=await ak(e);if(!i.ok)return i;let o=aO(i.data);if(!o)return aD("COMMAND_FAILED","Unable to read snapshot data for Maestro percentage point tap.");let s=q(o);if(!s)return aD("COMMAND_FAILED","Unable to resolve screen size for Maestro percentage point tap.");let l=tn(s,n,a);return await e.invoke({...e.baseReq,command:"click",positionals:[String(l.x),String(l.y)]})}async function iu(e){let t=await ic(e);if(t)return t;let r=await ih(e);return r.ok?await im(e,r,r.durationMs):r.response}async function ic(e){let[t,r,n]=e.positionals;if("direction"===t&&("left"===r||"right"===r))return await e.invoke({...e.baseReq,command:"gesture",positionals:["swipe",r,...n?[n]:[]]})}async function id(e){var t,r,n,a;let i,[o,s]=e.positionals;if(!o)return aD("INVALID_ARGS","tapOn requires a selector.");let l=function(e){if(!e)return{ok:!0,value:null};try{let t=JSON.parse(e);return{ok:!0,value:t}}catch{return{ok:!1,response:aD("INVALID_ARGS","tapOn runtime options must be valid JSON.")}}}(s);if(!l.ok)return l.response;let u=Date.now(),c=(t=e,t.baseReq.flags?.maestro?.optional===!0?3e3:3e4);for(;Date.now()-u<c;){let t=await iy(e,o,l.value??{});if(!t.retry)return t.response;i=t.response,await tp(250)}return r=e,n=o,a=i,r.baseReq.flags?.maestro?.optional===!0?{ok:!0,data:{skipped:!0,optional:!0,selector:n}}:a??aD("COMMAND_FAILED",`tapOn timed out for selector: ${n}`)}async function ip(e){let[t,r="up",n]=e.positionals;if(!t)return aD("INVALID_ARGS","swipe.label requires a label selector.");let a=await iS(e,t,{},"swipe.label",{promoteTapTarget:!1});if(!a.ok)return a.response;let i=function(e,t){let r=tl(e.rect),n=e.frame,a=io(n?.referenceWidth,e.rect.width),i=io(n?.referenceHeight,e.rect.height),o=a7,s=n?n.referenceWidth-o:r.x+a,l=n?n.referenceHeight-o:r.y+i;switch(t.toLowerCase()){case"up":return{ok:!0,start:r,end:{x:r.x,y:ti(r.y-i,o,l)}};case"down":return{ok:!0,start:r,end:{x:r.x,y:ti(r.y+i,o,l)}};case"left":return{ok:!0,start:r,end:{x:ti(r.x-a,o,s),y:r.y}};case"right":return{ok:!0,start:r,end:{x:ti(r.x+a,o,s),y:r.y}};default:return{ok:!1,message:"swipe.label direction must be up, down, left, or right."}}}(a.target,r);return i.ok?await im(e,i,n):aD("INVALID_ARGS",i.message)}async function im(e,t,r){return await e.invoke({...e.baseReq,command:"swipe",positionals:[String(t.start.x),String(t.start.y),String(t.end.x),String(t.end.y),...r?[r]:[]]})}async function ih(e){var t;let r=((t=e.scope)?aM.get(t):void 0)??await iw(e);if(!r)return{ok:!1,response:aD("COMMAND_FAILED","Unable to resolve screen size for Maestro swipe.")};let[n,...a]=e.positionals;return"direction"===n?function(e,t){let[r,n]=e;if(!r)return{ok:!1,response:aD("INVALID_ARGS","Maestro direction swipe requires a direction.")};switch(r){case"up":case"down":var a,i,o;let s;return a=r,i=t,o=n,{ok:!0,start:td({x:(s=ta({direction:a,amount:.6,referenceWidth:i.referenceWidth,referenceHeight:i.referenceHeight})).x1,y:s.y1},i,8),end:td({x:s.x2,y:s.y2},i,8),durationMs:o};default:return{ok:!1,response:aD("INVALID_ARGS","Maestro swipe direction must be UP, DOWN, LEFT, or RIGHT.")}}}(a,r):"percent"===n?function(e,t,r){var n,a,i,o,s;let[l,u,c,d,p]=e,f=[l,u,c,d].map(Number);if(f.some(e=>!Number.isFinite(e)))return{ok:!1,response:aD("INVALID_ARGS","Maestro percentage swipe requires numeric points.")};let[m,h,w,g]=f,y=(n=r,a=m,i=h,o=w,s=g,"android"!==n||i!==s||50!==i||30>Math.abs(o-a)?{startY:i,endY:s}:{startY:65,endY:65});return{ok:!0,start:tn(t,m,y.startY,{marginPx:1}),end:tn(t,w,y.endY,{marginPx:1}),durationMs:p}}(a,r,a$(e.baseReq.flags)):{ok:!1,response:aD("INVALID_ARGS","Maestro screen swipe requires direction or percent.")}}async function iw(e){let t=await ak(e);if(t.ok)return q(aO(t.data))}async function ig(e,t,r,n){let a=await e.invoke({...e.baseReq,command:"wait",positionals:[t,String(n)]});return a.ok||!r?a:await e.invoke({...e.baseReq,command:"find",positionals:[r,"wait",String(n)]})}async function iy(e,t,r){let n=aF(t),a=await iv(e,t,r);return a.response.ok?{retry:!1,response:a.response}:a.targetResolved&&n?await ib(e,n):{retry:!0,response:a.response}}async function iv(e,t,r){let n=await iS(e,t,r,"tapOn",{promoteTapTarget:!0});return n.ok?await iA(e,t,n.target):{response:n.response,targetResolved:!1}}async function iA(e,t,r){var n,a;let i=(n=null!==aF(t),!function(e,t,r){if(!t||r.width<ie)return!1;let n=tt(e.type??"");return!(r.height<it)&&!(r.height>ir)&&("cell"===n||"other"===n||"scrollview"===n||"scroll-area"===n)}(r.node,n,r.rect)?tl(r.rect):{x:to(r.rect.x,Math.min(r.rect.width,ia)),y:to(r.rect.y,Math.min(r.rect.height,ii))});eQ({level:"debug",phase:"maestro_tap_target",data:{selector:t,node:{index:r.node.index,type:r.node.type,label:r.node.label,value:r.node.value,identifier:r.node.identifier,visibleToUser:r.node.visibleToUser},rect:r.rect,point:i}});let o=await e.invoke({...e.baseReq,command:"click",positionals:[String(i.x),String(i.y)],flags:{...e.baseReq.flags,interactionOutcome:{retryOnNoChange:!0}}});return o.ok&&(a=e.scope)&&ax.delete(a),{response:o,targetResolved:!0}}async function ib(e,t){let r=await e.invoke({...e.baseReq,command:"find",positionals:[t,"click"],flags:{...e.baseReq.flags,findFirst:!0,interactionOutcome:{retryOnNoChange:!0}}});return r.ok?{retry:!1,response:r}:{retry:!0,response:r}}async function iS(e,t,r,n,a){let i=await ak(e);if(!i.ok)return{ok:!1,response:i};let o=aO(i.data);if(!o)return{ok:!1,response:aD("COMMAND_FAILED",`Unable to read snapshot data for ${n}.`)};let s=q(o),l=a$(e.baseReq.flags),u=function(e,t,r,n){var a;let i=(a=e.scope)?ax.get(a):void 0;if(!i)return;let o=aL(t,i.selector,r,n);if(o.ok)return eQ({level:"debug",phase:"maestro_preferred_context",data:{selector:i.selector,node:{index:o.node.index,type:o.node.type,label:o.node.label,value:o.node.value,identifier:o.node.identifier},rect:o.rect}}),{node:o.node,rect:o.rect}}(e,o,l,s),c=function(e,t,r,n,a,i={}){let o=aC(e,t,n);if(r.childOf){let t=aC(e,r.childOf,n);if(0===t.length)return{ok:!1,message:`Maestro childOf parent did not match: ${r.childOf}`};let a=e7(e.nodes);o=o.filter(r=>t.some(t=>e3(e.nodes,r,t,a)))}let s=aP({nodes:e.nodes,matches:o,platform:n}),l=aU(e.nodes,s.matches,r.index,aF(t),a,!1,i.promoteTapTarget,i.preferredContext);if(!l){let e=r.index??0;return{ok:!1,message:s.blockedByReactNativeOverlay?`React Native overlay is covering app content: ${t}`:o.length>0&&0===s.matches.length?`Maestro selector matched ${o.length} element(s), but none were visible: ${t}`:`Maestro selector did not match index ${e}: ${t}`}}return{ok:!0,node:l.node,rect:l.rect}}(o,t,r,l,s,{...a,preferredContext:u});if(!c.ok){let e=aF(t);if(e){let t=function(e,t,r,n,a={}){let i=function(e,t){let r=tr(t);if(!r)return[];let n=[],a=[];for(let t of e.nodes){let e=[t.label,e1(t),t.identifier,t.value].filter(e=>!!e).map(e=>tr(e));e.some(e=>e===r)?n.push(t):e.some(e=>e.includes(r))&&a.push(t)}return n.length>0?n:a}(e,t),o=aP({nodes:e.nodes,matches:i,platform:r}),s=aU(e.nodes,o.matches,void 0,t,n,!1,a.promoteTapTarget,a.preferredContext);return s?{ok:!0,node:s.node,rect:s.rect}:{ok:!1,message:`Maestro fuzzy text did not match: ${t}`}}(o,e,l,s,{...a,preferredContext:u});if(t.ok)return{ok:!0,target:{node:t.node,rect:t.rect,frame:s,snapshot:o}}}}return c.ok?{ok:!0,target:{node:c.node,rect:c.rect,frame:s,snapshot:o}}:{ok:!1,response:aD("ELEMENT_NOT_FOUND",c.message,{selector:t,options:r,command:n})}}async function iI(e){switch(e.command){case nG:return await aJ(e);case nj:return await a5(e);case nq:return await i_(e);case nK:return await a6(e);case nB:return await is(e);case nH:return await iu(e);case nW:return await ip(e);case nz:return await id(e);case nJ:return await il(e);case nT:return function(e){let[r]=e.positionals;if(!r)return aD("INVALID_ARGS","runScript requires a file path.");try{let n=function(e){let{scriptPath:r,env:n}=e,a=t.readFileSync(r,"utf8"),i=Object.create(null);try{var o,l;s.runInNewContext(a,(o=n,l=i,{...o,output:l,json:at,http:{post:(e,t)=>(function(e,t,r){let n=eZ(process.execPath,["-e",ae],{stdin:JSON.stringify({method:e,url:t,headers:r?.headers??{},body:r?.body??""}),timeoutMs:3e4,allowFailure:!0});if(0!==n.exitCode){let r;throw new d("COMMAND_FAILED",`Maestro runScript http.${e.toLowerCase()} failed for ${t}: ${(r=n.stderr.trim()).length>0?r.slice(0,1e3):"request process exited without stderr"}`,{exitCode:n.exitCode,stderr:n.stderr})}try{return JSON.parse(n.stdout)}catch(r){throw new d("COMMAND_FAILED",`Maestro runScript http.${e.toLowerCase()} returned invalid JSON for ${t}`,{stdout:n.stdout.slice(0,1e3),stderr:n.stderr.slice(0,1e3)},r instanceof Error?r:void 0)}})("POST",e,t)}}),{filename:r,timeout:3e4})}catch(e){throw new d("COMMAND_FAILED",`Maestro runScript failed for ${r}: ${e instanceof Error?e.message:String(e)}`,{scriptPath:r},e instanceof Error?e:void 0)}return function(e,t){for(let r of Object.keys(e))if(r.includes("."))throw new d("INVALID_ARGS",`Maestro runScript output key cannot contain ".": ${r}`,{scriptPath:t,key:r})}(i,r),Object.fromEntries(Object.entries(i).map(([e,t])=>{var r;return[`output.${e}`,(r=t,"string"==typeof r?r:"number"==typeof r||"boolean"==typeof r?String(r):JSON.stringify(r))]}))}({scriptPath:r,env:{...e.scope.values,...e.baseReq.flags?.maestro?.runScriptEnv??{}}});return{ok:!0,data:{outputEnv:n}}}catch(t){let e=u(t);return aD(e.code,e.message,e.details)}}(e);default:return}}async function i_(e){let t=await e.invoke({...e.baseReq,command:"keyboard",positionals:["enter"]});return t.ok?t:await e.invoke({...e.baseReq,command:"type",positionals:["\n"]})}async function iN(e){for(let[t,r]of e.actions.entries()){let n=await e.invokeReplayAction({action:r,line:e.line,step:e.step+t/1e3});if(!n.ok)return n}return{ok:!0,data:{ran:e.actions.length}}}async function iM(e){let t;for(let r=0;r<=e.maxRetries;r+=1){let n=await iN({actions:e.actions,line:e.line,step:e.step+r,invokeReplayAction:e.invokeReplayAction});if(n.ok)return{ok:!0,data:{attempts:r+1,retried:r>0}};t=n}return t??{ok:!1,error:{code:"COMMAND_FAILED",message:"retry commands failed."}}}async function ix(e){let t=await iD(e,e.control);return t.ok?t.matched?await iR(e):{ok:!0,data:{skipped:!0,condition:e.control.mode,selector:e.control.selector}}:t.response}async function iD(e,t){if("visible"===t.mode)return await ik(e,t);let r=await ak(e);if(!r.ok)return{ok:!1,response:r};let n=iO(e,t.selector,r);return n.ok?{ok:!0,matched:!n.matched}:{ok:!1,response:n.response}}async function ik(e,t){let r=Date.now();for(;;){let n=await ak(e);if(!n.ok)return{ok:!1,response:n};let a=iO(e,t.selector,n);if(!a.ok)return{ok:!1,response:a.response};if(a.matched)return{ok:!0,matched:!0};if(Date.now()-r>=3e3)return{ok:!0,matched:!1};await tp(250)}}function iO(e,t,r){let n=aO(r.data);return n?{ok:!0,matched:aL(n,t,a$(e.baseReq.flags),q(n)).ok}:{ok:!1,response:aD("COMMAND_FAILED","Unable to read snapshot data for runFlow.when.")}}async function iR(e){let t=await iN({actions:e.control.actions,line:e.line,step:e.step,invokeReplayAction:e.invokeReplayAction});return t.ok?{ok:!0,data:{ran:t.data?.ran,condition:e.control.mode,selector:e.control.selector}}:t}async function iL(e){var t;let{req:r,sessionName:n,action:a,scope:i,filePath:o,line:s,step:l,tracePath:u,invoke:c}=e,d=(t={file:o,line:s},{...a,positionals:(a.positionals??[]).map(e=>nm(e,i,t)),flags:nh(a.flags,i,t)??{},runtime:nh(a.runtime,i,t),replayControl:function(e,t,r){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:nm(e.selector,t,r)}}return e}(a.replayControl,i,t)}),p=Date.now();iF(u,{type:"replay_action_start",ts:new Date(p).toISOString(),replayPath:o,line:s,step:l,command:d.command,positionals:d.positionals??[]});let f=await iP({req:r,sessionName:n,resolved:d,scope:i,line:s,step:l,invoke:c,invokeReplayAction:e=>iL({req:r,sessionName:n,action:e.action,scope:i,filePath:o,line:e.line,step:e.step,tracePath:u,invoke:c})}),m=Date.now();return iF(u,{type:"replay_action_stop",ts:new Date(m).toISOString(),replayPath:o,line:s,step:l,command:d.command,ok:f.ok,durationMs:m-p,resultTiming:f.ok?function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;let t=e.timing;if(!(!t||"object"!=typeof t||Array.isArray(t)))return Object.fromEntries(Object.entries(t).filter(([,e])=>{let t=typeof e;return"number"===t||"string"===t||"boolean"===t}))}(f.data):void 0,errorCode:f.ok?void 0:f.error.code}),f}async function iP(e){var t;let{req:r,sessionName:n,resolved:a,scope:i,line:o,step:s,invoke:l,invokeReplayAction:u}=e,c=(t=r.flags,eW(t,{...a.flags??{}})),d={token:r.token,session:n,flags:c,runtime:a.runtime,meta:r.meta},p=await i$({control:a.replayControl,baseReq:d,line:o,step:s,invoke:l,invokeReplayAction:u})??await iI({command:a.command,baseReq:d,positionals:a.positionals??[],scope:i,line:o,step:s,invoke:l,invokeReplayAction:u})??await l({...d,command:a.command,positionals:a.positionals??[]});if(p.ok){let e=function(e){if(!e||"object"!=typeof e)return null;let t=e.outputEnv;if(!t||"object"!=typeof t||Array.isArray(t))return null;let r=Object.entries(t).filter(e=>"string"==typeof e[1]);return r.length>0?Object.fromEntries(r):null}(p.data);e&&Object.assign(i.values,e)}return p}async function i$(e){let{control:t,baseReq:r,line:n,step:a,invoke:i,invokeReplayAction:o}=e;if(t){switch(t.kind){case"retry":return await iM({actions:t.actions,maxRetries:t.maxRetries,line:n,step:a,invokeReplayAction:o});case"maestroRunFlowWhen":return await ix({baseReq:r,control:t,line:n,step:a,invoke:i,invokeReplayAction:o})}return t}}function iF(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
28
- `)}async function iC(e){let{req:r,sessionName:n,logPath:i,sessionStore:o,tracePath:s,invoke:l}=e,c=r.positionals?.[0];if(!c)return R("INVALID_ARGS","replay requires a path");let p="",f=new Set;try{var m,h;p=Q.expandHome(c,r.meta?.cwd);let e=t.readFileSync(p,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return R("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let w=function(e,t,r={}){var n;let a=function(e){let t=e?.replayBackend;if("string"!=typeof t)return;let r=ab[t];if(!r)throw new d("INVALID_ARGS",`Unsupported replay backend "${t}".`);return r}(t);return a?{...a.parse(e,{...r,platform:t?.platform,env:(n=t,{...nc(nf(n?.replayShellEnv)),...nd(np(n?.replayEnv))})}),updateUnsupportedMessage:"replay -u is not supported for compat flow input. Convert to .ad first, then update that replay file."}:{...function(e){let t=[],r=[],n=e.split(/\r?\n/),a=!1;for(let[e,i]of n.entries()){let n=i.trim();if(0===n.length||n.startsWith("#"))continue;if(nv(n)){if(a)throw new d("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let o=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[r,...n]=function(e){let t=[],r=0;for(;r<e.length&&!((r=function(e,t){let r=t;for(;r<e.length&&/\s/.test(e.charAt(r));)r+=1;return r}(e,r))>=e.length);){let n='"'===e[r]?function(e,t){let r=!1,n=t+1;for(;n<e.length;n+=1){let t=e.charAt(n);if('"'===t&&!r)break;if(r){r=!1;continue}r="\\"===t}if(n>=e.length)throw new d("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,n+1)),nextCursor:n+1}}(e,r):function(e,t){let r=t;for(;r<e.length&&!/\s/.test(e.charAt(r));)r+=1;return{value:e.slice(t,r),nextCursor:r}}(e,r);t.push(n.value),r=n.nextCursor}return t}(t);if(void 0===r||"context"===r)return null;let a={ts:Date.now(),command:r,positionals:[],flags:{}};if("snapshot"===r){a.positionals=[];for(let e=0;e<n.length;e+=1){let t=n[e];if("-i"===t){a.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){a.flags.snapshotCompact=!0;continue}if("--raw"===t){a.flags.snapshotRaw=!0;continue}if("--force-full"===t){a.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<n.length){let t=Number(n[e+1]);Number.isFinite(t)&&t>=0&&(a.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<n.length){a.flags.snapshotScope=n[e+1],e+=1;continue}if("--backend"===t&&e+1<n.length){e+=1;continue}}return a}if("open"===r){let e=P(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a.runtime=e.runtime,a}if("runtime"===r){let e=G(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a}if(M(r)){let e=eh(r,n);Object.assign(a.flags,e.flags);let t=e.positionals[0];if(void 0===t)return a;if(t.startsWith("@"))return a.positionals=[t],e.positionals[1]&&(a.result={refLabel:e.positionals[1]}),a;let i=e.positionals[0],o=e.positionals[1];return nb(i)&&nb(o)&&e.positionals.length>=2?a.positionals=[i,o]:a.positionals=[e.positionals.join(" ")],a}if("fill"===r){let e=eh(r,n);if(Object.assign(a.flags,e.flags),!(e.positionals.length>=2))return a.positionals=e.positionals,a;let[t,i,...o]=e.positionals;return t.startsWith("@")?(o.length>0?(a.positionals=[t,o.join(" ")],a.result={refLabel:i}):a.positionals=[t,i],a):(a.positionals=[t,[i,...o].join(" ")],a)}if("get"===r){let e=n[0],t=n[1];return void 0===e||void 0===t?a.positionals=n:t.startsWith("@")?(a.positionals=[e,t],n[2]&&(a.result={refLabel:n[2]})):a.positionals=[e,n.slice(1).join(" ")],a}if("swipe"===r||"type"===r){let e=eh(r,n);return Object.assign(a.flags,e.flags),a.positionals=e.positionals,a}if("record"===r){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t];if("--hide-touches"===r){a.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<n.length){let e=Number(n[t+1]);Number.isFinite(e)&&(a.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===r&&t+1<n.length){let e=Number(n[t+1]);Number.isFinite(e)&&(a.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return a.positionals=e,a}if("screenshot"===r){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t],i=eY({args:n,index:t,flags:a.flags});if(i.handled){t=i.nextIndex;continue}e.push(r)}return a.positionals=e,a}return a.positionals=n,a}(i);o&&(t.push(o),r.push(e+1),a=!0)}return{actions:t,actionLines:r}}(e),metadata:ny(e)}}(e,r.flags,{sourcePath:p}),g=w.metadata,y=g.platform||g.target?{...r,flags:(m=r.flags,h=g,{...m??{},...void 0!==h.platform&&m?.platform===void 0?{platform:h.platform}:{},...void 0!==h.target&&m?.target===void 0?{target:h.target}:{}})}:r,v=w.actions,A=w.actionLines;if(r.flags?.replayUpdate===!0&&w.updateUnsupportedMessage)return R("INVALID_ARGS",w.updateUnsupportedMessage);if(r.flags?.replayUpdate===!0&&g.env&&Object.keys(g.env).length>0)return R("INVALID_ARGS","replay -u does not yet preserve env directives. Temporarily remove the env lines, run replay -u, then restore them.");if(r.flags?.replayUpdate===!0&&function(e){for(let t of e){for(let e of t.positionals??[])if("string"==typeof e&&e.includes("${"))return!0;if(iU(t.flags)||iU(t.runtime))return!0}return!1}(v))return R("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let S=function(e){let t={};if(e.builtins)for(let[r,n]of Object.entries(e.builtins))t[r]=n;for(let r of[e.fileEnv,e.shellEnv,e.cliEnv])if(r)for(let[e,n]of Object.entries(r)){if(nl(e))throw nu(e);t[e]=n}return{values:t}}({builtins:function(e){let{req:t,sessionName:r,metadata:n,resolvedPath:i}=e,o=t.flags??{},s=t.meta?.cwd??process.cwd(),l={AD_SESSION:r,AD_FILENAME:a.relative(s,i)||i},u=o.platform??n.platform;u&&(l.AD_PLATFORM=u);let c=o.target??n.target;c&&(l.AD_TARGET=c);let d=o.device;"string"==typeof d&&d.length>0&&(l.AD_DEVICE=d);let p=o.artifactsDir;return"string"==typeof p&&p.length>0&&(l.AD_ARTIFACTS=p),l}({req:y,sessionName:n,metadata:g,resolvedPath:p}),fileEnv:g.env,shellEnv:nc(nf(r.flags?.replayShellEnv)),cliEnv:nd(np(r.flags?.replayEnv))}),I=r.flags?.replayUpdate===!0,_=s??o.get(n)?.trace?.outPath,N=0;for(let e=0;e<v.length;e+=1){let t=v[e];if(!t||"replay"===t.command)continue;let r=await iL({req:y,sessionName:n,action:t,scope:S,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l});if(r.ok){iV(r).forEach(e=>f.add(e));continue}if(!I)return iE(r,t,e,p,[...f]);let a=await aI({action:t,sessionName:n,logPath:i,sessionStore:o});if(!a)return iE(r,t,e,p,[...f]);if(v[e]=a,!(r=await iL({req:y,sessionName:n,action:a,scope:S,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l})).ok)return iE(r,a,e,p,[...f]);iV(r).forEach(e=>f.add(e)),N+=1}return I&&N>0&&function(e,r,n){let a=[];if(n){let e=n.device.kind?` kind=${n.device.kind}`:"",t=n.device.target?` target=${n.device.target}`:"";a.push(`context platform=${n.device.platform}${t} device=${ee(n.device.name)}${e} theme=unknown`)}for(let e of r){var i;a.push((i=e,b(i,{runtimeIncludeAllPositionals:!0})))}let o=`${a.join("\n")}
29
- `,s=`${e}.tmp-${process.pid}-${Date.now()}`;t.writeFileSync(s,o),t.renameSync(s,e)}(p,v,o.get(n)),{ok:!0,data:{replayed:v.length,healed:N,session:n,artifactPaths:[...f]}}}catch(t){let e=u(t);return R(e.code,e.message,f.size>0?{artifactPaths:[...f]}:void 0)}}function iE(e,t,r,n,a=[]){if(e.ok)return e;let i=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${i} (${et(t)}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:n,step:i,action:t.command,positionals:t.positionals??[],artifactPaths:a}}}}function iV(e){if(!e.ok||!e.data)return[];let r=[];if("string"==typeof e.data.path&&r.push(e.data.path),"string"==typeof e.data.outPath&&r.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let t of e.data.artifacts){if(!t||"object"!=typeof t)continue;let e="string"==typeof t.localPath?t.localPath:void 0,n="string"==typeof t.path?t.path:void 0;e?r.push(e):n&&r.push(n)}return[...new Set(r.filter(e=>(function(e){try{return t.statSync(e).isFile()}catch{return!1}})(e)))]}function iU(e){return"string"==typeof e?e.includes("${"):Array.isArray(e)?e.some(iU):!!e&&"object"==typeof e&&Object.values(e).some(iU)}async function iT(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}=e;return"replay"===t.command?await iC({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}):"test"===t.command?await av({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,target:s,requestId:l,artifactsDir:u,artifactPaths:c,tracePath:d})=>{let p=function(e){let{parentFlags:t,platform:r,target:n,artifactsDir:a}=e;return void 0===r&&void 0===n&&void 0===a?t:{...t??{},...void 0!==r?{platform:r}:{},...void 0!==n?{target:n}:{},...void 0!==a?{artifactsDir:a}:{}}}({parentFlags:t.flags,platform:o,target:s,artifactsDir:u});return await iC({req:{...t,command:"replay",session:r,positionals:[e],flags:p,meta:l?{...t.meta??{},requestId:l}:t.meta},sessionName:r,logPath:n,sessionStore:a,tracePath:d,invoke:async e=>{var t;return t=await i(e),c&&iV(t).forEach(e=>c.add(e)),t}})},cleanupSession:async e=>{a.get(e)&&await B({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:n,sessionStore:a})}}):null}let iG=tm.inventory,ij=tm.state,iq=tm.observability,iK=tm.replay,iB={...Object.fromEntries([...iG].map(e=>[e,!0])),...Object.fromEntries([...ij].map(e=>[e,!0])),...Object.fromEntries([...iq].map(e=>[e,!0])),...Object.fromEntries([...iK].map(e=>[e,!0])),[tf.runtime]:!0,[th.clipboard]:!0,[th.keyboard]:!0,[th.install]:!0,[th.reinstall]:!0,[tf.installSource]:!0,[tf.releaseMaterializedPaths]:!0,[th.push]:!0,[th.triggerAppEvent]:!0,[th.open]:!0,[th.batch]:!0,[th.close]:!0};async function iH(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,command:i,positionals:o,recordPositionals:s,deriveNextSession:l}=e,u=a.get(r),c=t.flags??{},d=I(i,u,c);if(d)return d;let p=await g({session:u,flags:c,ensureReady:!0});if(!eA(i,p))return R("UNSUPPORTED_OPERATION",`${i} is not supported on this device`);let f=await m(p,i,o,t.flags?.out,{...Y(n,t.flags,u?.appBundleId,u?.trace?.outPath)});if(u){let e=l?await l(u,f,p):u;a.recordAction(e,{command:i,positionals:s??o,flags:t.flags??{},result:f??{}}),e!==u&&a.set(r,e)}return{ok:!0,data:f??{}}}async function iW(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,i=a.get(r),o=t.flags??{},s=I(th.clipboard,i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return R("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await g({session:i,flags:o,ensureReady:!0});if(!eA(th.clipboard,u))return R("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let c=await m(u,th.clipboard,t.positionals??[],t.flags?.out,{...Y(n,t.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:c??{}}),{ok:!0,data:{platform:u.platform,...c??{}}}}async function iz(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i,invokeReplayAction:o,androidAdbExecutor:s}=e;if(iG.has(t.command))return await ro({req:t,sessionName:r,sessionStore:a});if("runtime"===t.command)return await tk({req:t,sessionName:r,sessionStore:a});if(ij.has(t.command))return await rd({req:t,sessionName:r,sessionStore:a});if(t.command===th.clipboard)return await iW({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===th.keyboard){let e=a.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i&&"enter"!==i&&"return"!==i||"ios"!==eI((t.flags??{}).platform)?await iH({req:t,sessionName:r,logPath:n,sessionStore:a,command:th.keyboard,positionals:t.positionals??[]}):R("SESSION_NOT_FOUND","iOS keyboard action requires an active session so the target app stays foregrounded. Run open first.")}if(iq.has(t.command))return await r9({req:t,sessionName:r,sessionStore:a,androidAdbExecutor:s});if(t.command===th.install||t.command===th.reinstall)return await ra({req:t,command:t.command,sessionName:r,sessionStore:a,deployOps:t.command===th.install?rn:rr});if(t.command===tf.installSource)return await tb({req:t,sessionName:r,sessionStore:a});if(t.command===tf.releaseMaterializedPaths)return await tS({req:t});if(t.command===th.push){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await iH({req:t,sessionName:r,logPath:n,sessionStore:a,command:th.push,positionals:[i,"file"===(e=eo(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>Q.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):R("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return t.command===th.triggerAppEvent?await iH({req:t,sessionName:r,logPath:n,sessionStore:a,command:th.triggerAppEvent,positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,n=r?await t1(e.device,r,e.appBundleId,tQ)??e.appBundleId:e.appBundleId;return{...e,appBundleId:n}}}):t.command===th.open?await rt({req:t,sessionName:r,logPath:n,sessionStore:a}):iK.has(t.command)?await iT({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o??i}):t.command===th.batch?await ri(t,r,i):t.command===th.close?await B({req:t,sessionName:r,logPath:n,sessionStore:a}):null}export{tg as session_namespaceObject};
24
+ `;function as(e){if("string"!=typeof e)throw new d("COMMAND_FAILED",`Maestro runScript json() expected a string body, received ${typeof e}.`);if(0===e.trim().length)throw new d("COMMAND_FAILED","Maestro runScript json() received an empty body. Check the preceding http response status and setup server output.");try{return JSON.parse(e,al)}catch(t){throw new d("COMMAND_FAILED",`Maestro runScript json() could not parse response body: ${t instanceof Error?t.message:String(t)}`,{bodyPreview:e.slice(0,1e3)},t instanceof Error?t:void 0)}}function al(e,t){return"__proto__"===e||"constructor"===e||"prototype"===e?void 0:t}let au={launchApp:({value:e,config:t,context:r})=>[nU(e,t,r)],tapOn:({value:e,context:t})=>[function(e,t){if("string"==typeof e)return nk(n0,[n9(nC(e,t))],at(e));if(nO(e)&&"string"==typeof e.point){nD(e,"tapOn",["point","repeat","delay","optional","label"]);let t=nH(e.point);return"percent"===t.kind?nk(n1,[String(t.x),String(t.y)],ae(e)):nk("click",[String(t.x),String(t.y)],ae(e))}nO(e)&&nD(e,"tapOn",["id","text","childOf","enabled","index","selected","repeat","delay","optional","label"]);let r=at(e);return nk(n0,[n8(e,"tapOn",["repeat","delay","optional","label","index","childOf"],t),...function(e,t){if(!nO(e))return[];let r={};if(void 0!==e.index){if("number"!=typeof e.index||!Number.isInteger(e.index)||e.index<0)throw new d("INVALID_ARGS","tapOn.index must be a non-negative integer.");r.index=e.index}return void 0!==e.childOf&&(r.childOf=n8(e.childOf,"tapOn.childOf",[],t)),Object.keys(r).length>0?[JSON.stringify(r)]:[]}(e,t)],r)}(e,t)],doubleTapOn:({value:e,context:t})=>[function(e,t){if(nO(e)&&"string"==typeof e.point){nD(e,"doubleTapOn",["point","delay"]);let t=nK(e.point);return nk("click",[String(t.x),String(t.y)],ar(e))}return nO(e)&&nD(e,"doubleTapOn",["id","text","enabled","selected","delay"]),nk("click",[n8(e,"doubleTapOn",["delay"],t)],ar(e))}(e,t)],longPressOn:({value:e,context:t})=>[function(e,t){if(nO(e)&&"string"==typeof e.point){nD(e,"longPressOn",["point"]);let t=nK(e.point);return nk("longpress",[String(t.x),String(t.y),"3000"])}return nO(e)&&nD(e,"longPressOn",["id","text","enabled","selected"]),nk("click",[n8(e,"longPressOn",[],t)],{holdMs:3e3})}(e,t)],inputText:({value:e,context:t})=>[nk("type",[nC(function(e){if("string"==typeof e)return e;if(!nO(e))throw new d("INVALID_ARGS","inputText expects a string or map.");if(nD(e,"inputText",["text","label"]),"string"!=typeof e.text)throw new d("INVALID_ARGS","inputText map requires a string text field.");return e.text}(e),t)])],eraseText:({value:e})=>[n2(e)],pasteText:({value:e,context:t,name:r})=>[nk("type",[nC(nF(r,e),t)])],openLink:({value:e,config:t,context:r,name:n})=>{var a,i,o,s,l,u;let c;return[(a=e,i=t,o=r,s=n,c=nC((l=a,u=s,"string"==typeof l?l:nO(l)?(nD(l,u,["link"]),nF(`${u}.link`,l.link)):nF(u,l)),o),("ios"===o.platform||"android"===o.platform)&&i.appId?nk("open",[nC(n$(i,s),o),c],"ios"===o.platform?{maestro:{prewarmRunnerBeforeOpen:!0}}:void 0):nk("open",[c]))]},assertVisible:({value:e,context:t,name:r})=>[nk(nW,[n8(e,r,[],t),"7000"])],assertNotVisible:({value:e,context:t,name:r})=>[nk(nz,[n8(e,r,[],t)])],extendedWaitUntil:({value:e,context:t})=>(function(e,t){if(!nO(e))throw new d("INVALID_ARGS","extendedWaitUntil expects a map.");nD(e,"extendedWaitUntil",["visible","notVisible","timeout"]);let r=e.visible??e.notVisible;if(void 0===r)throw nV("Only Maestro extendedWaitUntil.visible/notVisible is supported.");let n=n8(r,"extendedWaitUntil",[],t),a=String(nP(e,3e4));return void 0!==e.notVisible?[nk(nz,[n,a])]:[nk(nW,[n,a],{maestro:{allowAlreadyPastLoading:!0}})]})(e,t),takeScreenshot:({value:e,context:t,name:r})=>[nk("screenshot",[nC(nF(r,e),t)])],scroll:({value:e})=>[function(e){if(null!=e)throw nV("Maestro scroll options are not supported yet.");return nk("scroll",["down"])}(e)],scrollUntilVisible:({value:e,context:t})=>(function(e,t){if("string"==typeof e)return[nk(nY,[n9(nC(e,t)),"5000","down"])];if(!nO(e))throw new d("INVALID_ARGS","scrollUntilVisible expects a string or map.");nD(e,"scrollUntilVisible",["element","direction","timeout"]);let r=n8(e.element,"scrollUntilVisible.element",[],t),n="string"==typeof e.direction?n5(e.direction,"scrollUntilVisible.direction"):"down";return[nk(nY,[r,String(nP(e,5e3)),n])]})(e,t),swipe:({value:e,context:t})=>[function(e,t){var r,n,a;let i;if(!nO(e))throw new d("INVALID_ARGS","swipe expects a map.");nD(e,"swipe",["start","end","direction","duration","from","label"]);let o=e.from??("string"==typeof e.label?e.label:void 0);return void 0!==o?(r=e,n=o,a=t,i=n6("string"==typeof r.direction?r.direction:"up"),nk(nQ,[n8(n,"swipe.from",[],a),i,...n4(r)])):"string"==typeof e.direction?nk(nZ,["direction",n6(e.direction),...n4(e)]):function(e){let{start:t,end:r}=function(e){if("string"==typeof e.start&&"string"==typeof e.end)return{start:nH(e.start),end:nH(e.end)};throw nV("Only Maestro swipe start/end coordinates are supported.")}(e);var n=t,a=r,i=n3(e.duration);if("absolute"===n.kind&&"absolute"===a.kind)return nk("swipe",[String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);if("percent"===n.kind&&"percent"===a.kind)return nk(nZ,["percent",String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);throw nV("Maestro swipe start/end must both be absolute pixels or both be percentages.")}(e)}(e,t)],hideKeyboard:()=>[nk("keyboard",["dismiss"])],pressKey:({value:e})=>[function(e){let t=nF("pressKey",e).toLowerCase();if("back"===t)return nk("back");if("enter"===t||"return"===t)return nk(nJ);if("home"===t)return nk("home");throw nV(`Maestro pressKey "${t}" is not supported yet.`)}(e)],back:()=>[nk("back")],waitForAnimationToEnd:({value:e})=>[nk(nX,[String(nP(e,15e3))])],stopApp:({value:e,config:t,context:r})=>[nT(e,t,r)],runScript:({value:e,context:t})=>{let r;return[nk(nB,[function(e,t){if(a.isAbsolute(e))return e;if(!t.baseDir)throw new d("INVALID_ARGS","runScript file paths require replay input to have a source path.");return a.resolve(t.baseDir,e)}((r=function(e,t){if("string"==typeof e)return{file:nC(e,t),env:{}};if(!nO(e))throw new d("INVALID_ARGS","runScript expects a file path string or map.");return nD(e,"runScript",["file","env"]),{file:nC(nF("runScript.file",e.file),t),env:Object.fromEntries(Object.entries(nL(e.env,"runScript.env")).map(([e,r])=>[e,nC(r,t)]))}}(e,t)).file,t)],{...Object.keys(r.env).length>0?{maestro:{runScriptEnv:r.env}}:{}})]},runFlow:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){if("string"==typeof e)return n.parseRunFlowFile(nC(e,r),r).actions;if(!nO(e))throw new d("INVALID_ARGS","runFlow expects a file path string or map.");nD(e,"runFlow",["file","commands","env","when","label"]);let i=function(e,t){var r,n;if(null==e)return{shouldRun:!0};if(!nO(e))throw new d("INVALID_ARGS","runFlow.when expects a map.");return(nD(e,"runFlow.when",["platform","visible","notVisible","true"]),!function(e,t){if(void 0!==e.true&&!function(e,t){let r;if("boolean"==typeof e)return e;if("string"!=typeof e)throw new d("INVALID_ARGS","runFlow.when.true expects a boolean or expression string.");return new an(function(e){let t=[],r=0;for(;r<e.length;){var n,a;let i=e.slice(r),o=(n=i,/^\s+/.exec(n)?.[0].length??0);if(o>0){r+=o;continue}let s=function(e){let t="maestro.platform";return e.startsWith(t)?{token:{type:"platform"},length:t.length}:null}(a=i)??function(e){let t=/^(==|!=|&&|\|\|)/.exec(e)?.[1];return t?{token:{type:"operator",value:t},length:t.length}:null}(a)??function(e){let t=e[0];return"("===t||")"===t?{token:{type:"paren",value:t},length:1}:null}(a)??function(e){let t=/^(['"])(.*?)\1/.exec(e);return t?{token:{type:"string",value:t[2]??""},length:t[0].length}:null}(a)??function(e){let t=/^(true|false)\b/.exec(e)?.[1];return t?{token:{type:"boolean",value:"true"===t},length:t.length}:null}(a);if(s){t.push(s.token),r+=s.length;continue}throw new d("INVALID_ARGS",`Unsupported runFlow.when.true expression near "${i.slice(0,24)}".`)}return t}((r=nC(e,t).trim()).startsWith("${")&&r.endsWith("}")?r.slice(2,-1).trim():r),{platform:t.platform}).parse()}(e.true,t))return!1;if(void 0===e.platform)return!0;let r=function(e,t){if("string"!=typeof e)throw new d("INVALID_ARGS",`${t} expects Android, iOS, or Web.`);let r=e.trim().toLowerCase();if("android"===r||"ios"===r||"web"===r)return r;throw new d("INVALID_ARGS",`${t} expects Android, iOS, or Web.`)}(e.platform,"runFlow.when.platform");if(!t.platform)throw new d("INVALID_ARGS","Maestro runFlow.when.platform requires replay to be run with --platform ios|android.");return r===t.platform}(e,t))?{shouldRun:!1}:{shouldRun:!0,...(r=e,n=t,{...void 0!==r.visible?{visibleSelector:n8(r.visible,"runFlow.when.visible",[],n)}:{},...void 0!==r.notVisible?{notVisibleSelector:n8(r.notVisible,"runFlow.when.notVisible",[],n)}:{}})}}(e.when,r);if(!i.shouldRun)return[];let o={...r,env:{...r.env,...nL(e.env,"runFlow.env"),...r.envOverrides}};return function(e,t){let{visibleSelector:r,notVisibleSelector:n}=t;if(!r&&!n)return e;if(r&&n)throw nV("Maestro runFlow.when cannot combine visible and notVisible yet.");let a=r?"visible":"notVisible",i=r??n??"";return[aa("runFlow.when",[a,i],{kind:"maestroRunFlowWhen",mode:a,selector:i,actions:e})]}(function(e,t,r,n,a){if("string"==typeof e.file)return n.parseRunFlowFile(nC(e.file,r),r).actions;if(Array.isArray(e.commands))return a(nR(e.commands),t,r,n);throw new d("INVALID_ARGS","runFlow map requires either file or commands.")}(e,t,o,n,a),i)})(e,t,r,n,ap),repeat:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i;if(!nO(e))throw new d("INVALID_ARGS","repeat expects a map.");if(nD(e,"repeat",["times","commands","while"]),void 0!==e.while)throw nV("Maestro repeat.while is not supported yet. Only deterministic repeat.times is supported.");let o=(i=e.times,ai(i,r,"repeat.times"));if(!Array.isArray(e.commands))throw new d("INVALID_ARGS","repeat requires a commands list.");if(o>1e3)throw new d("INVALID_ARGS","repeat.times must be <= 1000 for deterministic replay expansion.");let s=nR(e.commands);return Array.from({length:o}).flatMap(()=>a(s,t,r,n))})(e,t,r,n,ap),retry:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i,o;if(!nO(e))throw new d("INVALID_ARGS","retry expects a map.");if(nD(e,"retry",["maxRetries","commands"]),!Array.isArray(e.commands))throw new d("INVALID_ARGS","retry requires a commands list.");let s=(i=e.maxRetries,o=r,void 0===i?1:ai(i,o,"retry.maxRetries")),l=a(nR(e.commands),t,r,n);return[aa("retry",[String(s)],{kind:"retry",maxRetries:s,actions:l})]})(e,t,r,n,ap)},ac={launchApp:(e,t)=>[nU(void 0,e,t)],scroll:()=>[nk("scroll",["down"])],hideKeyboard:()=>[nk("keyboard",["dismiss"])],eraseText:()=>[n2(void 0)],back:()=>[nk("back")],waitForAnimationToEnd:()=>[nk(nX,["15000"])],stopApp:(e,t)=>[nT(void 0,e,t)]};function ad(e,t,r,n,a){try{return function(e,t,r,n){if("string"==typeof e){var a,i,o;let n;return a=e,i=t,o=r,(n=ac[a])?n(i,o):nE(a)}let s=Object.entries(e);if(1!==s.length)throw new d("INVALID_ARGS","Maestro command maps must contain exactly one command.");let[l,u]=s[0],c=au[l];return c?c({value:u,config:t,context:r,deps:n,name:l}):nE(l)}(e,t,n,a)}catch(e){if(e instanceof d&&!/\bline \d+\b/.test(e.message))throw new d(e.code,`${e.message} (line ${r})`,e.details);throw e}}function ap(e,t,r,n){return e.flatMap((e,a)=>ad(e,t,a+1,r,n))}function af(e,t){let{config:r,commands:n}=ah(am(e)),a={...t,env:{...t.env,...r.env??{},...t.envOverrides}},{actions:i,actionLines:o}=function(e){let{config:t,commands:r,commandLines:n,context:a}=e,i=[...t.onFlowStart??[],...r,...t.onFlowComplete??[]],o=[...Array.from({length:t.onFlowStart?.length??0},()=>1),...n,...Array.from({length:t.onFlowComplete?.length??0},()=>n.at(-1)??1)],s=[],l=[];for(let[e,r]of i.entries()){let n=o[e]??e+1,i=ad(r,t,n,a,{parseRunFlowFile:aw});s.push(...i),i.forEach(()=>l.push(n))}return function(e,t){let r=[],n=[];for(let a=0;a<e.length;a+=1){let i=e[a],o=function(e,t,r){var n;let a=function(e,t,r){let n=e[r],a=e[r+1],i=e[r+2];if(i?.command!==nJ||n.flags?.maestro?.optional===!0)return null;let o=function(e){if(e?.command!=="type"||e.flags&&Object.keys(e.flags).length>0)return null;let[t,...r]=e.positionals??[];return r.length>0||"string"!=typeof t?null:t}(a),s=function(e){if(e?.command!==n0)return null;let[t,...r]=e.positionals??[];return r.length>0||"string"!=typeof t?null:t}(n);return a&&null!==o&&null!==s?{action:n,nextAction:a,pressEnterAction:i,tapSelector:s,typedAfterTap:o,line:t[r]??1}:null}(e,t,r);if(!a)return null;let{action:i,nextAction:o,pressEnterAction:s,tapSelector:l,typedAfterTap:u,line:c}=a;return(n=l,/\b(input|textfield|textarea|field|email|password|username|search|query)\b/i.test(n.replace(/([a-z])([A-Z])/g,"$1 $2")))?{actions:[{...i,command:"wait",positionals:[l,"30000"]},{...o,command:"fill",positionals:[l,u],flags:i.flags},s],actionLines:[c,c,t[r+2]??c],consumed:3}:{actions:[function(e){let t={...e.flags?.maestro??{}};return delete t.allowNonHittableCoordinateFallback,{...e,flags:{...e.flags??{},maestro:{...t}}}}(i)],actionLines:[c],consumed:1}}(e,t,a);if(o){r.push(...o.actions),n.push(...o.actionLines),a+=o.consumed-1;continue}r.push(i),n.push(t[a]??1)}return{actions:r,actionLines:n}}(s,l)}({config:r,commands:n,commandLines:function(e){let t=e.split(/\r?\n/),r=t.findIndex(e=>"---"===e.trim()),n=-1===r?0:r+1,a=[];for(let e=n;e<t.length;e+=1)/^-\s+/.test(t[e]??"")&&a.push(e+1);return a}(e),context:a});return{actions:i,actionLines:o,metadata:{env:r.env}}}function am(e){let t=o(e);for(let e of t)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new d("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return t.map(e=>e.toJSON()).filter(e=>null!==e)}function ah(e){if(0===e.length)throw new d("INVALID_ARGS","Maestro flow is empty.");if(Array.isArray(e[0]))return{config:{},commands:nR(e[0])};let t=function(e){if(!nO(e))throw new d("INVALID_ARGS","Maestro flow config must be a YAML map.");return{..."string"==typeof e.name&&e.name.length>0?{name:e.name}:{},..."string"==typeof e.appId&&e.appId.length>0?{appId:e.appId}:{},...nO(e.env)?{env:nL(e.env,"env")}:{},...Array.isArray(e.onFlowStart)?{onFlowStart:nR(e.onFlowStart)}:{},...Array.isArray(e.onFlowComplete)?{onFlowComplete:nR(e.onFlowComplete)}:{}}}(e[0]),r=e[1];if(!Array.isArray(r))throw new d("INVALID_ARGS","Maestro flow must contain a command list after the YAML document separator.");return{config:t,commands:nR(r)}}function aw(e,r){let n=function(e,t){if(a.isAbsolute(e))return e;if(!t.baseDir)throw new d("INVALID_ARGS","runFlow file paths require replay input to have a source path.");return a.resolve(t.baseDir,e)}(e,r);if(r.visitedPaths.has(n))throw new d("INVALID_ARGS",`Maestro runFlow cycle detected at ${n}.`);let i=t.readFileSync(n,"utf8"),o=new Set(r.visitedPaths);return o.add(n),af(i,{...r,baseDir:a.dirname(n),visitedPaths:o})}let ag=/[*?[\]{}]/;function ay(e){return"maestro"===e}let av=["failed to start daemon","runner did not accept connection","xcodebuild exited early","device is offline","device offline","device unauthorized"];function aA(e){var t,r,n,a;let i,o,s="ok"in(t=e)?t.ok?null:t.error:"failed"===t.status?t.error:null;return!!s&&(r=s.details,"timeout_cleanup_pending"===(i="string"==typeof r?.reason?r.reason:"")||!!i&&eB(i)||(n=s.code,a=s.message,o=`${n}
25
+ ${a}`.toLowerCase(),av.some(e=>o.includes(e))))}async function ab(e){let r,n,{filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:d,artifactsDir:p,runReplay:f,cleanupSession:m}=e;R(s);let h=new Set,w=!1,g=Date.now(),y=function(e){let{artifactsDir:r,artifactPaths:n,filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:c}=e;if(!r)return;let d=a.join(r,"replay-timing.ndjson");return t.mkdirSync(a.dirname(d),{recursive:!0}),t.writeFileSync(d,""),n.add(d),a_(d,{type:"replay_test_attempt_start",ts:new Date().toISOString(),replayPath:i,session:o,requestId:s,timeoutMs:l,platform:u,target:c}),d}({artifactsDir:p,artifactPaths:h,filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:d}),v=f({filePath:i,sessionName:o,platform:u,target:d,requestId:s,artifactsDir:p,artifactPaths:h,tracePath:y}).catch(e=>({ok:!1,error:c(e)})).finally(()=>{ey(s)});try{return n="number"==typeof l?await Promise.race([v,new Promise(e=>{r=setTimeout(()=>{w=!0,ep(s),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}}}}(l,[...h]))},l)})]):await v,a_(y,{type:"replay_test_attempt_stop",ts:new Date().toISOString(),session:o,ok:n.ok,timedOut:w,durationMs:Date.now()-g,errorCode:n.ok?void 0:n.error.code}),n}finally{var A;r&&clearTimeout(r),w&&(await aS(v)||((A=n)&&!A.ok&&(A.error.details={...A.error.details??{},reason:"timeout_cleanup_pending",timeoutCleanupPending:!0}),e6({level:"warn",phase:"test_timeout_cleanup_race",data:{session:o,requestId:s,graceMs:2e3}}),aI({replayPromise:v,cleanupSession:m,sessionName:o,requestId:s})));let e=Date.now();try{a_(y,{type:"replay_test_cleanup_start",ts:new Date().toISOString(),session:o}),await m(o),a_(y,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!0,durationMs:Date.now()-e})}catch(r){let t=c(r);a_(y,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!1,durationMs:Date.now()-e,errorCode:t.code}),e6({level:"warn",phase:"test_cleanup_failed",data:{session:o,error:t.message}})}}}async function aS(e){return await Promise.race([e.then(()=>!0),l(2e3).then(()=>!1)])}async function aI(e){let{replayPromise:t,cleanupSession:r,sessionName:n,requestId:a}=e;try{await t}finally{try{await r(n)}catch(e){e6({level:"warn",phase:"test_late_cleanup_failed",data:{session:n,requestId:a,error:c(e).message}})}}}function a_(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
26
+ `)}async function aN(e){let{req:r,sessionName:n,runReplay:i,cleanupSession:o}=e;if((r.positionals?.length??0)===0)return L("INVALID_ARGS","test requires at least one path or glob");try{var s,l,c,p,f,m;let e,u,h,w,g,y=function(e){var r,n,i,o,s,l;let{inputs:u,cwd:c,platformFilter:p,replayBackend:f}=e,m=(r=f,new Set(ay(r)?[".ad",".yaml",".yml"]:[".ad"])),h=c??process.cwd(),w=[...new Set(u.flatMap(e=>(function(e,r,n){var i,o;let s=en.expandHome(e,r);if(t.existsSync(s)){let r=t.statSync(s);if(r.isDirectory())return[...n].map(e=>`**/*${e}`).flatMap(e=>t.globSync(e,{cwd:s}).map(e=>a.join(s,e)));if(r.isFile()){if(!n.has(a.extname(s)))throw new d("INVALID_ARGS",`test does not support this file type: ${e}`);return[s]}return[]}if(i=e,!ag.test(i)&&(o=s,!ag.test(o)))throw new d("INVALID_ARGS",`test input not found: ${e}`);let l=a.isAbsolute(s)?s:e;return t.globSync(l,{cwd:a.isAbsolute(s)?void 0:r}).map(e=>a.isAbsolute(e)?e:a.resolve(r,e)).filter(e=>n.has(a.extname(e))&&function(e){try{return t.statSync(e).isFile()}catch{return!1}}(e))})(e,h,m)))].map(e=>a.normalize(e)).sort((e,t)=>e.localeCompare(t)),g=[];for(let e of w){let r=t.readFileSync(e,"utf8"),u=n_(r),c=(n=r,i=e,o=f,ay(o)&&".ad"!==a.extname(i)?function(e){let{config:t}=ah(am(e));return t.name}(n):void 0);if(!p){g.push({kind:"run",path:e,title:c,metadata:u});continue}if(!u.platform){ay(f)?g.push({kind:"run",path:e,title:c,metadata:u}):g.push({kind:"skip",path:e,reason:"skipped-by-filter",message:`missing platform metadata for --platform ${p}`});continue}s=p,l=u.platform,("apple"===s?"apple"===l||"ios"===l||"macos"===l:l===s)&&g.push({kind:"run",path:e,title:c,metadata:u})}if(0===g.filter(e=>"run"===e.kind).length){let e=p?` for --platform ${p}`:"";throw new d("INVALID_ARGS",`No replay tests matched${e}.`)}return g}({inputs:r.positionals,cwd:r.meta?.cwd,platformFilter:r.flags?.platform,replayBackend:r.flags?.replayBackend}),v=(s=r.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),A=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:n}=e,i=en.expandHome(t??".agent-device/test-artifacts",r);return a.join(i,n)}({artifactsDir:"string"==typeof r.flags?.artifactsDir?r.flags.artifactsDir:void 0,cwd:r.meta?.cwd,suiteInvocationId:v}),b=[],S=Date.now(),I=0;for(let[e,t]of y.entries()){if("skip"===t.kind){eP({type:"replay-test",file:t.path,status:"skip",index:e+1,total:y.length,message:t.message}),b.push({file:t.path,status:"skipped",durationMs:0,reason:t.reason,message:t.message});continue}I+=1;let a=await aM({entry:t,sessionName:n,suiteInvocationId:v,caseIndex:I-1,cwd:r.meta?.cwd,requestId:r.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))}(r.flags?.retries,t.metadata.retries),timeoutMs:(l=r.flags?.timeoutMs,c=t.metadata.timeoutMs,"number"==typeof l?l:c),suiteArtifactsDir:A,suiteIndex:e+1,suiteTotal:y.length,runReplay:i,cleanupSession:o});if(b.push(a),r.flags?.failFast===!0||aA(a))break}let _=(p=y.length,f=b,m=Date.now()-S,e=f.filter(e=>"passed"===e.status).length,h=(u=f.filter(e=>"failed"===e.status)).length,w=f.filter(e=>"skipped"===e.status).length,g=e+h,{total:p,executed:g,passed:e,failed:h,skipped:w,notRun:Math.max(0,p-g-w),durationMs:m,failures:u,tests:f});return{ok:!0,data:_}}catch(t){let e=u(t);return L(e.code,e.message)}}async function aM(e){var r,n;let i,o,{entry:s,sessionName:l,suiteInvocationId:u,caseIndex:c,cwd:d,requestId:p,retries:f,timeoutMs:m,suiteArtifactsDir:h,suiteIndex:w,suiteTotal:g,runReplay:y,cleanupSession:v}=e,A=Date.now(),b=a.join(h,(r=s.path,(0===(o=d?a.relative(d,r):a.basename(r)).length||o.startsWith("..")?a.basename(r):o).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),S="",I=0,_=0,N=[];for(let e=0;e<=f;e+=1){I=e+1;let r=Date.now(),o=function(e,t,r,n,i=0){let o=a.basename(r,a.extname(r)).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`${e}:test:${t}:${n+1}${o?`-${o}`:""}:attempt-${i+1}`}(l,u,s.path,c,e),d=a.join(b,`attempt-${I}`);n=s.path,t.mkdirSync(d,{recursive:!0}),function(e,r){let n=a.join(r,"replay.ad");if(t.copyFileSync(e,n),!function(e){let t=a.extname(e).toLowerCase();return".yml"===t||".yaml"===t}(e))return;let i=a.join(r,a.basename(e));a.resolve(i)!==a.resolve(n)&&t.copyFileSync(e,i)}(n,d);let h=function(e){let{requestId:t,suiteInvocationId:r,filePath:n,caseIndex:i,attemptIndex:o}=e;return es(`${t??r}:test:${i+1}:${a.basename(n)}:attempt:${o+1}`,r)}({requestId:p,suiteInvocationId:u,filePath:s.path,caseIndex:c,attemptIndex:e}),A=await ab({filePath:s.path,sessionName:o,requestId:h,timeoutMs:m,platform:s.metadata.platform,target:s.metadata.target,artifactsDir:d,runReplay:y,cleanupSession:v});if(_=Date.now()-r,!function(e){let{response:r,filePath:n,sessionName:i,attempts:o,maxAttempts:s,attemptArtifactsDir:l}=e,u=[...function(e){let t=e.ok?e.data?.artifactPaths:e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e))]:[]}(r)];r.ok||"string"!=typeof r.error.logPath||u.push(r.error.logPath);let c=function(e,r){let n=[],i=new Map;for(let o of e){if(!function(e){try{return t.statSync(e).isFile()}catch{return!1}}(o))continue;let e=function(e,t){let r=a.extname(e),n=r?e.slice(0,-r.length):e,i=t.get(e)??0;return(t.set(e,i+1),0===i)?e:`${n}-${i+1}${r}`}(a.basename(o),i),s=a.join(r,e);a.resolve(o)!==a.resolve(s)&&t.copyFileSync(o,s),n.push(s)}return n}(u,l),d=[`file: ${n}`,`session: ${i}`,`attempt: ${o}/${s}`,`status: ${r.ok?"passed":"failed"}`];if(r.ok){let e="number"==typeof r.data?.replayed?r.data.replayed:0,t="number"==typeof r.data?.healed?r.data.healed:0;d.push(`replayed: ${e}`,`healed: ${t}`)}else d.push(`code: ${r.error.code}`,`message: ${r.error.message}`),r.error.hint&&d.push(`hint: ${r.error.hint}`),r.error.diagnosticId&&d.push(`diagnosticId: ${r.error.diagnosticId}`),r.error.logPath&&d.push(`logPath: ${r.error.logPath}`),r.error.details?.reason==="timeout"&&d.push("timeoutMode: cooperative");c.length>0&&d.push(`copiedArtifacts: ${c.map(e=>a.basename(e)).join(", ")}`);let p=a.join(l,"result.txt"),f=`${d.join("\n")}
27
+ `;t.writeFileSync(p,f),r.ok||t.writeFileSync(a.join(l,"failure.txt"),f)}({response:A,filePath:s.path,sessionName:o,attempts:I,maxAttempts:f+1,attemptArtifactsDir:d}),i=A,S=o,A.ok||(N.push({attempt:I,message:A.error.message,durationMs:_}),aA(A)||e>=f))break;eP({type:"replay-test",file:s.path,title:s.title,status:"fail",index:w,total:g,attempt:I,maxAttempts:f+1,durationMs:_,retrying:!0,message:A.error.message})}let M=Date.now()-A;if(i?.ok)return eP({type:"replay-test",file:s.path,title:s.title,status:"pass",index:w,total:g,attempt:I,maxAttempts:f+1,durationMs:M,artifactsDir:b}),{file:s.path,title:s.title,session:S,status:"passed",durationMs:M,finalAttemptDurationMs:_,attempts:I,artifactsDir:b,replayed:"number"==typeof i.data?.replayed?i.data.replayed:0,healed:"number"==typeof i.data?.healed?i.data.healed:0,...N.length>0?{attemptFailures:N}:{}};let x=i?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:i?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return eP({type:"replay-test",file:s.path,title:s.title,status:"fail",index:w,total:g,attempt:I,maxAttempts:f+1,durationMs:M,artifactsDir:b,message:x.message}),{file:s.path,title:s.title,session:S,status:"failed",durationMs:M,attempts:I,artifactsDir:b,error:x}}let ax={maestro:{parse:function(e,t={}){var r;let n;return af(e,(n=(r=t).visitedPaths??new Set,r.sourcePath&&n.add(a.resolve(r.sourcePath)),{baseDir:r.sourcePath?a.dirname(r.sourcePath):void 0,platform:function(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}(r.platform),env:{},envOverrides:r.env??{},visitedPaths:n}))}}};function ak(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=void 0!==t&&/^\d+$/.test(t)?t:null,n=e8(null!==r?e.slice(0,-1):e.slice());return!n||n.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:n.selectorExpression,selectorTimeout:r}}async function aD(e){let{action:t,sessionName:r,logPath:n,sessionStore:a}=e;if(!(N(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let i=a.get(r);if(!i)return null;let o=(function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),N(e.command)){let r=function(e){let t=e.positionals??[];if("longpress"!==e.command)return t;let r=t.at(-1);return t.length>1&&aO(r)?t.slice(0,-1):t}(e),n=r[0]??"";n&&!n.startsWith("@")&&t.push(r.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}=te(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=ak(e.positionals??[]);r&&t.push(r)}return E(t).filter(e=>e.trim().length>0)})(t).map(e=>tt(e)).filter(e=>null!==e);if(0===o.length)return null;let s=N(t.command)||"fill"===t.command,l=N(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await aR(i,t,n,s,a);for(let e of o){let r=tn(u.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let n=ta(r.node,i.device.platform,{action:"fill"===t.command?"fill":N(t.command)?"click":"get"}).join(" || ");if(N(t.command))return{...t,positionals:"longpress"===t.command?function(e,t){let r="number"==typeof e.result?.durationMs?String(e.result.durationMs):function(e){let t=e.at(-1);return e.length>1&&aO(t)?t:void 0}(e.positionals??[]);return r?[t,r]:[t]}(t,n):[n]};if("fill"===t.command){let e=A(t);if(!e)continue;return{...t,positionals:[n,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,n]}}if("is"===t.command){let{predicate:e,split:r}=te(t.positionals);if(!e)continue;let a=r?.rest.join(" ").trim()??"",i=[e,n];return"text"===e&&a.length>0&&i.push(a),{...t,positionals:i}}if("wait"===t.command){let{selectorTimeout:e}=ak(t.positionals??[]),r=[n];return e&&r.push(e),{...t,positionals:r}}}return null}function aO(e){return void 0!==e&&""!==e.trim()&&Number.isFinite(Number(e))}async function aR(e,t,r,n,a){let i=ee(await m(e.device,"snapshot",[],t.flags?.out,{...et(r,{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n},e.appBundleId,e.trace?.outPath)}),{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n});return K(e,i),a.set(e.name,e),i}let aL=new WeakMap,aP=new WeakMap;function a$(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}async function aF(e){var t;let r,n="raw"===e.mode||"1"===process.env.AGENT_DEVICE_MAESTRO_RAW_SNAPSHOTS,a=await e.invoke({...e.baseReq,command:"snapshot",positionals:[],flags:{...e.baseReq.flags,noRecord:!0,..."interactive"===e.mode&&!n?{snapshotInteractiveOnly:!0}:{},...n?{snapshotRaw:!0}:{}}});return a.ok&&e.scope&&(t=e.scope,(r=H(aC(a.data)))&&aL.set(t,r)),a}function aC(e){return Array.isArray(e?.nodes)?e:void 0}function aE(e){return e.flags?.platform==="ios"}function aV(e,t){e6({level:"debug",phase:"maestro_raw_snapshot_fallback",data:{command:e,selector:t,reason:"optimized_snapshot_missed"}})}let aU=new Map([["button",0],["link",0],["textfield",0],["textview",0],["searchfield",0],["switch",0],["slider",0],["cell",1],["statictext",2]]);function aT(e,t,r,n){let a=aK(e,t,r,{allowLeadingCompositeLabelMatch:!1}),i=aG({nodes:e.nodes,matches:a,platform:r}),o=aW(e.nodes,i.matches,void 0,aj(t),n,!0);return o?{ok:!0,node:o.node,rect:o.rect,matches:i.matches.length}:{ok:!1,message:i.blockedByReactNativeOverlay?`React Native overlay is covering app content: ${t}`:a.length>0?`Maestro selector matched ${a.length} element(s), but none were visible: ${t}`:`Maestro selector did not match: ${t}`}}function aG(e){let t=e.matches.filter(t=>tf({predicate:"visible",node:t,nodes:e.nodes,platform:e.platform}).pass),r=function(e,t,r){let n=tw(e);if(!n.detected||!n.redBox)return{matches:t,blockedByReactNativeOverlay:!1};let a=th(n),i=a.filter(t=>tf({predicate:"visible",node:t,nodes:e,platform:r}).pass);if(0===i.length)return 0===a.length?{matches:[],blockedByReactNativeOverlay:!0}:{matches:t,blockedByReactNativeOverlay:!1};let o=new Set(i.map(e=>e.index)),s=t.filter(e=>o.has(e.index));return{matches:s,blockedByReactNativeOverlay:t.length>0&&0===s.length}}(e.nodes,t,e.platform);return{matches:r.matches,blockedByReactNativeOverlay:r.blockedByReactNativeOverlay}}function aq(e){return e?.platform==="android"?"android":"ios"}function aj(e){let t=tr(e).selectors.flatMap(e=>e.terms);if(0===t.length||!t.some(e=>"label"===e.key||"text"===e.key)||!t.every(e=>["label","text","id"].includes(e.key)))return null;let r=t.map(e=>"string"==typeof e.value?e.value:""),n=r[0];return n&&r.every(e=>e===n)?n:null}function aK(e,t,r,n={}){for(let a of tr(t).selectors){let t=e.nodes.filter(e=>(function(e,t,r,n){return!!to(e,t,r)||t.terms.every(t=>(function(e,t,r,n){var a,i,o;return"string"!=typeof t.value||"id"!==(a=t.key)&&"label"!==a&&"text"!==a&&"value"!==a?to(e,{raw:t.key,terms:[t]},r):aH((i=e,"id"===(o=t.key)?i.identifier:"label"===o?i.label:"value"===o?i.value:e9(i)),t.value,n)})(e,t,r,n))})(e,a,r,n));if(t.length>0)return t}return[]}function aH(e,t,r={}){var n;let a=e??"",i=tl(a),o=tl(t);if(i===o||!1!==r.allowLeadingCompositeLabelMatch&&function(e,t){if(!e||!t||!e.startsWith(t))return!1;let r=e.at(t.length);return","===r||":"===r||";"===r}(i,o))return!0;if(n=t,!/(?:\.\*|\.\+|\[[^\]]+\]|\([^)]*\)|\||\^|\$|\\[dDsSwWbB])/.test(n))return!1;try{return new RegExp(t).test(a)}catch{return!1}}function aB(e,t,r){if(t.rect&&t.rect.width>0&&t.rect.height>0)return{rect:t.rect,inherited:!1};if(t.rect)return null;let n=function(e,t,r){let n=t;for(;"number"==typeof n.parentIndex&&(n=r.get(n.parentIndex)??e[n.parentIndex]);)if(n.rect)return n.rect.width>0&&n.rect.height>0?n.rect:null;return null}(e,t,r);return n?{rect:n,inherited:!0}:null}function aW(e,t,r,n,a,i=!1,o=!1,s){var l,u,c,d,p,f,m,h,w,g,y,v,A,b,S,I,_,N,M;let x,k,D,O,R=ti(e),L=(l=e,u=t,c=R,d=n,p=r,f=a,m=i,D=(k=(x=u.map(e=>{var t;let r;return(r=aB(l,t=e,c))?{node:t,rect:r.rect,inheritedRect:r.inherited}:null}).filter(e=>!!e)).filter(e=>!e.inheritedRect)).length>0?k:x,d&&void 0===p?(h=D,w=f,g=m,O=h.filter(e=>{var t,r;let n,a;return t=e.rect,r=w,n=r?.referenceWidth??1/0,a=r?.referenceHeight??1/0,t.x<n&&t.y<a&&t.x+t.width>0&&t.y+t.height>0}),g||O.length>0?O:h):x),P=function(e,t,r,n,a,i){var o,s,l,u,c,d,p;if(void 0!==r)return t[r]??null;let f=(o=e,s=t,l=n,u=a,c=i,u&&l?function(e,t,r,n){let a=t.filter(e=>0===a3(e.node,r));if(a.length>=2){let t=aJ(e,a,r,n);if(t)return t}let i=t.filter(e=>1===a3(e.node,r));return a.length>0||i.length<2?null:aJ(e,i,r,n)}(o,s,l,c)??az(o,s,l,c):az(o,s,l,c));return(d=f,p=n,a&&p&&d)?function(e,t,r){var n,a,i,o,s,l,u,c,d,p,f,m,h,w,g,y,v,A;let b,S,I,_,N,M,x,k;if(n=t,a=r,!(("cell"===(b=ts(n.node.type??""))||"other"===b||"scrollview"===b||"scroll-area"===b)&&!(n.rect.width<120)&&!(n.rect.height<32)&&!(n.rect.height>80)&&1>=a3(n.node,a)))return null;let D=(i=e,o=t,s=r,l=ti(e),i.filter(e=>{var t,r,n;let a;return e.index!==o.node.index&&!!e.rect&&e7(i,e,o.node,l)&&(t=e,r=o.rect,n=s,!("button"!==(a=ts(t.type??""))&&"cell"!==a&&"other"!==a||1>=a3(t,n))&&!(t.rect.width<16)&&!(t.rect.height<16)&&!!a1(r,t.rect)&&aQ(r,t.rect)>=.5)}).sort((e,t)=>e.rect.x-t.rect.x));if(0===D.length)return null;let O=(I=Math.floor((S=[...D.map(e=>e.rect.width)].sort((e,t)=>e-t)).length/2),S[I]??0),R=function(e,t){let r=[],n=e.x,a=e.x+e.width;for(let i of t){let t=Math.max(e.x,i.x),o=Math.min(a,i.x+i.width);t>n&&r.push({x:n,width:t-n}),n=Math.max(n,o)}return a>n&&r.push({x:n,width:a-n}),r}(t.rect,D.map(e=>e.rect)),L=(u=t,c=r,d=R,p=O,M=d.filter(e=>{var t,r;return t=e.width,r=p,!(t<24)&&!(r<24)&&t>=.4*r&&t<=1.6*r}),x=(f=u,m=c,_=d.find(e=>1>Math.abs(e.x-f.rect.x)),N=Math.max(48,Math.min(220,8*m.length+24)),(h=f,w=m,g=_,y=N,g&&"scrollview"===ts(h.node.type??"")&&1>=a3(h.node,w)&&h.rect.width>=240&&h.rect.height>=32&&h.rect.height<=80&&g.width<=.55*h.rect.width&&g.width>=.6*y)?{x:f.rect.x,width:Math.min(N,_.width)}:null),k=M.some(e=>{var t;return t=u.rect,1>Math.abs(e.x-t.x)}),x&&!k?x:1===M.length?M[0]??null:x);return L?(v=t,A=L,{...v,rect:{x:A.x,y:v.rect.y,width:A.width,height:v.rect.height}}):null}(e,f,n)??f:f}(e,L,r,n,o,s);return y=e,v=P,A=R,b=o,S=a,v?b?(I=y,_=v,N=A,M=S,(a0(_.node)?null:e4(I,_.node,N,e=>{if(!a0(e))return null;let t=aB(I,e,N);return t&&function(e,t,r){var n,a;if(!a1(t,e)||(n=e,!((a=t).height<32||a.height>80||n.height<.75*a.height||.75>aQ(n,a))&&!(a.width<240)&&a.width>=3*n.width))return!1;let i=aY(t),o=aY(e);if(o>0&&i>30*o)return!1;if(r){let e=r.referenceWidth*r.referenceHeight;if(e>0&&i>.5*e)return!1}return!0}(_.rect,t.rect,M)?{node:e,rect:t.rect}:null}))??{node:v.node,rect:v.rect}):{node:v.node,rect:v.rect}:null}function az(e,t,r,n){return(function(e,t,r,n){var a;let i,o,s;if(!r||t.length<2)return t;let l=t.filter(e=>0===a3(e.node,r));if(l.length<2)return t;let u=ti(e),c=l.map(t=>({candidate:t,container:aX(e,t.node,u)})).filter(e=>!!e.container);if(c.length<2||c.length!==l.length)return t;let d=c.filter(e=>{var t;return t=e,c.some(e=>e!==t&&t.container.index!==e.container.index&&a2(t.container.rect,e.container.rect)>=.6)});if(d.length<2)return t;let p=(o=Math.max(...i=(a=d).map(e=>aY(e.container.rect))),(s=Math.min(...i))<=0||o<1.2*s?[]:a.filter(e=>aY(e.container.rect)===o).map(e=>e.candidate));if(p.length>0)return p;let f=function(e,t,r,n){if(!r)return[];let a=aX(e,r.node,n),i=a&&a1(a.rect,r.rect)?a:null,o=t.map(e=>({entry:e,score:function(e,t,r){if(r)return e.index===r.index?0:.6>a2(e.rect,r.rect)?1/0:Math.abs(e.index-r.index);if(a2(e.rect,t.rect)>=.6)return 0;let n=e.index-t.node.index;return n>=0?n:1e5+Math.abs(n)}(e.container,r,i)})),s=Math.min(...o.map(e=>e.score));return Number.isFinite(s)?o.filter(e=>e.score===s).map(e=>e.entry.candidate):[]}(e,d,n,u);if(f.length>0)return f;let m=Math.max(...d.map(e=>e.container.index)),h=d.filter(e=>e.container.index===m).map(e=>e.candidate);return h.length>0?h:t})(e,t,r,n).sort((e,t)=>(function(e,t,r){var n,a;let i=function(e,t,r){if(r){let n=a3(e.node,r)-a3(t.node,r);if(0!==n)return n}let n=aZ(e.node)-aZ(t.node);if(0!==n)return n;let a=Number(e.inheritedRect)-Number(t.inheritedRect);if(0!==a)return a;let i=r&&aZ(e.node)===aZ(t.node)?aY(t.rect)-aY(e.rect):aY(e.rect)-aY(t.rect);return 0!==i?i:0}(e,t,r);if(0!==i)return i;if(n=e.rect,a=t.rect,Math.round(n.x)!==Math.round(a.x)||Math.round(n.y)!==Math.round(a.y)||Math.round(n.width)!==Math.round(a.width)||Math.round(n.height)!==Math.round(a.height))return e.node.index-t.node.index;let o=(t.node.depth??0)-(e.node.depth??0);return 0!==o?o:t.node.index-e.node.index})(e,t,r))[0]??null}function aJ(e,t,r,n){let a=ti(e),i=t.filter(r=>{var n;return(n=r).rect.width>=16&&n.rect.width<=260&&n.rect.height>=24&&n.rect.height<=80&&t.some(t=>{var n,i,o,s;return n=e,i=t,o=r,s=a,!(i.node.index===o.node.index||!a1(i.rect,o.rect)||aY(i.rect)<2*aY(o.rect))&&e7(n,o.node,i.node,s)})});return az(e,i,r,n)}function aX(e,t,r){return e4(e,t,r,e=>{let t;return!e.rect||"scrollview"!==(t=ts(e.type??""))&&"scroll-area"!==t&&"list"!==t||e.rect.width<240||e.rect.height<320?null:e})}function aY(e){return e.width*e.height}function aZ(e){return aU.get(ts(e.type??""))??3}function aQ(e,t){let r=Math.max(e.y,t.y);return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-r)/Math.max(1,Math.min(e.height,t.height))}function a0(e){let t=ts(e.type??"");return!0===e.hittable||"button"===t||"link"===t||"cell"===t||"textfield"===t||"searchfield"===t||"switch"===t||"slider"===t}function a1(e,t){return t.x>=e.x-1&&t.y>=e.y-1&&t.x+t.width<=e.x+e.width+1&&t.y+t.height<=e.y+e.height+1}function a2(e,t){let r=Math.max(e.x,t.x),n=Math.min(e.x+e.width,t.x+t.width),a=Math.max(e.y,t.y);return Math.max(0,n-r)*Math.max(0,Math.min(e.y+e.height,t.y+t.height)-a)/Math.max(1,Math.min(aY(e),aY(t)))}function a3(e,t){let r=[e.label,e9(e),e.identifier,e.value].filter(e=>!!e);return r.some(e=>e===t)?0:r.some(e=>tl(e)===tl(t))?1:r.some(e=>aH(e,t))?2:3}async function a5(e){var t,r,n;let a=a7(e.positionals,{command:"assertVisible",defaultTimeoutMs:7e3});if(!a.ok)return a.response;let i=(t=e.baseReq,r=a.selector,n=a.timeoutMs,t.flags?.platform!=="ios"||t.flags?.maestro?.allowAlreadyPastLoading===!0||n<3e4?null:aj(r));return i?await a6(e,a,i):await a9(e,a)}async function a6(e,t,r){let n=Date.now(),a=await a8(e,t,r);return a.ok?ii({ok:!0,data:{selector:t.selector,nativeWait:!0,query:r,response:a.data}},t.selector,n):a}async function a8(e,t,r){return await e.invoke({...e.baseReq,command:"wait",positionals:[r,String(t.timeoutMs)]})}async function a9(e,t){let r,n=Date.now(),a=t.timeoutMs+1e3,i=!1;for(;;){let o=Date.now(),s=await ie(e,t.selector,"assertVisible",{rawFallback:!0});if(s.visible)return ii(s.response,t.selector,n);r=s.response;let l=function(e,t,r,n){var a,i,o,s,l,u;return a4(r.response)?{kind:"return",response:r.response}:(a=e,i=t.selector,o=r.snapshot,a.flags?.maestro?.allowAlreadyPastLoading===!0&&void 0!==o&&function(e,t){let r=ir(aj(e));if(!ia(r))return!1;let n=t.nodes.flatMap(e=>[e.label,e.value,e.identifier]).filter(e=>!!e?.trim()).map(e=>ir(e));return!n.some(e=>e.includes("something went wrong"))&&n.some(e=>e!==r&&!ia(e))}(i,o))?{kind:"return",response:(s=t.selector,l=t.timeoutMs,u=n,{ok:!0,data:{selector:s,alreadyPastLoading:!0,waitedMs:Date.now()-u,timeoutMs:l}})}:{kind:"continue"}}(e.baseReq,t,s,n);if("return"===l.kind)return l.response;let u=function(e){var t,r,n,a;return Date.now()-e.startedAt<e.deadlineMs?"wait":(t=e.capturedAfterDeadline,r=e.captureStartedAt,n=e.startedAt,a=e.deadlineMs,!t&&r-n<a)?"capture-again":"finish"}({captureStartedAt:o,capturedAfterDeadline:i,startedAt:n,deadlineMs:a});if("capture-again"===u){i=!0;continue}if("finish"===u)break;await ty(250)}return r??a$("COMMAND_FAILED",`Expected visible but did not match: ${t.selector}`,{selector:t.selector,timeoutMs:t.timeoutMs})}function a4(e){return!e.ok&&"COMMAND_FAILED"===e.error.code&&e.error.message.includes("React Native overlay")}function a7(e,t){let[r,n=String(t.defaultTimeoutMs)]=e;if(!r)return{ok:!1,response:a$("INVALID_ARGS",`${t.command} requires a selector.`)};let a=Number(n);return!Number.isFinite(a)||a<0?{ok:!1,response:a$("INVALID_ARGS",`${t.command} timeout must be a non-negative number.`)}:{ok:!0,selector:r,timeoutMs:a}}async function ie(e,t,r,n={}){let a=await aF(e),i=it(e,t,r,a);if(i.visible||i.infrastructureFailure||!n.rawFallback||!aE(e.baseReq)||a4(i.response))return i;aV(r,t);let o=await aF({...e,mode:"raw"});return it(e,t,r,o)}function it(e,t,r,n){var a;if(!n.ok)return{visible:!1,response:n,infrastructureFailure:!0};let i=aC(n.data);if(!i)return{visible:!1,response:a$("COMMAND_FAILED",`Unable to read snapshot data for ${r}.`),infrastructureFailure:!0};let o=aT(i,t,aq(e.baseReq.flags),H(i));return o.ok?(a=e.scope,a&&aP.set(a,{selector:t}),{visible:!0,response:{ok:!0,data:{selector:t,matches:o.matches,nodeIndex:o.node.index,nodeType:o.node.type,nodeLabel:o.node.label,nodeIdentifier:o.node.identifier,rect:o.rect}}}):{visible:!1,response:a$("COMMAND_FAILED",o.message,{selector:t}),infrastructureFailure:!1,snapshot:i}}function ir(e){return e?.trim().toLowerCase().replace(/\u2026/g,"...")??""}function ia(e){return"loading"===e||"loading..."===e}function ii(e,t,r){return e.ok?{ok:!0,data:{selector:t,...e.data,waitedMs:Date.now()-r}}:e}async function io(e){let t,r=a7(e.positionals,{command:"assertNotVisible",defaultTimeoutMs:3e3});if(!r.ok)return r.response;let n=Date.now(),a=0;for(;Date.now()-n<=r.timeoutMs;){let i=await ie(e,r.selector,"assertNotVisible");if(!i.visible&&i.infrastructureFailure)return i.response;if(i.visible)a=0,t=i.response;else{a+=1;let e=Date.now()-n;if(a>=2||e>=r.timeoutMs)return{ok:!0,data:{pass:!0,selector:r.selector,stableSamples:a,waitedMs:e,timeoutMs:r.timeoutMs}}}await ty(250)}return a>0?{ok:!0,data:{pass:!0,selector:r.selector,stableSamples:a,waitedMs:Date.now()-n,timeoutMs:r.timeoutMs}}:a$("COMMAND_FAILED",`Expected not visible but matched: ${r.selector}`,{selector:r.selector,timeoutMs:r.timeoutMs,lastResponse:t})}async function is(e){let t,r,n=Number(e.positionals[0]??15e3);if(!Number.isFinite(n)||n<0)return a$("INVALID_ARGS","waitForAnimationToEnd timeout must be a number.");let a=Date.now();for(;Date.now()-a<n;){let a=await aF(e),i=function(e,t,r){let n=function(e){if(!e.ok)return null;let t=aC(e.data);return t?JSON.stringify(t.nodes.map(e=>({index:e.index,parentIndex:e.parentIndex,type:e.type,identifier:e.identifier,label:e.label,value:e.value,rect:e.rect?{x:Math.round(e.rect.x),y:Math.round(e.rect.y),width:Math.round(e.rect.width),height:Math.round(e.rect.height)}:void 0}))):null}(e);return e.ok?n?t===n?{done:!0,response:{ok:!0,data:{stable:!0,timeoutMs:r}}}:{done:!1,signature:n}:{done:!0,response:e}:{done:!1}}(a,t,n);if(i.done)return i.response;t=i.signature??t,r=a,await ty(250)}return r?.ok===!1?r:{ok:!0,data:{stable:!1,timeoutMs:n}}}let il=.35,iu=120,ic=360,id=8,ip={minWidth:120,minHeight:70,maxHeight:200,width:168,height:48};function im(e,t){return Math.round(Math.min(ic,Math.max(iu,"number"==typeof e?e*il:0,1.5*t)))}async function ih(e){var t,r,n;let[a,i="5000",o="down"]=e.positionals;if(!a)return a$("INVALID_ARGS","scrollUntilVisible requires a selector.");let s=Number(i);if(!Number.isFinite(s)||s<=0)return a$("INVALID_ARGS","scrollUntilVisible timeout must be a positive number.");let l=aj(a),u=Math.max(1,Math.ceil(s/500)),c=null;for(let t=0;t<u;t+=1){let r=await i_(e,a,l,Math.min(500,Math.max(1,s-500*t)));if(r.ok)return r;if(c=r,t===u-1)break;let n=await e.invoke({...e.baseReq,command:"scroll",positionals:[o]});if(!n.ok)return n}return t=c,r=a,n=s,t?{ok:!1,error:{...t.error,message:`scrollUntilVisible timed out after ${n}ms for selector: ${r}. Last wait: ${t.error.message}`}}:a$("COMMAND_FAILED",`scrollUntilVisible timed out after ${n}ms for selector: ${r}`)}async function iw(e){let[t,r]=e.positionals,n=Number(t),a=Number(r);if(!Number.isFinite(n)||!Number.isFinite(a))return a$("INVALID_ARGS","tapOn percentage point requires numeric x/y values.");let i=await aF(e);if(!i.ok)return i;let o=aC(i.data);if(!o)return a$("COMMAND_FAILED","Unable to read snapshot data for Maestro percentage point tap.");let s=H(o);if(!s)return a$("COMMAND_FAILED","Unable to resolve screen size for Maestro percentage point tap.");let l=tu(s,n,a);return await e.invoke({...e.baseReq,command:"click",positionals:[String(l.x),String(l.y)]})}async function ig(e){let t=await iy(e);if(t)return t;let r=await iS(e);return r.ok?await ib(e,r,r.durationMs):r.response}async function iy(e){let[t,r,n]=e.positionals;if("direction"===t&&("left"===r||"right"===r))return await e.invoke({...e.baseReq,command:"gesture",positionals:["swipe",r,...n?[n]:[]]})}async function iv(e){var t,r,n,a;let i,[o,s]=e.positionals;if(!o)return a$("INVALID_ARGS","tapOn requires a selector.");let l=function(e){if(!e)return{ok:!0,value:null};try{let t=JSON.parse(e);return{ok:!0,value:t}}catch{return{ok:!1,response:a$("INVALID_ARGS","tapOn runtime options must be valid JSON.")}}}(s);if(!l.ok)return l.response;let u=Date.now(),c=(t=e,t.baseReq.flags?.maestro?.optional===!0?3e3:3e4);for(;Date.now()-u<c;){let t=await iN(e,o,l.value??{});if(!t.retry)return t.response;i=t.response,await ty(250)}return r=e,n=o,a=i,r.baseReq.flags?.maestro?.optional===!0?{ok:!0,data:{skipped:!0,optional:!0,selector:n}}:a??a$("COMMAND_FAILED",`tapOn timed out for selector: ${n}`)}async function iA(e){let[t,r="up",n]=e.positionals;if(!t)return a$("INVALID_ARGS","swipe.label requires a label selector.");let a=await iD(e,t,{},"swipe.label",{promoteTapTarget:!1});if(!a.ok)return a.response;let i=function(e,t){let r=tm(e.rect),n=e.frame,a=im(n?.referenceWidth,e.rect.width),i=im(n?.referenceHeight,e.rect.height),o=id,s=n?n.referenceWidth-o:r.x+a,l=n?n.referenceHeight-o:r.y+i;switch(t.toLowerCase()){case"up":return{ok:!0,start:r,end:{x:r.x,y:td(r.y-i,o,l)}};case"down":return{ok:!0,start:r,end:{x:r.x,y:td(r.y+i,o,l)}};case"left":return{ok:!0,start:r,end:{x:td(r.x-a,o,s),y:r.y}};case"right":return{ok:!0,start:r,end:{x:td(r.x+a,o,s),y:r.y}};default:return{ok:!1,message:"swipe.label direction must be up, down, left, or right."}}}(a.target,r);return i.ok?await ib(e,i,n):a$("INVALID_ARGS",i.message)}async function ib(e,t,r){return await e.invoke({...e.baseReq,command:"swipe",positionals:[String(t.start.x),String(t.start.y),String(t.end.x),String(t.end.y),...r?[r]:[]]})}async function iS(e){var t;let r=((t=e.scope)?aL.get(t):void 0)??await iI(e);if(!r)return{ok:!1,response:a$("COMMAND_FAILED","Unable to resolve screen size for Maestro swipe.")};let[n,...a]=e.positionals;return"direction"===n?function(e,t){let[r,n]=e;if(!r)return{ok:!1,response:a$("INVALID_ARGS","Maestro direction swipe requires a direction.")};switch(r){case"up":case"down":var a,i,o;let s;return a=r,i=t,o=n,{ok:!0,start:tg({x:(s=tc({direction:a,amount:.6,referenceWidth:i.referenceWidth,referenceHeight:i.referenceHeight})).x1,y:s.y1},i,8),end:tg({x:s.x2,y:s.y2},i,8),durationMs:o};default:return{ok:!1,response:a$("INVALID_ARGS","Maestro swipe direction must be UP, DOWN, LEFT, or RIGHT.")}}}(a,r):"percent"===n?function(e,t,r){var n,a,i,o,s;let[l,u,c,d,p]=e,f=[l,u,c,d].map(Number);if(f.some(e=>!Number.isFinite(e)))return{ok:!1,response:a$("INVALID_ARGS","Maestro percentage swipe requires numeric points.")};let[m,h,w,g]=f,y=(n=r,a=m,i=h,o=w,s=g,"android"!==n||i!==s||50!==i||30>Math.abs(o-a)?{startY:i,endY:s}:{startY:65,endY:65});return{ok:!0,start:tu(t,m,y.startY,{marginPx:1}),end:tu(t,w,y.endY,{marginPx:1}),durationMs:p}}(a,r,aq(e.baseReq.flags)):{ok:!1,response:a$("INVALID_ARGS","Maestro screen swipe requires direction or percent.")}}async function iI(e){let t=await aF(e);if(t.ok)return H(aC(t.data))}async function i_(e,t,r,n){let a=await e.invoke({...e.baseReq,command:"wait",positionals:[t,String(n)]});return a.ok||!r?a:await e.invoke({...e.baseReq,command:"find",positionals:[r,"wait",String(n)]})}async function iN(e,t,r){let n=aj(t),a=await iM(e,t,r);return a.response.ok?{retry:!1,response:a.response}:a.targetResolved&&n?await ik(e,n):{retry:!0,response:a.response}}async function iM(e,t,r){let n=await iD(e,t,r,"tapOn",{promoteTapTarget:!0});return n.ok?await ix(e,t,n.target):{response:n.response,targetResolved:!1}}async function ix(e,t,r){var n;let a=function(e,t,r={}){var n,a,i,o,s;let l;return(n=e.node,a=t,i=e.rect,!0===r.allowLargeContainerBias&&a&&(o=i).width>=ip.minWidth&&o.height>=ip.minHeight&&o.height<=ip.maxHeight&&("cell"===(l=ts(n.type??""))||"other"===l||"scrollview"===(s=l)||"scroll-area"===s))?{x:tp(e.rect.x,Math.min(e.rect.width,ip.width)),y:tp(e.rect.y,Math.min(e.rect.height,ip.height))}:tm(e.rect)}(r,null!==aj(t),{allowLargeContainerBias:"raw"===r.snapshotMode});e6({level:"debug",phase:"maestro_tap_target",data:{selector:t,node:{index:r.node.index,type:r.node.type,label:r.node.label,value:r.node.value,identifier:r.node.identifier,visibleToUser:r.node.visibleToUser},rect:r.rect,point:a}});let i=await e.invoke({...e.baseReq,command:"click",positionals:[String(a.x),String(a.y)],flags:{...e.baseReq.flags,interactionOutcome:{retryOnNoChange:!0}}});return i.ok&&(n=e.scope)&&aP.delete(n),{response:i,targetResolved:!0}}async function ik(e,t){let r=await e.invoke({...e.baseReq,command:"find",positionals:[t,"click"],flags:{...e.baseReq.flags,findFirst:!0,interactionOutcome:{retryOnNoChange:!0}}});return(e6({level:r.ok?"info":"debug",phase:"maestro_fuzzy_tap_fallback",data:{query:t,ok:r.ok}}),r.ok)?{retry:!1,response:r}:{retry:!0,response:r}}async function iD(e,t,r,n,a){let i=await aF({...e,mode:"interactive"}),o=iO(e,t,r,n,a,i,"interactive");if(o.ok||!i.ok||!aE(e.baseReq))return o;aV(n,t);let s=await aF({...e,mode:"raw"});return iO(e,t,r,n,a,s,"raw")}function iO(e,t,r,n,a,i,o){if(!i.ok)return{ok:!1,response:i};let s=aC(i.data);if(!s)return{ok:!1,response:a$("COMMAND_FAILED",`Unable to read snapshot data for ${n}.`)};let l=H(s),u=aq(e.baseReq.flags),c=function(e,t,r,n){var a;let i=(a=e.scope)?aP.get(a):void 0;if(!i)return;let o=aT(t,i.selector,r,n);if(o.ok)return e6({level:"debug",phase:"maestro_preferred_context",data:{selector:i.selector,node:{index:o.node.index,type:o.node.type,label:o.node.label,value:o.node.value,identifier:o.node.identifier},rect:o.rect}}),{node:o.node,rect:o.rect}}(e,s,u,l),d=function(e,t,r,n,a,i={}){let o=aK(e,t,n);if(r.childOf){let t=aK(e,r.childOf,n);if(0===t.length)return{ok:!1,message:`Maestro childOf parent did not match: ${r.childOf}`};let a=ti(e.nodes);o=o.filter(r=>t.some(t=>e7(e.nodes,r,t,a)))}let s=aG({nodes:e.nodes,matches:o,platform:n}),l=aW(e.nodes,s.matches,r.index,aj(t),a,!0===i.requireOnScreen,i.promoteTapTarget,i.preferredContext);if(!l){let e=r.index??0;return{ok:!1,message:s.blockedByReactNativeOverlay?`React Native overlay is covering app content: ${t}`:o.length>0&&0===s.matches.length?`Maestro selector matched ${o.length} element(s), but none were visible: ${t}`:`Maestro selector did not match index ${e}: ${t}`}}return{ok:!0,node:l.node,rect:l.rect}}(s,t,r,u,l,{...a,preferredContext:c,requireOnScreen:!0});if(!d.ok){let e=aj(t);if(e){let t=function(e,t,r,n,a={}){let i=function(e,t){let r=tl(t);if(!r)return[];let n=[],a=[];for(let t of e.nodes){let e=[t.label,e9(t),t.identifier,t.value].filter(e=>!!e).map(e=>tl(e));e.some(e=>e===r)?n.push(t):e.some(e=>e.includes(r))&&a.push(t)}return n.length>0?n:a}(e,t),o=aG({nodes:e.nodes,matches:i,platform:r}),s=aW(e.nodes,o.matches,void 0,t,n,!0===a.requireOnScreen,a.promoteTapTarget,a.preferredContext);return s?{ok:!0,node:s.node,rect:s.rect}:{ok:!1,message:`Maestro fuzzy text did not match: ${t}`}}(s,e,u,l,{...a,preferredContext:c,requireOnScreen:!0});if(t.ok)return{ok:!0,target:{node:t.node,rect:t.rect,frame:l,snapshot:s,snapshotMode:o}}}}return d.ok?{ok:!0,target:{node:d.node,rect:d.rect,frame:l,snapshot:s,snapshotMode:o}}:{ok:!1,response:a$("ELEMENT_NOT_FOUND",d.message,{selector:t,options:r,command:n})}}async function iR(e){switch(e.command){case nW:return await a5(e);case nz:return await io(e);case nJ:return await iL(e);case nX:return await is(e);case nY:return await ih(e);case nZ:return await ig(e);case nQ:return await iA(e);case n0:return await iv(e);case n1:return await iw(e);case nB:return function(e){let[r]=e.positionals;if(!r)return a$("INVALID_ARGS","runScript requires a file path.");try{let n=function(e){let{scriptPath:r,env:n}=e,a=t.readFileSync(r,"utf8"),i=Object.create(null);try{var o,l;s.runInNewContext(a,(o=n,l=i,{...o,output:l,json:as,http:{post:(e,t)=>(function(e,t,r){let n=e5(process.execPath,["-e",ao],{stdin:JSON.stringify({method:e,url:t,headers:r?.headers??{},body:r?.body??""}),timeoutMs:3e4,allowFailure:!0});if(0!==n.exitCode){let r;throw new d("COMMAND_FAILED",`Maestro runScript http.${e.toLowerCase()} failed for ${t}: ${(r=n.stderr.trim()).length>0?r.slice(0,1e3):"request process exited without stderr"}`,{exitCode:n.exitCode,stderr:n.stderr})}try{return JSON.parse(n.stdout)}catch(r){throw new d("COMMAND_FAILED",`Maestro runScript http.${e.toLowerCase()} returned invalid JSON for ${t}`,{stdout:n.stdout.slice(0,1e3),stderr:n.stderr.slice(0,1e3)},r instanceof Error?r:void 0)}})("POST",e,t)}}),{filename:r,timeout:3e4})}catch(e){throw new d("COMMAND_FAILED",`Maestro runScript failed for ${r}: ${e instanceof Error?e.message:String(e)}`,{scriptPath:r},e instanceof Error?e:void 0)}return function(e,t){for(let r of Object.keys(e))if(r.includes("."))throw new d("INVALID_ARGS",`Maestro runScript output key cannot contain ".": ${r}`,{scriptPath:t,key:r})}(i,r),Object.fromEntries(Object.entries(i).map(([e,t])=>{var r;return[`output.${e}`,(r=t,"string"==typeof r?r:"number"==typeof r||"boolean"==typeof r?String(r):JSON.stringify(r))]}))}({scriptPath:r,env:{...e.scope.values,...e.baseReq.flags?.maestro?.runScriptEnv??{}}});return{ok:!0,data:{outputEnv:n}}}catch(t){let e=u(t);return a$(e.code,e.message,e.details)}}(e);default:return}}async function iL(e){let t=await e.invoke({...e.baseReq,command:"keyboard",positionals:["enter"]});return t.ok?t:await e.invoke({...e.baseReq,command:"type",positionals:["\n"]})}async function iP(e){for(let[t,r]of e.actions.entries()){let n=await e.invokeReplayAction({action:r,line:e.line,step:e.step+t/1e3});if(!n.ok)return n}return{ok:!0,data:{ran:e.actions.length}}}async function i$(e){let t;for(let r=0;r<=e.maxRetries;r+=1){let n=await iP({actions:e.actions,line:e.line,step:e.step+r,invokeReplayAction:e.invokeReplayAction});if(n.ok)return{ok:!0,data:{attempts:r+1,retried:r>0}};t=n}return t??{ok:!1,error:{code:"COMMAND_FAILED",message:"retry commands failed."}}}async function iF(e){let t=await iC(e,e.control);return t.ok?t.matched?await iT(e):{ok:!0,data:{skipped:!0,condition:e.control.mode,selector:e.control.selector}}:t.response}async function iC(e,t){if("visible"===t.mode)return await iE(e,t);let r=await iV(e,t.selector);return r.ok?{ok:!0,matched:!r.matched}:{ok:!1,response:r.response}}async function iE(e,t){let r=Date.now();for(;;){let n=await iV(e,t.selector);if(!n.ok)return{ok:!1,response:n.response};if(n.matched)return{ok:!0,matched:!0};if(Date.now()-r>=3e3)return{ok:!0,matched:!1};await ty(250)}}async function iV(e,t){let r=await aF(e);if(!r.ok)return{ok:!1,response:r};let n=iU(e,t,r);if(!n.ok||n.matched||!aE(e.baseReq))return n;aV("runFlow.when",t);let a=await aF({...e,mode:"raw"});return a.ok?iU(e,t,a):{ok:!1,response:a}}function iU(e,t,r){let n=aC(r.data);return n?{ok:!0,matched:aT(n,t,aq(e.baseReq.flags),H(n)).ok}:{ok:!1,response:a$("COMMAND_FAILED","Unable to read snapshot data for runFlow.when.")}}async function iT(e){let t=await iP({actions:e.control.actions,line:e.line,step:e.step,invokeReplayAction:e.invokeReplayAction});return t.ok?{ok:!0,data:{ran:t.data?.ran,condition:e.control.mode,selector:e.control.selector}}:t}async function iG(e){var t;let{req:r,sessionName:n,action:a,scope:i,filePath:o,line:s,step:l,tracePath:u,invoke:c}=e,d=(t={file:o,line:s},{...a,positionals:(a.positionals??[]).map(e=>nA(e,i,t)),flags:nb(a.flags,i,t)??{},runtime:nb(a.runtime,i,t),replayControl:function(e,t,r){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:nA(e.selector,t,r)}}return e}(a.replayControl,i,t)}),p=Date.now();iK(u,{type:"replay_action_start",ts:new Date(p).toISOString(),replayPath:o,line:s,step:l,command:d.command,positionals:d.positionals??[]});let f=await iq({req:r,sessionName:n,resolved:d,scope:i,line:s,step:l,invoke:c,invokeReplayAction:e=>iG({req:r,sessionName:n,action:e.action,scope:i,filePath:o,line:e.line,step:e.step,tracePath:u,invoke:c})}),m=Date.now();return iK(u,{type:"replay_action_stop",ts:new Date(m).toISOString(),replayPath:o,line:s,step:l,command:d.command,ok:f.ok,durationMs:m-p,resultTiming:f.ok?function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;let t=e.timing;if(!(!t||"object"!=typeof t||Array.isArray(t)))return Object.fromEntries(Object.entries(t).filter(([,e])=>{let t=typeof e;return"number"===t||"string"===t||"boolean"===t}))}(f.data):void 0,errorCode:f.ok?void 0:f.error.code}),f}async function iq(e){var t;let{req:r,sessionName:n,resolved:a,scope:i,line:o,step:s,invoke:l,invokeReplayAction:u}=e,c=(t=r.flags,eQ(t,{...a.flags??{}})),d={token:r.token,session:n,flags:c,runtime:a.runtime,meta:r.meta},p=await ij({control:a.replayControl,baseReq:d,line:o,step:s,invoke:l,invokeReplayAction:u})??await iR({command:a.command,baseReq:d,positionals:a.positionals??[],scope:i,line:o,step:s,invoke:l,invokeReplayAction:u})??await l({...d,command:a.command,positionals:a.positionals??[]});if(p.ok){let e=function(e){if(!e||"object"!=typeof e)return null;let t=e.outputEnv;if(!t||"object"!=typeof t||Array.isArray(t))return null;let r=Object.entries(t).filter(e=>"string"==typeof e[1]);return r.length>0?Object.fromEntries(r):null}(p.data);e&&Object.assign(i.values,e)}return p}async function ij(e){let{control:t,baseReq:r,line:n,step:a,invoke:i,invokeReplayAction:o}=e;if(t){switch(t.kind){case"retry":return await i$({actions:t.actions,maxRetries:t.maxRetries,line:n,step:a,invokeReplayAction:o});case"maestroRunFlowWhen":return await iF({baseReq:r,control:t,line:n,step:a,invoke:i,invokeReplayAction:o})}return t}}function iK(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
28
+ `)}async function iH(e){let{req:r,sessionName:n,logPath:i,sessionStore:o,tracePath:s,invoke:l}=e,c=r.positionals?.[0];if(!c)return L("INVALID_ARGS","replay requires a path");let p="",f=new Set;try{var m,h;p=en.expandHome(c,r.meta?.cwd);let e=t.readFileSync(p,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return L("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let w=function(e,t,r={}){var n;let a=function(e){let t=e?.replayBackend;if("string"!=typeof t)return;let r=ax[t];if(!r)throw new d("INVALID_ARGS",`Unsupported replay backend "${t}".`);return r}(t);return a?{...a.parse(e,{...r,platform:t?.platform,env:(n=t,{...nw(nv(n?.replayShellEnv)),...ng(ny(n?.replayEnv))})}),updateUnsupportedMessage:"replay -u is not supported for compat flow input. Convert to .ad first, then update that replay file."}:{...function(e){let t=[],r=[],n=e.split(/\r?\n/),a=!1;for(let[e,i]of n.entries()){let n=i.trim();if(0===n.length||n.startsWith("#"))continue;if(nN(n)){if(a)throw new d("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let o=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[r,...n]=function(e){let t=[],r=0;for(;r<e.length&&!((r=function(e,t){let r=t;for(;r<e.length&&/\s/.test(e.charAt(r));)r+=1;return r}(e,r))>=e.length);){let n='"'===e[r]?function(e,t){let r=!1,n=t+1;for(;n<e.length;n+=1){let t=e.charAt(n);if('"'===t&&!r)break;if(r){r=!1;continue}r="\\"===t}if(n>=e.length)throw new d("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,n+1)),nextCursor:n+1}}(e,r):function(e,t){let r=t;for(;r<e.length&&!/\s/.test(e.charAt(r));)r+=1;return{value:e.slice(t,r),nextCursor:r}}(e,r);t.push(n.value),r=n.nextCursor}return t}(t);if(void 0===r||"context"===r)return null;let a={ts:Date.now(),command:r,positionals:[],flags:{}};if("snapshot"===r){a.positionals=[];for(let e=0;e<n.length;e+=1){let t=n[e];if("-i"===t){a.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){a.flags.snapshotCompact=!0;continue}if("--raw"===t){a.flags.snapshotRaw=!0;continue}if("--force-full"===t){a.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<n.length){let t=Number(n[e+1]);Number.isFinite(t)&&t>=0&&(a.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<n.length){a.flags.snapshotScope=n[e+1],e+=1;continue}if("--backend"===t&&e+1<n.length){e+=1;continue}}return a}if("open"===r){let e=F(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a.runtime=e.runtime,a}if("runtime"===r){let e=j(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a}if(x(r)){let e=eb(r,n);Object.assign(a.flags,e.flags);let t=e.positionals[0];if(void 0===t)return a;if(t.startsWith("@"))return a.positionals=[t],e.positionals[1]&&(a.result={refLabel:e.positionals[1]}),a;let i=e.positionals[0],o=e.positionals[1];return nx(i)&&nx(o)&&e.positionals.length>=2?a.positionals=[i,o]:a.positionals=[e.positionals.join(" ")],a}if("fill"===r){let e=eb(r,n);if(Object.assign(a.flags,e.flags),!(e.positionals.length>=2))return a.positionals=e.positionals,a;let[t,i,...o]=e.positionals;return t.startsWith("@")?(o.length>0?(a.positionals=[t,o.join(" ")],a.result={refLabel:i}):a.positionals=[t,i],a):(a.positionals=[t,[i,...o].join(" ")],a)}if("get"===r){let e=n[0],t=n[1];return void 0===e||void 0===t?a.positionals=n:t.startsWith("@")?(a.positionals=[e,t],n[2]&&(a.result={refLabel:n[2]})):a.positionals=[e,n.slice(1).join(" ")],a}if("swipe"===r||"type"===r){let e=eb(r,n);return Object.assign(a.flags,e.flags),a.positionals=e.positionals,a}if("record"===r){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t];if("--hide-touches"===r){a.flags.hideTouches=!0;continue}if("--fps"===r&&t+1<n.length){let e=Number(n[t+1]);Number.isFinite(e)&&(a.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===r&&t+1<n.length){let e=Number(n[t+1]);Number.isFinite(e)&&(a.flags.quality=Math.floor(e)),t+=1;continue}e.push(r)}return a.positionals=e,a}if("screenshot"===r){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t],i=e3({args:n,index:t,flags:a.flags});if(i.handled){t=i.nextIndex;continue}e.push(r)}return a.positionals=e,a}return a.positionals=n,a}(i);o&&(t.push(o),r.push(e+1),a=!0)}return{actions:t,actionLines:r}}(e),metadata:n_(e)}}(e,r.flags,{sourcePath:p}),g=w.metadata,y=g.platform||g.target?{...r,flags:(m=r.flags,h=g,{...m??{},...void 0!==h.platform&&m?.platform===void 0?{platform:h.platform}:{},...void 0!==h.target&&m?.target===void 0?{target:h.target}:{}})}:r,v=w.actions,A=w.actionLines;if(r.flags?.replayUpdate===!0&&w.updateUnsupportedMessage)return L("INVALID_ARGS",w.updateUnsupportedMessage);if(r.flags?.replayUpdate===!0&&g.env&&Object.keys(g.env).length>0)return L("INVALID_ARGS","replay -u does not yet preserve env directives. Temporarily remove the env lines, run replay -u, then restore them.");if(r.flags?.replayUpdate===!0&&function(e){for(let t of e){for(let e of t.positionals??[])if("string"==typeof e&&e.includes("${"))return!0;if(iz(t.flags)||iz(t.runtime))return!0}return!1}(v))return L("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let S=function(e){let t={};if(e.builtins)for(let[r,n]of Object.entries(e.builtins))t[r]=n;for(let r of[e.fileEnv,e.shellEnv,e.cliEnv])if(r)for(let[e,n]of Object.entries(r)){if(nm(e))throw nh(e);t[e]=n}return{values:t}}({builtins:function(e){let{req:t,sessionName:r,metadata:n,resolvedPath:i}=e,o=t.flags??{},s=t.meta?.cwd??process.cwd(),l={AD_SESSION:r,AD_FILENAME:a.relative(s,i)||i},u=o.platform??n.platform;u&&(l.AD_PLATFORM=u);let c=o.target??n.target;c&&(l.AD_TARGET=c);let d=o.device;"string"==typeof d&&d.length>0&&(l.AD_DEVICE=d);let p=o.artifactsDir;return"string"==typeof p&&p.length>0&&(l.AD_ARTIFACTS=p),l}({req:y,sessionName:n,metadata:g,resolvedPath:p}),fileEnv:g.env,shellEnv:nw(nv(r.flags?.replayShellEnv)),cliEnv:ng(ny(r.flags?.replayEnv))}),I=r.flags?.replayUpdate===!0,_=s??o.get(n)?.trace?.outPath,N=0;for(let e=0;e<v.length;e+=1){let t=v[e];if(!t||"replay"===t.command)continue;let r=await iG({req:y,sessionName:n,action:t,scope:S,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l});if(r.ok){iW(r).forEach(e=>f.add(e));continue}if(!I)return iB(r,t,e,p,[...f]);let a=await aD({action:t,sessionName:n,logPath:i,sessionStore:o});if(!a)return iB(r,t,e,p,[...f]);if(v[e]=a,!(r=await iG({req:y,sessionName:n,action:a,scope:S,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l})).ok)return iB(r,a,e,p,[...f]);iW(r).forEach(e=>f.add(e)),N+=1}return I&&N>0&&function(e,r,n){let a=[];if(n){let e=n.device.kind?` kind=${n.device.kind}`:"",t=n.device.target?` target=${n.device.target}`:"";a.push(`context platform=${n.device.platform}${t} device=${ea(n.device.name)}${e} theme=unknown`)}for(let e of r){var i;a.push((i=e,b(i,{runtimeIncludeAllPositionals:!0})))}let o=`${a.join("\n")}
29
+ `,s=`${e}.tmp-${process.pid}-${Date.now()}`;t.writeFileSync(s,o),t.renameSync(s,e)}(p,v,o.get(n)),{ok:!0,data:{replayed:v.length,healed:N,session:n,artifactPaths:[...f]}}}catch(t){let e=u(t);return L(e.code,e.message,f.size>0?{artifactPaths:[...f]}:void 0)}}function iB(e,t,r,n,a=[]){if(e.ok)return e;let i=r+1;return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${i} (${ei(t)}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:{...e.error.details??{},replayPath:n,step:i,action:t.command,positionals:t.positionals??[],artifactPaths:a}}}}function iW(e){if(!e.ok||!e.data)return[];let r=[];if("string"==typeof e.data.path&&r.push(e.data.path),"string"==typeof e.data.outPath&&r.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let t of e.data.artifacts){if(!t||"object"!=typeof t)continue;let e="string"==typeof t.localPath?t.localPath:void 0,n="string"==typeof t.path?t.path:void 0;e?r.push(e):n&&r.push(n)}return[...new Set(r.filter(e=>(function(e){try{return t.statSync(e).isFile()}catch{return!1}})(e)))]}function iz(e){return"string"==typeof e?e.includes("${"):Array.isArray(e)?e.some(iz):!!e&&"object"==typeof e&&Object.values(e).some(iz)}async function iJ(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}=e;return"replay"===t.command?await iH({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}):"test"===t.command?await aN({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,target:s,requestId:l,artifactsDir:u,artifactPaths:c,tracePath:d})=>{let p=function(e){let{parentFlags:t,platform:r,target:n,artifactsDir:a}=e;return void 0===r&&void 0===n&&void 0===a?t:{...t??{},...void 0!==r?{platform:r}:{},...void 0!==n?{target:n}:{},...void 0!==a?{artifactsDir:a}:{}}}({parentFlags:t.flags,platform:o,target:s,artifactsDir:u});return await iH({req:{...t,command:"replay",session:r,positionals:[e],flags:p,meta:l?{...t.meta??{},requestId:l}:t.meta},sessionName:r,logPath:n,sessionStore:a,tracePath:d,invoke:async e=>{var t;return t=await i(e),c&&iW(t).forEach(e=>c.add(e)),t}})},cleanupSession:async e=>{a.get(e)&&await W({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:n,sessionStore:a})}}):null}let iX=tA.inventory,iY=tA.state,iZ=tA.observability,iQ=tA.replay,i0={...Object.fromEntries([...iX].map(e=>[e,!0])),...Object.fromEntries([...iY].map(e=>[e,!0])),...Object.fromEntries([...iZ].map(e=>[e,!0])),...Object.fromEntries([...iQ].map(e=>[e,!0])),[tv.runtime]:!0,[tb.clipboard]:!0,[tb.keyboard]:!0,[tb.install]:!0,[tb.reinstall]:!0,[tv.installSource]:!0,[tv.releaseMaterializedPaths]:!0,[tb.push]:!0,[tb.triggerAppEvent]:!0,[tb.open]:!0,[tb.prepare]:!0,[tb.batch]:!0,[tb.close]:!0};async function i1(e){var t,r,n,a,i,o,s;let{req:l,sessionName:u,logPath:c,sessionStore:d}=e,p=l.positionals?.[0]??"";if("ios-runner"!==p)return L("INVALID_ARGS","prepare requires a subcommand: ios-runner");let f=d.get(u),m=l.flags??{},h=_(tb.prepare,f,m);if(h)return h;let w=await y({session:f,flags:m,ensureReady:!0});if("ios"!==w.platform)return L("UNSUPPORTED_OPERATION","prepare ios-runner is only supported on iOS");let g=Date.now(),v=await em(w,{command:"uptime"},(t=l,r=f,n=c,{verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId}));return{ok:!0,data:(a=p,i=w,o=Math.max(0,Date.now()-g),s=v,{action:a,platform:i.platform,deviceId:i.id,deviceName:i.name,kind:i.kind,durationMs:o,runner:s,message:`Prepared iOS runner: ${i.name}`})}}async function i2(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,command:i,positionals:o,recordPositionals:s,deriveNextSession:l}=e,u=a.get(r),c=t.flags??{},d=_(i,u,c);if(d)return d;let p=await y({session:u,flags:c,ensureReady:!0});if(!eM(i,p))return L("UNSUPPORTED_OPERATION",`${i} is not supported on this device`);let f=await m(p,i,o,t.flags?.out,{...et(n,t.flags,u?.appBundleId,u?.trace?.outPath)});if(u){let e=l?await l(u,f,p):u;a.recordAction(e,{command:i,positionals:s??o,flags:t.flags??{},result:f??{}}),e!==u&&a.set(r,e)}return{ok:!0,data:f??{}}}async function i3(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,i=a.get(r),o=t.flags??{},s=_(tb.clipboard,i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return L("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await y({session:i,flags:o,ensureReady:!0});if(!eM(tb.clipboard,u))return L("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let c=await m(u,tb.clipboard,t.positionals??[],t.flags?.out,{...et(n,t.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:c??{}}),{ok:!0,data:{platform:u.platform,...c??{}}}}async function i5(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i,invokeReplayAction:o,androidAdbExecutor:s}=e;if(iX.has(t.command))return await rp({req:t,sessionName:r,sessionStore:a});if("runtime"===t.command)return await tF({req:t,sessionName:r,sessionStore:a});if(iY.has(t.command))return await rg({req:t,sessionName:r,sessionStore:a});if(t.command===tb.clipboard)return await i3({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===tb.keyboard){let e=a.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i&&"enter"!==i&&"return"!==i||"ios"!==eD((t.flags??{}).platform)?await i2({req:t,sessionName:r,logPath:n,sessionStore:a,command:tb.keyboard,positionals:t.positionals??[]}):L("SESSION_NOT_FOUND","iOS keyboard action requires an active session so the target app stays foregrounded. Run open first.")}if(iZ.has(t.command))return await nn({req:t,sessionName:r,sessionStore:a,androidAdbExecutor:s});if(t.command===tb.prepare)return await i1({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===tb.install||t.command===tb.reinstall)return await rc({req:t,command:t.command,sessionName:r,sessionStore:a,deployOps:t.command===tb.install?ru:rl});if(t.command===tv.installSource)return await tx({req:t,sessionName:r,sessionStore:a});if(t.command===tv.releaseMaterializedPaths)return await tk({req:t});if(t.command===tb.push){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await i2({req:t,sessionName:r,logPath:n,sessionStore:a,command:tb.push,positionals:[i,"file"===(e=ec(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>en.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):L("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return t.command===tb.triggerAppEvent?await i2({req:t,sessionName:r,logPath:n,sessionStore:a,command:tb.triggerAppEvent,positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,n=r?await t9(e.device,r,e.appBundleId,t6)??e.appBundleId:e.appBundleId;return{...e,appBundleId:n}}}):t.command===tb.open?await rs({req:t,sessionName:r,logPath:n,sessionStore:a}):iQ.has(t.command)?await iJ({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o??i}):t.command===tb.batch?await rd(t,r,i):t.command===tb.close?await W({req:t,sessionName:r,logPath:n,sessionStore:a}):null}export{tI as session_namespaceObject};