agent-device 0.16.14 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.14.apk → agent-device-android-multitouch-helper-0.17.0.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.0.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.14.manifest.json → agent-device-android-multitouch-helper-0.17.0.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.14.apk → agent-device-android-snapshot-helper-0.17.0.apk} +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.0.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.14.manifest.json → agent-device-android-snapshot-helper-0.17.0.manifest.json} +6 -6
  7. package/dist/src/1352.js +1 -1
  8. package/dist/src/221.js +4 -4
  9. package/dist/src/2415.js +29 -29
  10. package/dist/src/2805.js +1 -1
  11. package/dist/src/6232.js +1 -1
  12. package/dist/src/7599.js +4 -3
  13. package/dist/src/8020.js +1 -0
  14. package/dist/src/8699.js +1 -1
  15. package/dist/src/940.js +1 -1
  16. package/dist/src/9533.js +1 -1
  17. package/dist/src/android-snapshot-helper.d.ts +1 -0
  18. package/dist/src/apple.js +1 -1
  19. package/dist/src/args.js +14 -9
  20. package/dist/src/cli.js +9 -9
  21. package/dist/src/command-metadata.js +1 -1
  22. package/dist/src/contracts.d.ts +1 -0
  23. package/dist/src/find.js +1 -1
  24. package/dist/src/finders.d.ts +1 -0
  25. package/dist/src/generic.js +9 -9
  26. package/dist/src/index.d.ts +19 -1
  27. package/dist/src/selectors.d.ts +1 -0
  28. package/dist/src/session.js +11 -11
  29. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +4 -0
  30. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +71 -0
  31. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +41 -7
  32. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +154 -11
  33. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +11 -0
  34. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +12 -4
  35. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +26 -0
  36. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
  37. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +7 -1
  38. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +571 -56
  39. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +21 -0
  40. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +11 -0
  41. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +13 -2
  42. package/ios-runner/README.md +13 -0
  43. package/package.json +1 -1
  44. package/server.json +2 -2
  45. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.14.apk.sha256 +0 -1
  46. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.14.apk.sha256 +0 -1
@@ -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,sessionMatchesScope as h,selectorTargetsSessionDevice as w,appendAppLogMarker as g,resolveCommandDevice as y,hasRuntimeTransportHints as v,getSessionCommandKind as A,inferFillText as b,formatPortableActionLine as S,stopIosRunnerSession as I,resolvePublicSessionName as _,requireSessionOrExplicitSelector as N,isTouchTargetCommand as M,cleanupUploadedArtifact as x,isClickLikeCommand as k,refreshSessionDeviceIfNeeded as D,createRequestCanceledError as O,resolveIosDevicectlHint as R,registerRequestAbort as L,errorResponse as P,IOS_SIMULATOR_POST_OPEN_SETTLE_MS as $,IOS_SIMULATOR_POST_CLOSE_SETTLE_MS as F,parseReplayOpenFlags as C,settleIosSimulator as E,uniqueStrings as V,applyRuntimeHintsToApp as T,withKeyedLock as U,getAppLogPathMetadata as G,buildSessionRecoveryHint as q,resolveTargetDevice as j,parseReplayRuntimeFlags as K,setSessionSnapshot as B,getSnapshotReferenceFrame as H,clearRuntimeHintsFromApp as W,handleCloseCommand as z,clearAppLogFiles as J,prepareIosRunner as X,session_device_utils_hasExplicitSessionFlag as Y,readSessionNetworkCapture as Z,cleanupRetainedMaterializedPaths as Q,isImplicitSessionScopeConflict as ee,IOS_DEVICECTL_DEFAULT_HINT as et,buildSnapshotState as er,context_contextFromFlags as en,listDeviceInventory as ea,SessionStore as ei,formatScriptStringLiteral as eo,formatScriptActionSummary as es,isRequestCanceled as el,resolveRequestTrackingId as eu,retainMaterializedPaths as ec,runAppLogDoctor as ed,resolvePayloadInput as ep,prepareUploadedArtifact as ef,markRequestCanceled as em,stopAppLog as eh,resolveImplicitSessionScope as ew,ensureDeviceReady as eg,prewarmIosRunnerSession as ey,clearRequestCanceled as ev,resolveAndroidEmulatorAvdName as eA,buildSimctlArgsForDevice as eb,parseReplaySeriesFlags as eS,parseXmlDocumentSync as eI,resolveFrontmostMacOsApp as e_,runAppleToolCommand as eN,listIosDeviceApps as eM,isCommandSupportedOnDevice as ex,isApplePlatform as ek,listIosDeviceProcesses as eD,normalizePlatformSelector as eO,getRequestSignal as eR,markAndroidSnapshotFreshness as eL,startAppLog as eP,emitRequestProgress as e$}from"./2415.js";import{withSuccessText as eF,successText as eC}from"./1998.js";import{resolveDeployResultTarget as eE,resolveInstallFromSourceResultTarget as eV}from"./6232.js";import{parseSessionSurface as eT,MAESTRO_COMPAT_TRACKER_URL as eU,MAESTRO_NEW_ISSUE_URL as eG}from"./1352.js";import{resolveAndroidAdbExecutor as eq}from"./9639.js";import{splitNonEmptyTrimmedLines as ej}from"./7455.js";import{resolveIosSimulatorDeviceSetPath as eK,classifyAndroidAppTarget as eB,resolveIosDeviceDeepLinkBundleId as eH,isInfrastructureBootFailureReason as eW,isWebUrl as ez,resolveAndroidSerialAllowlist as eJ,isDeepLinkTarget as eX,formatAndroidInstalledPackageRequiredMessage as eY,listAndroidApps as eZ}from"./8806.js";import{runBatch as eQ,mergeParentFlags as e0}from"./1231.js";import{assertResolvedAppsFilter as e1}from"./1393.js";import{listIosApps as e2,readInfoPlistString as e3}from"./apps.js";import{readScreenshotScriptFlag as e5}from"./5310.js";import{runCmdSync as e6}from"./9818.js";import{emitDiagnostic as e8}from"./7599.js";import{splitSelectorFromArgs as e9,extractNodeText as e4,findSnapshotAncestor as e7,isDescendantOfSnapshotNode as te,splitIsSelectorArgs as tt,tryParseSelectorChain as tr,parseSelectorChain as tn,resolveSelectorChain as ta,buildSelectorChainForNode as ti,buildSnapshotNodeByIndex as to,matchesSelector as ts,normalizeType as tl}from"./940.js";import{normalizeText as tu}from"./7556.js";import{pointFromPercent as tc,clampToRange as td,buildSwipeGesturePlan as tp,interiorCoordinate as tf,evaluateIsPredicate as tm,pointInsideRect as th,readReactNativeOverlayActionNodes as tw,detectReactNativeOverlay as tg,clampGesturePoint as ty,buildSnapshotDisplayLines as tv}from"./9533.js";import{sleep as tA}from"./4829.js";import{INTERNAL_COMMANDS as tb,PUBLIC_COMMANDS as tS}from"./5792.js";import{trimRuntimeValue as tI}from"./8656.js";var t_={};async function tN(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 eg(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 j(e.flags??{});return await eg(n),n}async function tM(e){let{prepared:t,retention:r,req:n,session:a,sessionName:i}=e;if(r.enabled)return await ec({archivePath:t.archivePath,installablePath:t.installablePath,tenantId:n.meta?.tenantId,sessionName:a?i:void 0,ttlMs:r.ttlMs})}function tx(e){return e?{...e.archivePath?{archivePath:e.archivePath}:{},installablePath:e.installablePath,materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}}async function tk(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:ef(i,t.meta?.tenantId)},cleanup:()=>{x(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 tN({session:a,flags:t.flags});if(!ex("install",l))return P("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=eR(t.meta?.requestId),c=async(e,i)=>{let l;try{var u;l=await tM({prepared:e,retention:s,req:t,session:a,sessionName:r});let o=await i(l),c=eF(o,(u=o,`Installed: ${eV(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 Q(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{...tx(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{...tx(e),packageName:t,...n?{appName:n}:{},launchTarget:t}})}catch(e){return{ok:!1,error:c(e)}}}async function tD(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 Q(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:c(e)}}}e.r(t_),e.d(t_,{handleSessionCommands:()=>i1});let tO=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function tR(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function tL(e,t){if(void 0!==e){if("string"!=typeof e)throw new d("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return tI(e)}}function tP(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 t$(e){if("ios"===e||"android"===e)return e}async function tF(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:n,session:a}=e;!t||!a?.appBundleId||!v(r)||v(n)||await W({device:a.device,appId:a.appBundleId})}async function tC(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 P("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){v(l)&&s?.appBundleId&&await W({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=t$(eO(n.flags?.platform)??l?.platform??s?.device.platform);if(!u)return P("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 P("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:tI(t?.metroHost),metroPort:tP(t?.metroPort),bundleUrl:tI(t?.bundleUrl),launchUrl:tI(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===tR(c)?P("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 tE="open-command-roundtrip",tV="Not implemented for this platform in this release.",tT=new Set(["app","desktop","frontmost-app"]);async function tU(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await e_();return{appBundleId:t.bundleId,appName:t.appName}}function tG(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}function tq(e){return Math.round(10*e)/10}function tj(e){return Math.round(10*e)/10}let tK="adb-shell-dumpsys-gfxinfo-framestats";function tB(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 tW(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function tz(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:tG(a)??void 0}async function tJ(e,t,r={}){var n,a,i,o,s,l,u,c;let p=eq(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=tz(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=tG(a)??void 0,s=Number(i);if(void 0===o||!Number.isFinite(s)||r<0)return;let l=tz(t,"Uptime"),u=tz(t,"Stats since");return{droppedFramePercent:tq(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=tB(e,t,"Flags"),n=tB(e,t,"IntendedVsync"),a=tB(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=tW(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 tW(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?tq(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:tj(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:tj(l/1e6),refreshRateHz:void 0===l?void 0:tj(1e9/l)}),windowStartedAt:g.windowStartedAt,windowEndedAt:g.windowEndedAt,timestampSource:g.timestampSource,measuredAt:a,method:tK,source:f?"android-gfxinfo-summary":"framestats-rows",worstWindows:b&&b.length>0?b:void 0});return await tX(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 tX(e,t,r={}){let n=eq(e,r.adb);try{await n(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let tY="adb-shell-dumpsys-cpuinfo",tZ="adb-shell-dumpsys-meminfo";async function tQ(e,t,r={}){let n=eq(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 ej(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:tq(a),measuredAt:r,method:tY,matchedProcesses:[...n]}}(e.stdout,t,new Date().toISOString())}catch(e){throw t1("cpu",t,e)}}async function t0(e,t,r={}){let n=eq(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=t2(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!==tG(e));if(!r)break;return tG(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:t2(e,"TOTAL RSS"),measuredAt:r,method:tZ}}(e.stdout,t,new Date().toISOString())}catch(e){throw t1("memory",t,e)}}function t1(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 t2(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:tG(a)??void 0}async function t3(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return eX(t)?"macos"===e.platform?void 0:"device"===e.kind?eH(r,t):ez(t)?void 0:r??await t5(e,t):await t6(e,t)}async function t5(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function t6(e,t){try{let{resolveIosApp:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function t8(e,t){if(!("android"!==e.platform||!t||eX(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 t9(e,t,r){if(r||"android"!==e.platform||!t||!eX(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 t4(e,t,r,n){return await t3(e,t,r)??await n(e,t)??("android"===e.platform&&t&&eX(t)?r:void 0)}function t7(e){return P("INVALID_ARGS",e)}function re(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=eT(r);if(!tT.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?eT(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 P(e instanceof d?e.code:"INVALID_ARGS",String(e.message))}}function rt(e){let{shouldRelaunch:t,openTarget:r,surface:n,device:a}=e;return t?r&&eX(r)?t7("open --relaunch does not support URL targets."):"app"!==n?t7("open --relaunch is supported only for app surfaces."):"android"===a.platform&&r&&"binary"===eB(r)?t7(eY(r)):null:null}async function rr(e){let{req:t,sessionName:r,sessionStore:n,device:a,surface:i,openTarget:o,existingSession:s}=e;await eg(a);let{appBundleId:l,appName:c}=await rn({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=>!tO.includes(e));if(a)throw new d("INVALID_ARGS",`Invalid open runtime field: ${a}. Supported fields are ${tO.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:tL(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 tP(e)}}(t.metroPort),bundleUrl:tL(t.bundleUrl,"bundleUrl"),launchUrl:tL(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:n,platform:t$(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=t$(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&&tR(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=u(t);return P(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 tF({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:c,runtime:p.data.runtime}}}async function rn(e){let{device:t,surface:r,openTarget:n,existingAppBundleId:a}=e,i=await tU(r);return{appBundleId:i.appBundleId??await t4(t,n,a,t8),appName:i.appName??n}}let ra=new Map;async function ri(e){let{device:t,closeTarget:r,outFlag:n,context:a}=e;"android"!==t.platform&&await I(t.id),await m(t,"close",[r],n,a),await E(t,F)}async function ro(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||eX(p)||await m(i,"open",[d],o.flags?.out,{...(t=s,r=o.flags,n=en(t,r,l,u),delete n.launchConsole,delete n.launchArgs,n)})}async function rs(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 ri({device:c,closeTarget:e,outFlag:o.flags?.out,context:{...en(u,o.flags,b??y?.appBundleId,A)}}),I.relaunchCloseDurationMs=Math.max(0,Date.now()-t)}let N=Date.now();await T({device:c,appId:b,runtime:g}),I.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&&(I.runnerPrewarmKind="session",I.runnerPrewarmScheduled=!0,i=ey(c,x)),i&&o.flags?.maestro?.prewarmRunnerBeforeOpen===!0){let e=Date.now();await i,I.runnerPrewarmWaited=!0,I.runnerPrewarmDurationMs=Math.max(0,Date.now()-e)}let k=Date.now();await m(c,"open",p,o.flags?.out,{...en(u,o.flags,b)}),I.openDispatchDurationMs=Math.max(0,Date.now()-k);let D=Date.now();if(await ro({runtime:g,device:c,req:o,logPath:u,appBundleId:b,traceLogPath:A,openPositionals:p}),I.launchUrlDurationMs=Math.max(0,Date.now()-D),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 t9(c,d,b),"android"===c.platform&&b&&await tX(c,b);let R=d?(t=b,{durationMs:Math.max(0,Date.now()-k),measuredAt:new Date().toISOString(),method:tE,appTarget:d,appBundleId:t}):void 0,L=Date.now();if(await E(c,$),I.postOpenSettleDurationMs=Math.max(0,Date.now()-L),el(o.meta?.requestId)){let e=O();return P(e.code,e.message,e.details)}y&&eL(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??_(o),sessionScope:y?.sessionScope??ew(o),device:c,surface:h,appBundleId:b,appName:f,saveScript:!!o.flags?.saveScript});void 0!==o.runtime&&(r=l,n=s,(a=g)&&(0===tR(a)?r.clearRuntimeHints(n):r.setRuntimeHints(n,a)));let C=l.ensureSessionDir(s);I.totalDurationMs=Math.max(0,Date.now()-S);let V=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,...eC(`Opened: ${n??a??t}`)}}({sessionName:F.name,sessionStateDir:C,appName:f,appBundleId:b,surface:h,startup:R,timing:I,device:c,runtime:g,runtimeHintCount:tR});return l.recordAction(F,{command:"open",positionals:p,flags:o.flags??{},runtime:void 0!==o.runtime?g:void 0,result:V}),l.set(s,F),{ok:!0,data:V}}async function rl(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=re(i.device,t.flags?.surface,s,i.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return e?t7("open --relaunch requires an app name or an active session app."):t7("Session already active. Close it first or pass a new --session name.");let u=rt({shouldRelaunch:e,openTarget:s,surface:l,device:i.device});if(u)return u;let c=await D(i.device),d=await rr({req:t,sessionName:r,sessionStore:a,device:c,surface:l,openTarget:s,existingSession:i});return"response"===d.type?d.response:await rs({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 t7("open --relaunch requires an app argument.");let l=function(e){let{shouldRelaunch:t,openTarget:r,platform:n}=e;return t?r&&eX(r)?t7("open --relaunch does not support URL targets."):"android"===n&&r&&"binary"===eB(r)?t7(eY(r)):null:null}({shouldRelaunch:o,openTarget:s,platform:t.flags?.platform==="android"?"android":void 0});if(l)return l;let u=await j(t.flags??{}),c=re(u,t.flags?.surface,s);if("string"!=typeof c)return c;let d=rt({shouldRelaunch:o,openTarget:s,surface:c,device:u});return d||await U(ra,u.id,async()=>{let e=a.toArray().find(e=>e.device.id===u.id);if(e)return ee(t,e)?P("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."}):P("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:u.id,deviceName:u.name,hint:q(e,"device-in-use")});let i=await rr({req:t,sessionName:r,sessionStore:a,device:u,surface:c,openTarget:s});return"response"===i.type?i.response:await rs({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 ru={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)}},rc={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 rd(e){let{req:r,command:n,sessionName:a,sessionStore:i,deployOps:o}=e,s=i.get(a),l=r.flags??{},u=N(n,s,l);if(u)return u;let c=r.positionals?.[0]?.trim(),d=r.positionals?.[1]?.trim();if(!c||!d)return P("INVALID_ARGS",`${n} requires: ${n} <app> <path-to-app-binary>`);let p=r.meta?.uploadedArtifactId;try{var f;let e,a=p?ef(p,r.meta?.tenantId):ei.expandHome(d);if(!t.existsSync(a))return P("INVALID_ARGS",`App binary not found: ${a}`);let u=await y({session:s,flags:l,ensureReady:!1});if(!ex(n,u))return P("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=eF(e,(f=e,`Installed: ${f.appName??eE(f)}`));return s&&i.recordAction(s,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&x(p)}}async function rp(e,t,r){return await eQ(e,t,r)}async function rf(e){let{req:t,sessionName:r,sessionStore:n}=e;if("session_list"===t.command){let e=ew(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=eJ(t.flags?.androidDeviceAllowlist),r=eO(t.flags?.platform),n=f({simulatorSetPath:eK(t.flags?.iosSimulatorDeviceSet),platform:r,target:t.flags?.target}),a=await ea({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?ek(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 P(e.code,e.message,e.details)}if("apps"===t.command){let e=n.get(r),a=t.flags??{},i=N(t.command,e,a);if(i)return i;let o=await y({session:e,flags:a,ensureReady:!0});if(!ex("apps",o))return P("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=e1(t.flags?.appsFilter);return ek(o.platform)?{ok:!0,data:{apps:(await e2(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}:{ok:!0,data:{apps:(await eZ(o,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}return null}async function rm(e){let{ensureAndroidEmulatorBooted:t}=await import("./8806.js");return await t(e)}let rh='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',rw='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function rg(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r),i=t.flags??{},o=eO(i.platform);if(!a&&Y(i))return P("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=N("appstate",a,i);if(s)return s;let l=ek(a?.device.platform)&&w(i,a);if("ios"===o&&!l)return P("SESSION_NOT_FOUND",rh);if("macos"===o&&!l)return P("SESSION_NOT_FOUND",rw);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 P("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 P("SESSION_NOT_FOUND",rh);if("macos"===u.platform)return P("SESSION_NOT_FOUND",rw);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 ry(e){let{req:t,sessionName:r,sessionStore:n}=e;if("boot"===t.command){let e,a=n.get(r),i=t.flags??{},o=N(t.command,a,i);if(o)return o;let s="android"===(eO(i.platform)??a?.device.platform),l=!0===i.headless;if(l&&!s)return P("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 P("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 rm({avdName:c,serial:i.serial,headless:l}),p=!0}if(i.target&&(e.target??"mobile")!==i.target)return P("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${i.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return P("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 P("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");e=await rm({avdName:t,serial:i.serial,headless:!0})}await eg(e)}else("android"!==e.platform||!0!==e.booted)&&await eg(e);return ex("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:P("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await rg({req:t,sessionName:r,sessionStore:n}):null}function rv(e,t){for(let r of e){if(t(r))return r;let e=rv(r.children,t);if(e)return e}}function rA(e,t){let r=[];for(let n of e)t(n)&&r.push(n),r.push(...rA(n.children,t));return r}function rb(e,t){let r=rv(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 rS(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 rI(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:rS(e):null}let r_="xctrace-animation-hitches";function rN(e,t){let r=eI(e),n=rb(r,t);return{rows:0===n.length?[]:rA(r,e=>"row"===e.name),schema:n}}function rM(e,t){for(let r of e)rM(r.children,t),r.attributes.id&&t.set(r.attributes.id,{numberValue:rS(r),process:rx(r)})}function rx(e){if(!e||e.children.some(e=>"sentinel"===e.name))return null;let t=rS(rv(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 rk="ps-process-snapshot",rD="ps-process-snapshot",rO="xctrace-activity-monitor",rR="xctrace-activity-monitor";async function rL(e,t){if("ios"===e.platform&&"device"===e.kind)return await rq(e,t);let r=await rG(e,t),n=await rz(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:rk,memoryMethod:rD})}async function rP(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 rj(e,t),f=await r$(e,t,p);return n=rN((r={hitchesXml:f.hitchesXml,frameLifetimesXml:f.frameLifetimesXml,displayInfoXml:f.displayInfoXml,processIds:p.map(e=>e.pid),processNames:V(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}=rN(e,"device-display-info"),n=r.indexOf("max-refresh-rate");if(n<0)return;let a=new Map;for(let e of t){rM(e.children,a);let t=rI(e.children[n],a);if(null!==t&&t>0)return t}}(r.displayInfoXml),l=(s=(function(e){let t,r,n=eI(e),a=Object.values(r={start:(t=rb(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 rA(n,e=>"row"===e.name).map(e=>(function(e,t,r){var n,a,i;let o;if(rM(e.children,r),!0===(n=e.children[t.isSystem],null===(o=rI(n,r))?null:0!==o))return null;let s=rI(e.children[t.start],r),l=rI(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:rx(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:tq(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?tq(l/n*100):0,droppedFrameCount:l,totalFrameCount:n,sampleWindowMs:u,windowStartedAt:r.windowStartedAt,windowEndedAt:r.windowEndedAt,measuredAt:r.measuredAt,method:r_,matchedProcesses:[...new Set(s.map(e=>e.processName).filter(e=>"string"==typeof e&&e.length>0))],frameDeadlineMs:void 0===o?void 0:tq(1e3/o),refreshRateHz:o,worstWindows:c.length>0?c:void 0}}async function r$(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 rF({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 rV(e,t,s,"hitches",l),await rV(e,t,s,"hitches-frame-lifetimes",u);let a=await rT(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 rF(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 rC(s,e.tracePath);if(0===l.result.exitCode)return e.validateTraceOutput&&await rE(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:rY(l.result.stdout,l.result.stderr)})}async function rC(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 rE(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 rV(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:rY(o.stdout,o.stderr)})}async function rT(e,t,r,n,a){try{return await rV(e,t,r,n,a),!0}catch{return!1}}async function rU(e){let t=eI(e),r=rb(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=rA(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=rv(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:rS(e),processName:rX(e)})}let r=rI(t[n],u),s=(c=t[a],p=u,c?c.attributes.ref?p.get(c.attributes.ref)?.processName??null:rX(c):null);null!==r&&Number.isFinite(r)&&s&&l.push({pid:r,processName:s,cpuTimeNs:rI(t[i],u),residentMemoryBytes:rI(t[o],u)})}return l}async function rG(e,t){let r="macos"===e.platform?await rH(t):await rW(e,t),n="macos"===e.platform?a.join(r,"Contents","Info.plist"):a.join(r,"Info.plist"),i=await e3(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 rq(e,t){let r=await rj(e,t),n=await rK(e,t),a=await rK(e,t),i=rB(await rU(n.xml),r,t,e),o=rB(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 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:rO,memoryMethod:rR})}async function rj(e,t){let r=(await eM(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 eD(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 rK(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 rF({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 rV(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 rB(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:rZ(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:rZ(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:V(c.map(e=>e.processName))}}async function rH(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await eN("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 rW(e,t){let r=eb(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 rz(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:eb(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of ej(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 eN("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:tq(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 rX(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function rY(e,t){let r=R(e,t);if(r)return r;let n=`${e}
3
- ${t}`.toLowerCase();return n.includes("no device matched")||n.includes("failed to find device")?et: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 rZ(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function rQ(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===tE&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:tE,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:tE,sampleCount:i.length,samples:i}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:tE},{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:tV},cpu:{available:!1,reason:tV}},sampling:{startup:{method:tE,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:tZ,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:tY,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:tK,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:r_,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:r_,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:rR,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:rO,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:rD,description:`Resident memory snapshot from ${n}`,unit:"kB"},cpu:{method:rk,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 r0(u,e,t):await r1(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 r0(e,t,r){let n=await r2(t,r);e.metrics.memory=r6(n.memory),e.metrics.cpu=r6(n.cpu),e.metrics.fps=r8(r6(n.fps),t)}async function r1(e,t){let r=await r3(t);e.metrics.memory=r6(r.memory),e.metrics.cpu=r6(r.cpu),e.metrics.fps=r8(r6(r.fps),t)}async function r2(e,t){let r=e.appBundleId,n={adb:t.androidAdb},[a,i,o]=await Promise.allSettled([t0(e.device,r,n),tQ(e.device,r,n),tJ(e.device,r,n)]);return{memory:a,cpu:i,fps:o}}async function r3(e){let t=e.appBundleId,r=await r5(rP(e.device,t)),n=await r5(rL(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 r5(e){try{return{status:"fulfilled",value:await e}}catch(e){return{status:"rejected",reason:e}}}function r6(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=c(e.reason);return{available:!1,reason:t.message,error:t}}function r8(e,t){var r,n;let a,i;if(!0!==e.available)return e;let o=(r=t.actions,a=r9((n=e).windowStartedAt),i=r9(n.windowEndedAt)??r9(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 r9(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let r4=["path","start","stop","doctor","mark","clear"],r7=`logs requires ${r4.slice(0,-1).join(", ")}, or ${r4.at(-1)}`,ne=["dump","log"],nt=`network requires ${ne.join(" or ")}`,nr=["summary","headers","body","all"],nn=`network include mode must be one of: ${nr.join(", ")}`;async function na(e){let{req:t}=e;return"perf"===t.command?ni(e):"logs"===t.command?no(e):"network"===t.command?nd(e):null}async function ni(e){let{sessionName:t,sessionStore:r,androidAdbExecutor:n}=e,a=r.get(t);if(!a)return P("SESSION_NOT_FOUND","perf requires an active session. Run open first.");try{return{ok:!0,data:await rQ(a,{androidAdb:n})}}catch(e){return{ok:!1,error:c(e)}}}async function no(e){var t,r,n;let a,i,{req:o,sessionName:s,sessionStore:l}=e,u=l.get(s);if(!u)return P("SESSION_NOT_FOUND","logs requires an active session");if(!ex("logs",u.device))return P("UNSUPPORTED_OPERATION","logs is not supported on this device");let c=(o.positionals?.[0]??"path").toLowerCase(),d=!!o.flags?.restart;return r4.includes(c)?d&&"clear"!==c?P("INVALID_ARGS","logs --restart is only supported with logs clear"):"path"===c?function(e,t,r){let n=r.resolveAppLogPath(t),a=G(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?ns(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?nl(u,s,l,d):"start"===c?nu(u,s,l):"stop"===c?nc(u,s,l):P("INVALID_ARGS",r7):P("INVALID_ARGS",r7)}async function ns(e,t,r){let n=r.resolveAppLogPath(t),a=await ed(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 nl(e,t,r,n){if(e.appLog&&!n)return P("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");if(n&&!e.appBundleId)return P("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");let a=r.resolveAppLogPath(t);if(!n)return{ok:!0,data:J(a)};e.appLog&&await eh(e.appLog);let i=J(a),o=r.resolveAppLogPidPath(t);try{let n=await eP(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 nu(e,t,r){if(e.appLog)return P("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return P("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 eP(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 nc(e,t,r){if(!e.appLog)return P("INVALID_ARGS","no app log stream active");let n=e.appLog.outPath;return await eh(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:n,stopped:!0}}}async function nd(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return P("SESSION_NOT_FOUND","network requires an active session");if(!ex("network",a.device))return P("UNSUPPORTED_OPERATION","network is not supported on this device");let i=(t.positionals?.[0]??"dump").toLowerCase();if(!ne.includes(i))return P("INVALID_ARGS",nt);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return P("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 P("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let n=(r??t??"summary").toLowerCase();return nr.includes(n)?{ok:!0,include:n}:P("INVALID_ARGS",nn)}(t);if(!s.ok)return s;let{include:l}=s,u=await Z({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 np=/^[A-Z_][A-Z0-9_]*$/,nf=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,nm="AD_VAR_";function nh(e){return e.startsWith("AD_")}function nw(e){return new d("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function ng(e){let t={};for(let[r,n]of Object.entries(e)){if("string"!=typeof n||!r.startsWith(nm))continue;let e=r.slice(nm.length);0!==e.length&&np.test(e)&&(nh(e)||(t[e]=n))}return t}function ny(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(!np.test(n))throw new d("INVALID_ARGS",`Invalid -e key "${n}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(nh(n))throw nw(n);t[n]=r.slice(e+1)}return t}function nv(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function nA(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 nb(e,t,r){return e.replace(nf,(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 nS(e,t,r){return e?function e(t,r,n){return"string"==typeof t?nb(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 nI=new Set(["ios","android","macos","linux"]),n_=new Set(["mobile","tv","desktop"]);function nN(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(nM(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(!np.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&&nI.has(e)&&nx(r,"platform",e)}let i=t.match(/(?:^|\s)target=([^\s]+)/);if(i){let e=i[1];e&&n_.has(e)&&nx(r,"target",e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&nx(r,"timeoutMs",Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&nx(r,"retries",Math.floor(e))}}return r}function nM(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function nx(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 nk(e){return!!e&&!Number.isNaN(Number(e))}function nD(e,t=[],r){return{ts:Date.now(),command:e,positionals:t,flags:r??{}}}function nO(e,t,r){let n=new Set(r),a=Object.keys(e).filter(e=>!n.has(e));if(a.length>0)throw nT(`Maestro ${t} field "${a[0]}" is not supported yet.`)}function nR(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function nL(e){return e.map((e,t)=>{if("string"==typeof e||nR(e))return e;throw new d("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function nP(e,t){if(null==e)return{};if(!nR(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 n$(e,t){return nR(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function nF(e,t){if(e.appId)return e.appId;throw new d("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function nC(e,t){if("string"==typeof t)return t;throw new d("INVALID_ARGS",`${e} expects a string value.`)}function nE(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 nV(e){throw nT(`Maestro command "${e}" is not supported yet.`)}function nT(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 ${eG}.`)}function nU(e,t,r){var n,a;if(null==e)return nD("open",[nE(nF(t,"launchApp"),r)]);if("string"==typeof e)return nD("open",[nE(e,r)]);if(!nR(e))throw new d("INVALID_ARGS","launchApp expects a string or map.");nO(e,"launchApp",["appId","stopApp","clearState","clearKeychain","arguments","permissions","launchArguments"]),nK(e,"permissions"),nK(e,"clearKeychain");let i=nE("string"==typeof e.appId?e.appId:nF(t,"launchApp"),r),o=(n=e,a=r,[...nq(n.arguments,"launchApp.arguments",a),...nq(n.launchArguments,"launchApp.launchArguments",a)]),s=!0===e.clearState;return nD("open",[i],{...!s&&(!0===e.stopApp||o.length>0)?{relaunch:!0}:{},...s?{clearAppState:!0}:{},...o.length>0?{launchArgs:o}:{}})}function nG(e,t,r){if(null==e)return nD("close",[nE(nF(t,"stopApp"),r)]);if("string"==typeof e)return nD("close",[nE(e,r)]);throw new d("INVALID_ARGS","stopApp expects a string appId or no value.")}function nq(e,t,r){if(null==e)return[];if("string"==typeof e)return[nE(e,r)];if(Array.isArray(e))return e.map((e,n)=>nj(e,`${t}[${n}]`,r));if(nR(e))return Object.entries(e).flatMap(([e,n])=>[nE(e,r),nj(n,`${t}.${e}`,r)]);throw new d("INVALID_ARGS",`${t} expects a string, list, or map.`)}function nj(e,t,r){if("string"==typeof e)return nE(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 nK(e,t){if(void 0!==e[t])throw nT(`Maestro launchApp field "${t}" is not supported yet.`)}function nB(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw nT('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 nT('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}let nW="__maestroRunScript",nz="__maestroAssertVisible",nJ="__maestroAssertNotVisible",nX="__maestroPressEnter",nY="__maestroWaitForAnimationToEnd",nZ="__maestroScrollUntilVisible",nQ="__maestroSwipeScreen",n0="__maestroSwipeOn",n1="__maestroTapOn",n2="__maestroTapPointPercent";function n3(e){if(null==e)return nD("type",["\b".repeat(50)]);if("number"==typeof e&&Number.isInteger(e)&&e>0)return nD("type",["\b".repeat(e)]);if(!nR(e))throw new d("INVALID_ARGS","eraseText expects empty, a positive count, or a map.");if(nO(e,"eraseText",["charactersToErase"]),void 0===e.charactersToErase)return nD("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 nD("type",["\b".repeat(e.charactersToErase)])}function n5(e){return"number"==typeof e&&Number.isFinite(e)?String(Math.max(16,Math.floor(e))):void 0}function n6(e,t){let r=e.toLowerCase();switch(r){case"up":case"down":case"left":case"right":return r;default:throw nT(`Maestro ${t} must be UP, DOWN, LEFT, or RIGHT.`)}}function n8(e){return n6(e,"swipe direction")}function n9(e,t,r=[],n){if("string"==typeof e)return n4(nE(e,n));if(!nR(e))throw new d("INVALID_ARGS",`${t} expects a string or selector map.`);nO(e,t,["id","text","enabled","selected",...r]);let a=[],i=[];if("boolean"==typeof e.enabled&&i.push(ae("enabled",String(e.enabled))),"boolean"==typeof e.selected&&i.push(ae("selected",String(e.selected))),"string"==typeof e.id&&a.push(ae("id",nE(e.id,n)),...i),"string"==typeof e.text&&0===a.length)return n4(nE(e.text,n),i);if("string"==typeof e.label&&0===a.length&&a.push(ae("label",nE(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 n4(e,t=[]){return[[ae("label",e),...t].join(" "),[ae("text",e),...t].join(" "),[ae("id",e),...t].join(" ")].join(" || ")}function n7(e){let t=n5(e.duration);return t?[t]:[]}function ae(e,t){return`${e}=${JSON.stringify(t)}`}function at(e){var t,r;if(!nR(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 ar(e){let t=at(e)??{};return{...t,maestro:{...t.maestro??{},allowNonHittableCoordinateFallback:!0}}}function an(e){let t={doubleTap:!0};return nR(e)&&"number"==typeof e.delay&&Number.isInteger(e.delay)&&(t.intervalMs=Math.max(0,e.delay)),t}class aa{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 ai(e,t,r){return{...nD(e,t),replayControl:r}}function ao(e,t,r){let n="string"==typeof e?nE(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 as=`
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 d,AppError as c}from"./9152.js";import{runXcrun as p,resolveAppleSimulatorSetPathForSelector as f,dispatchCommand as m,sessionMatchesScope as h,selectorTargetsSessionDevice as g,appendAppLogMarker as w,resolveCommandDevice as y,hasRuntimeTransportHints as v,getSessionCommandKind as A,inferFillText as b,formatPortableActionLine as S,stopIosRunnerSession as I,resolvePublicSessionName as _,requireSessionOrExplicitSelector as N,isTouchTargetCommand as M,resolveSessionRequestLogPath as x,cleanupUploadedArtifact as k,isClickLikeCommand as D,refreshSessionDeviceIfNeeded as R,createRequestCanceledError as O,resolveIosDevicectlHint as L,registerRequestAbort as P,errorResponse as $,IOS_SIMULATOR_POST_OPEN_SETTLE_MS as C,IOS_SIMULATOR_POST_CLOSE_SETTLE_MS as F,parseReplayOpenFlags as E,settleIosSimulator as V,uniqueStrings as T,applyRuntimeHintsToApp as U,withKeyedLock as G,buildSessionRecoveryHint as q,resolveTargetDevice as j,getAppLogPathMetadata as K,parseReplayRuntimeFlags as B,setSessionSnapshot as H,getSnapshotReferenceFrame as W,clearRuntimeHintsFromApp as z,handleCloseCommand as J,clearAppLogFiles as X,prepareIosRunner as Y,session_device_utils_hasExplicitSessionFlag as Z,readSessionNetworkCapture as Q,cleanupRetainedMaterializedPaths as ee,isImplicitSessionScopeConflict as et,resolveSessionRunnerLogPath as er,IOS_DEVICECTL_DEFAULT_HINT as en,buildSnapshotState as ea,context_contextFromFlags as ei,listDeviceInventory as eo,SessionStore as es,formatScriptStringLiteral as el,formatScriptActionSummary as eu,isRequestCanceled as ed,resolveRequestTrackingId as ec,retainMaterializedPaths as ep,runAppLogDoctor as ef,resolvePayloadInput as em,prepareUploadedArtifact as eh,markRequestCanceled as eg,stopAppLog as ew,resolveImplicitSessionScope as ey,ensureDeviceReady as ev,prewarmIosRunnerSession as eA,clearRequestCanceled as eb,buildSimctlArgsForDevice as eS,resolveAndroidEmulatorAvdName as eI,parseReplaySeriesFlags as e_,parseXmlDocumentSync as eN,resolveFrontmostMacOsApp as eM,runAppleToolCommand as ex,matchesPlatformSelector as ek,isCommandSupportedOnDevice as eD,listIosDeviceApps as eR,isApplePlatform as eO,listIosDeviceProcesses as eL,normalizePlatformSelector as eP,getRequestSignal as e$,markAndroidSnapshotFreshness as eC,startAppLog as eF,emitRequestProgress as eE}from"./2415.js";import{withSuccessText as eV,successText as eT}from"./1998.js";import{resolveDeployResultTarget as eU,resolveInstallFromSourceResultTarget as eG}from"./6232.js";import{parseSessionSurface as eq,MAESTRO_COMPAT_TRACKER_URL as ej,MAESTRO_NEW_ISSUE_URL as eK}from"./1352.js";import{resolveAndroidAdbExecutor as eB}from"./9639.js";import{splitNonEmptyTrimmedLines as eH}from"./7455.js";import{resolveIosSimulatorDeviceSetPath as eW,classifyAndroidAppTarget as ez,resolveIosDeviceDeepLinkBundleId as eJ,isInfrastructureBootFailureReason as eX,isWebUrl as eY,resolveAndroidSerialAllowlist as eZ,isDeepLinkTarget as eQ,formatAndroidInstalledPackageRequiredMessage as e0,listAndroidApps as e1}from"./8806.js";import{getDiagnosticsMeta as e2,emitDiagnostic as e3}from"./7599.js";import{runBatch as e5,mergeParentFlags as e6}from"./1231.js";import{assertResolvedAppsFilter as e8}from"./1393.js";import{listIosApps as e9,readInfoPlistString as e4}from"./apps.js";import{isPerfAction as e7,PERF_AREA_ERROR_MESSAGE as te,PERF_ACTION_ERROR_MESSAGE as tt,isPerfArea as tr}from"./8020.js";import{readScreenshotScriptFlag as tn}from"./5310.js";import{runCmdSync as ta}from"./9818.js";import{splitSelectorFromArgs as ti,extractNodeText as to,findSnapshotAncestor as ts,isDescendantOfSnapshotNode as tl,splitIsSelectorArgs as tu,tryParseSelectorChain as td,parseSelectorChain as tc,resolveSelectorChain as tp,buildSelectorChainForNode as tf,buildSnapshotNodeByIndex as tm,matchesSelector as th,normalizeType as tg}from"./940.js";import{normalizeText as tw}from"./7556.js";import{pointFromPercent as ty,clampToRange as tv,buildSwipeGesturePlan as tA,evaluateIsPredicate as tb,pointInsideRect as tS,readReactNativeOverlayActionNodes as tI,detectReactNativeOverlay as t_,clampGesturePoint as tN,buildSnapshotDisplayLines as tM}from"./9533.js";import{sleep as tx}from"./4829.js";import{INTERNAL_COMMANDS as tk,PUBLIC_COMMANDS as tD}from"./5792.js";import{trimRuntimeValue as tR}from"./8656.js";var tO={};async function tL(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 c("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await ev(e.session.device),e.session.device}if(!r)throw new c("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let n=await j(e.flags??{});return await ev(n),n}async function tP(e){let{prepared:t,retention:r,req:n,session:a,sessionName:i}=e;if(r.enabled)return await ep({archivePath:t.archivePath,installablePath:t.installablePath,tenantId:n.meta?.tenantId,sessionName:a?i:void 0,ttlMs:r.ttlMs})}function t$(e){return e?{...e.archivePath?{archivePath:e.archivePath}:{},installablePath:e.installablePath,materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}}async function tC(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 c("INVALID_ARGS","install_from_source requires a source payload");switch(t.kind){case"url":if(!t.url||0===t.url.trim().length)throw new c("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 c("INVALID_ARGS","install_from_source path source requires a non-empty path");return t;case"github-actions-artifact":throw new c("UNSUPPORTED_OPERATION","install_from_source github-actions-artifact sources require a compatible remote daemon");default:throw new c("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:eh(i,t.meta?.tenantId)},cleanup:()=>{k(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 c("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),l=await tL({session:a,flags:t.flags});if(!eD("install",l))return $("UNSUPPORTED_OPERATION","install_from_source is not supported on this device");let u=e$(t.meta?.requestId),d=async(e,i)=>{let l;try{var u;l=await tP({prepared:e,retention:s,req:t,session:a,sessionName:r});let o=await i(l),d=eV(o,(u=o,`Installed: ${eG(u)}`));return!function(e){let{session:t,sessionStore:r,req:n,data:a}=e;t&&r.recordAction(t,{command:"install_source",positionals:[],flags:n.flags??{},result:a})}({session:a,sessionStore:n,req:t,data:d}),{ok:!0,data:d}}catch(e){throw l&&await ee(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 d(r,async t=>{if(await e(l,r.installablePath),!r.bundleId)throw new c("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");return{...t$(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 d(m,async e=>{let t=await f(l,m.installablePath,m.packageName);if(!t)throw new c("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{...t$(e),packageName:t,...n?{appName:n}:{},launchTarget:t}})}catch(e){return{ok:!1,error:d(e)}}}async function tF(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new c("INVALID_ARGS","release_materialized_paths requires a materializationId");return await ee(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:d(e)}}}e.r(tO),e.d(tO,{handleSessionCommands:()=>ow});let tE=["platform","metroHost","metroPort","bundleUrl","launchUrl"];function tV(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function tT(e,t){if(void 0!==e){if("string"!=typeof e)throw new c("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return tR(e)}}function tU(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new c("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function tG(e){if("ios"===e||"android"===e)return e}async function tq(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:n,session:a}=e;!t||!a?.appBundleId||!v(r)||v(n)||await z({device:a.device,appId:a.appBundleId})}async function tj(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 $("INVALID_ARGS","runtime requires set, show, or clear");if("clear"===o){v(l)&&s?.appBundleId&&await z({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=tG(eP(n.flags?.platform)??l?.platform??s?.device.platform);if(!u)return $("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 $("INVALID_ARGS",`runtime set targets ${u}, but session "${a}" is already bound to ${s.device.platform}.`);let d={platform:(t=n.flags,r={platform:u,metroHost:tR(t?.metroHost),metroPort:tU(t?.metroPort),bundleUrl:tR(t?.bundleUrl),launchUrl:tR(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===tV(d)?$("INVALID_ARGS","runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."):(i.setRuntimeHints(a,d),{ok:!0,data:{session:a,configured:!0,runtime:d}})}let tK="open-command-roundtrip",tB="Not implemented for this platform in this release.",tH=new Set(["app","desktop","frontmost-app"]);async function tW(e){if("app"===e||"desktop"===e||"menubar"===e)return{};let t=await eM();return{appBundleId:t.bundleId,appName:t.appName}}function tz(e){let t=e.replaceAll(",","").match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let r=Number(t[0]);return Number.isFinite(r)?r:null}function tJ(e){return Math.round(10*e)/10}function tX(e){return Math.round(10*e)/10}let tY="adb-shell-dumpsys-gfxinfo-framestats",tZ="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.";function tQ(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 t0(e){return 0===e.length?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function t1(e,t){if(void 0!==e&&void 0!==t)return Math.max(0,Math.round((t-e)/1e6))}function t2(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:tz(a)??void 0}async function t3(e,t,r={}){var n,a,i,o,s,l,u,d;let p=eB(e,r.adb);try{let u,d,f,m,h,g,w,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 c("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=t2(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=tz(a)??void 0,s=Number(i);if(void 0===o||!Number.isFinite(s)||r<0)return;let l=t2(t,"Uptime"),u=t2(t,"Stats since");return{droppedFramePercent:tJ(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=tQ(e,t,"Flags"),n=tQ(e,t,"IntendedVsync"),a=tQ(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 c("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 c("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),g=Date.parse(a),w=function(e){let{frames:t,measuredAtMs:r,summary:n}=e,a=t0(t),i=n?.statsSinceNs,o=i??a.firstFrameNs,s=t1(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:g,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??w.sampleWindowMs??function(e){if(0===e.length)return;let t=t0(e);return t1(t.firstFrameNs,t.lastFrameNs)}(m),i=f,o=m,s=y,u=i?.totalFrameCount??o.length,d=i?.droppedFrameCount??s.length,A={totalFrameCount:u,droppedFrameCount:d,droppedFramePercent:i?.droppedFramePercent??(u>0?tJ(d/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:tX(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:w,measuredAtMs:g,summary:f}),{...A,sampleWindowMs:v,...(l=h,{frameDeadlineMs:void 0===l?void 0:tX(l/1e6),refreshRateHz:void 0===l?void 0:tX(1e9/l)}),windowStartedAt:w.windowStartedAt,windowEndedAt:w.windowEndedAt,timestampSource:w.timestampSource,measuredAt:a,method:tY,source:f?"android-gfxinfo-summary":"framestats-rows",worstWindows:b&&b.length>0?b:void 0});return await t5(e,t,r),S}catch(e){throw u=t,(d=e)instanceof c?new c(d.code,d.message,{...d.details??{},metric:"fps",package:u},d):new c("COMMAND_FAILED",`Failed to sample Android fps for ${u}`,{metric:"fps",package:u},d)}}async function t5(e,t,r={}){let n=eB(e,r.adb);try{await n(["shell","dumpsys","gfxinfo",t,"reset"],{allowFailure:!0,timeoutMs:3e3})}catch{}}let t6="adb-shell-dumpsys-cpuinfo",t8="adb-shell-dumpsys-meminfo";async function t9(e,t,r={}){let n=eB(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 eH(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:tJ(a),measuredAt:r,method:t6,matchedProcesses:[...n]}}(e.stdout,t,new Date().toISOString())}catch(e){throw t7("cpu",t,e)}}async function t4(e,t,r={}){let n=eB(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 c("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=re(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!==tz(e));if(!r)break;return tz(r)??void 0}}(e);if(void 0===n)throw new c("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:re(e,"TOTAL RSS"),measuredAt:r,method:t8}}(e.stdout,t,new Date().toISOString())}catch(e){throw t7("memory",t,e)}}function t7(e,t,r){return r instanceof c?new c(r.code,r.message,{...r.details??{},metric:e,package:t},r):new c("COMMAND_FAILED",`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function re(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:tz(a)??void 0}async function rt(e,t,r){if(("ios"===e.platform||"macos"===e.platform)&&t)return eQ(t)?"macos"===e.platform?void 0:"device"===e.kind?eJ(r,t):eY(t)?void 0:r??await rr(e,t):await rn(e,t)}async function rr(e,t){try{let{resolveIosSimulatorDeepLinkBundleId:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function rn(e,t){try{let{resolveIosApp:r}=await import("./apps.js");return await r(e,t)}catch{return}}async function ra(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 ri(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 ro(e,t,r,n){return await rt(e,t,r)??await n(e,t)??("android"===e.platform&&t&&eQ(t)?r:void 0)}function rs(e){return $("INVALID_ARGS",e)}function rl(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=eq(r);if(!tH.has(e))throw new c("INVALID_ARGS",`Linux supports --surface app, desktop, and frontmost-app (got "${r}")`);if("app"!==e&&n)throw new c("INVALID_ARGS",`open --surface ${e} does not accept an app target`);return e}if("macos"!==t.platform){if(r)throw new c("INVALID_ARGS","surface is only supported on macOS and Linux");return"app"}let i=r?eq(r):"app";if("app"!==i&&"menubar"!==i&&n)throw new c("INVALID_ARGS",`open --surface ${i} does not accept an app target`);return i}({device:e,surfaceFlag:t,openTarget:r,existingSurface:n})}catch(e){return $(e instanceof c?e.code:"INVALID_ARGS",String(e.message))}}function ru(e){let{shouldRelaunch:t,openTarget:r,surface:n,device:a}=e;return t?r&&eQ(r)?rs("open --relaunch does not support URL targets."):"app"!==n?rs("open --relaunch is supported only for app surfaces."):"android"===a.platform&&r&&"binary"===ez(r)?rs(e0(r)):null:null}async function rd(e){let{req:t,sessionName:r,sessionStore:n,device:a,surface:i,openTarget:o,existingSession:s}=e;await ev(a);let{appBundleId:l,appName:d}=await rc({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 c("INVALID_ARGS","open runtime must be an object.");let a=Object.keys(t).find(e=>!tE.includes(e));if(a)throw new c("INVALID_ARGS",`Invalid open runtime field: ${a}. Supported fields are ${tE.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new c("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new c("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,n),metroHost:tT(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new c("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return tU(e)}}(t.metroPort),bundleUrl:tT(t.bundleUrl,"bundleUrl"),launchUrl:tT(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:n,platform:tG(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=tG(a);if(n.platform&&r&&!i)throw new c("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 c("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&&tV(o)>0?o:void 0,previousRuntime:i,replacedStoredRuntime:!0}}(e)}}catch(t){let e=u(t);return $(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 tq({replacedStoredRuntime:r,previousRuntime:t,runtime:e,session:s})}return{type:"details",details:{appBundleId:l,appName:d,runtime:p.data.runtime}}}async function rc(e){let{device:t,surface:r,openTarget:n,existingAppBundleId:a}=e,i=await tW(r);return{appBundleId:i.appBundleId??await ro(t,n,a,ra),appName:i.appName??n}}let rp=new Map;async function rf(e){let{device:t,closeTarget:r,outFlag:n,context:a}=e;"android"!==t.platform&&await I(t.id),await m(t,"close",[r],n,a),await V(t,F)}async function rm(e){var t,r;let n,{runtime:a,device:i,req:o,logPath:s,appBundleId:l,traceLogPath:u,openPositionals:d}=e,c=a?.launchUrl;if(!c||0===d.length||d.length>1)return;let p=d[0]?.trim();!p||eQ(p)||await m(i,"open",[c],o.flags?.out,{...(t=s,r=o.flags,n=ei(t,r,l,u),delete n.launchConsole,delete n.launchArgs,n)})}async function rh(e){var t,r,n,a;let i,{req:o,sessionName:s,sessionStore:l,logPath:u,device:d,openTarget:c,openPositionals:p,appName:f,surface:h,appBundleId:g,runtime:w,existingSession:y}=e,v=o.flags?.relaunch===!0,A=y?.trace?.outPath,b=g,S=Date.now(),I={};if(v&&c){let e=b??c,t=Date.now();await rf({device:d,closeTarget:e,outFlag:o.flags?.out,context:{...ei(u,o.flags,b??y?.appBundleId,A)}}),I.relaunchCloseDurationMs=Math.max(0,Date.now()-t)}let N=Date.now();await U({device:d,appId:b,runtime:w}),I.runtimeHintsDurationMs=Math.max(0,Date.now()-N);let M="ios"===d.platform&&"app"===h&&p.length>0,k={verbose:o.flags?.verbose,logPath:u,traceLogPath:A,requestId:o.meta?.requestId},D=o.flags?.maestro?.prewarmRunnerBeforeOpen===!0;if(M&&b&&(I.runnerPrewarmKind="session",I.runnerPrewarmScheduled=!0,D)){i=eA(d,k);let e=Date.now();await i,I.runnerPrewarmWaited=!0,I.runnerPrewarmDurationMs=Math.max(0,Date.now()-e)}let R=Date.now();await m(d,"open",p,o.flags?.out,{...ei(u,o.flags,b)}),I.openDispatchDurationMs=Math.max(0,Date.now()-R);let L=Date.now();if(await rm({runtime:w,device:d,req:o,logPath:u,appBundleId:b,traceLogPath:A,openPositionals:p}),I.launchUrlDurationMs=Math.max(0,Date.now()-L),M&&b&&!i&&(i=eA(d,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 ri(d,c,b),"android"===d.platform&&b&&await t5(d,b);let P=c?(t=b,{durationMs:Math.max(0,Date.now()-R),measuredAt:new Date().toISOString(),method:tK,appTarget:c,appBundleId:t}):void 0,F=Date.now();if(await V(d,C),I.postOpenSettleDurationMs=Math.max(0,Date.now()-F),ed(o.meta?.requestId)){let e=O();return $(e.code,e.message,e.details)}y&&eC(y,"open",y.snapshot);let E=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??_(o),sessionScope:y?.sessionScope??ey(o),device:d,surface:h,appBundleId:b,appName:f,saveScript:!!o.flags?.saveScript});void 0!==o.runtime&&(r=l,n=s,(a=w)&&(0===tV(a)?r.clearRuntimeHints(n):r.setRuntimeHints(n,a)));let T=l.ensureSessionDir(s),G=x(T,o.meta?.requestId??e2().requestId);I.totalDurationMs=Math.max(0,Date.now()-S);let q=function(e){let{sessionName:t,sessionStateDir:r,runnerLogPath:n,requestLogPath:a,appName:i,appBundleId:o,surface:s,startup:l,timing:u,device:d,runtime:c,runtimeHintCount:p}=e,f={session:t,surface:s,sessionStateDir:r,runnerLogPath:n,requestLogPath:a};return i&&(f.appName=i),o&&(f.appBundleId=o),l&&(f.startup=l),u&&(f.timing=u),c&&p(c)>0&&(f.runtime=c),d&&(f.platform=d.platform,f.target=d.target??"mobile",f.device=d.name,f.id=d.id,f.kind=d.kind,"android"===d.platform&&(f.serial=d.id)),d?.platform==="ios"&&(f.device_udid=d.id,f.ios_simulator_device_set=d.simulatorSetPath??null),{...f,...eT(`Opened: ${i??o??t}`)}}({sessionName:E.name,sessionStateDir:T,runnerLogPath:er(T),requestLogPath:G,appName:f,appBundleId:b,surface:h,startup:P,timing:I,device:d,runtime:w,runtimeHintCount:tV});return l.recordAction(E,{command:"open",positionals:p,flags:o.flags??{},runtime:void 0!==o.runtime?w:void 0,result:q}),l.set(s,E),{ok:!0,data:q}}async function rg(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=rl(i.device,t.flags?.surface,s,i.surface);if("string"!=typeof l)return l;if(!s&&"app"===l)return e?rs("open --relaunch requires an app name or an active session app."):rs("Session already active. Close it first or pass a new --session name.");let u=ru({shouldRelaunch:e,openTarget:s,surface:l,device:i.device});if(u)return u;let d=await R(i.device),c=await rd({req:t,sessionName:r,sessionStore:a,device:d,surface:l,openTarget:s,existingSession:i});return"response"===c.type?c.response:await rh({req:t,sessionName:r,sessionStore:a,logPath:n,device:d,openTarget:s,openPositionals:o?t.positionals??[]:s?[s]:[],appBundleId:c.details.appBundleId,appName:c.details.appName,runtime:c.details.runtime,surface:l,existingSession:i})}let o=t.flags?.relaunch===!0,s=t.positionals?.[0];if(o&&!s)return rs("open --relaunch requires an app argument.");let l=function(e){let{shouldRelaunch:t,openTarget:r,platform:n}=e;return t?r&&eQ(r)?rs("open --relaunch does not support URL targets."):"android"===n&&r&&"binary"===ez(r)?rs(e0(r)):null:null}({shouldRelaunch:o,openTarget:s,platform:t.flags?.platform==="android"?"android":void 0});if(l)return l;let u=await j(t.flags??{}),d=rl(u,t.flags?.surface,s);if("string"!=typeof d)return d;let c=ru({shouldRelaunch:o,openTarget:s,surface:d,device:u});return c||await G(rp,u.id,async()=>{let e=a.toArray().find(e=>e.device.id===u.id);if(e)return et(t,e)?$("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."}):$("DEVICE_IN_USE",`Device is already in use by session "${e.name}".`,{session:e.name,deviceId:u.id,deviceName:u.name,hint:q(e,"device-in-use")});let i=await rd({req:t,sessionName:r,sessionStore:a,device:u,surface:d,openTarget:s});return"response"===i.type?i.response:await rh({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:d})})}let rw={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)}},ry={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 rv(e){let{req:r,command:n,sessionName:a,sessionStore:i,deployOps:o}=e,s=i.get(a),l=r.flags??{},u=N(n,s,l);if(u)return u;let d=r.positionals?.[0]?.trim(),c=r.positionals?.[1]?.trim();if(!d||!c)return $("INVALID_ARGS",`${n} requires: ${n} <app> <path-to-app-binary>`);let p=r.meta?.uploadedArtifactId;try{var f;let e,a=p?eh(p,r.meta?.tenantId):es.expandHome(c);if(!t.existsSync(a))return $("INVALID_ARGS",`App binary not found: ${a}`);let u=await y({session:s,flags:l,ensureReady:!1});if(!eD(n,u))return $("UNSUPPORTED_OPERATION",`${n} is not supported on this device`);if("ios"===u.platform){let t=await o.ios(u,d,a),r=t.bundleId;e=r?{app:d,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:d,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await o.android(u,d,a),r=t.package;e=r?{app:d,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:d,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}let m=eV(e,(f=e,`Installed: ${f.appName??eU(f)}`));return s&&i.recordAction(s,{command:n,positionals:r.positionals??[],flags:r.flags??{},result:m??{}}),{ok:!0,data:m}}finally{p&&k(p)}}async function rA(e,t,r){return await e5(e,t,r)}async function rb(e){let{req:t,sessionName:r,sessionStore:n}=e;if("session_list"===t.command){let e=ey(t);return{ok:!0,data:{sessions:n.toArray().filter(t=>h(t,e)).map(e=>{let t=n.resolveSessionDir(e.name);return{name:e.name,sessionStateDir:t,runnerLogPath:er(t),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=eP(t.flags?.platform),n=f({simulatorSetPath:eW(t.flags?.iosSimulatorDeviceSet),platform:r,target:t.flags?.target}),a=await eo({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?eO(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 $(e.code,e.message,e.details)}if("apps"===t.command){let e=n.get(r),a=t.flags??{},i=N(t.command,e,a);if(i)return i;let o=await y({session:e,flags:a,ensureReady:!0});if(!eD("apps",o))return $("UNSUPPORTED_OPERATION","apps is not supported on this device");let s=e8(t.flags?.appsFilter);return eO(o.platform)?{ok:!0,data:{apps:(await e9(o,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}:{ok:!0,data:{apps:(await e1(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 rI='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',r_='macOS appstate requires an active session on the target device. Run open first (for example: open --session macos --platform macos "System Settings").';async function rN(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r),i=t.flags??{},o=eP(i.platform);if(!a&&Z(i))return $("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=N("appstate",a,i);if(s)return s;let l=eO(a?.device.platform)&&g(i,a);if("ios"===o&&!l)return $("SESSION_NOT_FOUND",rI);if("macos"===o&&!l)return $("SESSION_NOT_FOUND",r_);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 $("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 $("SESSION_NOT_FOUND",rI);if("macos"===u.platform)return $("SESSION_NOT_FOUND",r_);let{getAndroidAppState:d}=await import("./8806.js"),c=await d(u);return{ok:!0,data:{platform:"android",package:c.package,activity:c.activity}}}async function rM(e){let{req:t,sessionName:r,sessionStore:n}=e;if("boot"===t.command){let e,a=n.get(r),i=t.flags??{},o=N(t.command,a,i);if(o)return o;let s="android"===(eP(i.platform)??a?.device.platform),l=!0===i.headless;if(l&&!s)return $("INVALID_ARGS","boot --headless is supported only for Android emulators.");let d=eI({flags:i,sessionDevice:a?.device}),c=s&&!!d,p=!1;try{e=await y({session:a,flags:i,ensureReady:!1})}catch(r){let t=u(r);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return $("INVALID_ARGS","boot --headless requires --device <avd-name> (or an Android emulator session target).");if(!c||"DEVICE_NOT_FOUND"!==t.code||!d)throw r;e=await rS({avdName:d,serial:i.serial,headless:l}),p=!0}if(i.target&&(e.target??"mobile")!==i.target)return $("DEVICE_NOT_FOUND",`No ${e.platform} device found matching --target ${i.target}.`);if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return $("INVALID_ARGS","boot --headless is supported only for Android emulators.");if(!p){let t=eI({flags:i,sessionDevice:a?.device,resolvedDevice:e});if(!t)return $("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 ev(e)}else("android"!==e.platform||!0!==e.booted)&&await ev(e);return eD("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:$("UNSUPPORTED_OPERATION","boot is not supported on this device")}return"appstate"===t.command?await rN({req:t,sessionName:r,sessionStore:n}):null}function rx(e,t){for(let r of e){if(t(r))return r;let e=rx(r.children,t);if(e)return e}}function rk(e,t){let r=[];for(let n of e)t(n)&&r.push(n),r.push(...rk(n.children,t));return r}function rD(e,t){let r=rx(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 rR(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 rO(e,t){return e?e.attributes.ref?t.get(e.attributes.ref)?.numberValue??null:rR(e):null}let rL="xctrace-animation-hitches";function rP(e,t){let r=eN(e),n=rD(r,t);return{rows:0===n.length?[]:rk(r,e=>"row"===e.name),schema:n}}function r$(e,t){for(let r of e)r$(r.children,t),r.attributes.id&&t.set(r.attributes.id,{numberValue:rR(r),process:rC(r)})}function rC(e){if(!e||e.children.some(e=>"sentinel"===e.name))return null;let t=rR(rx(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 rF="ps-process-snapshot",rE="ps-process-snapshot",rV="xctrace-activity-monitor",rT="xctrace-activity-monitor";async function rU(e,t){if("ios"===e.platform&&"device"===e.kind)return await rY(e,t);let r=await rX(e,t),n=await r3(e,r);if(0===n.length)throw new c("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 r5({usagePercent:n.reduce((e,t)=>e+t.cpuPercent,0),residentMemoryKb:n.reduce((e,t)=>e+t.rssKb,0),measuredAt:a,matchedProcesses:[r.executableName],cpuMethod:rF,memoryMethod:rE})}async function rG(e,t){var r;let n,o,s,l,u,d;if("ios"!==e.platform||"device"!==e.kind)throw new c("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 rZ(e,t),f=await rj(e,t,p);return n=rP((r={hitchesXml:f.hitchesXml,frameLifetimesXml:f.frameLifetimesXml,displayInfoXml:f.displayInfoXml,processIds:p.map(e=>e.pid),processNames:T(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}=rP(e,"device-display-info"),n=r.indexOf("max-refresh-rate");if(n<0)return;let a=new Map;for(let e of t){r$(e.children,a);let t=rO(e.children[n],a);if(null!==t&&t>0)return t}}(r.displayInfoXml),l=(s=(function(e){let t,r,n=eN(e),a=Object.values(r={start:(t=rD(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 rk(n,e=>"row"===e.name).map(e=>(function(e,t,r){var n,a,i;let o;if(r$(e.children,r),!0===(n=e.children[t.isSystem],null===(o=rO(n,r))?null:0!==o))return null;let s=rO(e.children[t.start],r),l=rO(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:rC(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))),d=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:tJ(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?tJ(l/n*100):0,droppedFrameCount:l,totalFrameCount:n,sampleWindowMs:u,windowStartedAt:r.windowStartedAt,windowEndedAt:r.windowEndedAt,measuredAt:r.measuredAt,method:rL,matchedProcesses:[...new Set(s.map(e=>e.processName).filter(e=>"string"==typeof e&&e.length>0))],frameDeadlineMs:void 0===o?void 0:tJ(1e3/o),refreshRateHz:o,worstWindows:d.length>0?d:void 0}}function rq(e){return"ios"===e.platform&&"device"===e.kind?{method:rL,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:rL,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"}}async function rj(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"),d=a.join(o,"display-info.xml");try{let n=await rK({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 rW(e,t,s,"hitches",l),await rW(e,t,s,"hitches-frame-lifetimes",u);let a=await rz(e,t,s,"device-display-info",d);return{windowStartedAt:n.startedAt,windowEndedAt:n.endedAt,hitchesXml:await r.readFile(l,"utf8"),frameLifetimesXml:await r.readFile(u,"utf8"),displayInfoXml:a?await r.readFile(d,"utf8"):void 0}}finally{await r.rm(o,{recursive:!0,force:!0}).catch(()=>{})}}async function rK(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 rB(s,e.tracePath);if(0===l.result.exitCode)return e.validateTraceOutput&&await rH(e,l.result.stdout,l.result.stderr),{startedAt:l.startedAt,endedAt:l.endedAt,capturedAtMs:l.capturedAtMs};throw new c("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:r8(l.result.stdout,l.result.stderr)})}async function rB(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 rH(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 c("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 rW(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 c("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:r8(o.stdout,o.stderr)})}async function rz(e,t,r,n,a){try{return await rW(e,t,r,n,a),!0}catch{return!1}}async function rJ(e){let t=eN(e),r=rD(t,"activity-monitor-process-live");if(0===r.length)throw new c("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 c("COMMAND_FAILED","xctrace activity-monitor-process-live export is missing expected columns");let s=rk(t,e=>"row"===e.name),l=[],u=new Map;for(let e of s){var d,p;let t=e.children;if(0===t.length)continue;for(let e of t){let t=rx(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:rR(e),processName:r6(e)})}let r=rO(t[n],u),s=(d=t[a],p=u,d?d.attributes.ref?p.get(d.attributes.ref)?.processName??null:r6(d):null);null!==r&&Number.isFinite(r)&&s&&l.push({pid:r,processName:s,cpuTimeNs:rO(t[i],u),residentMemoryBytes:rO(t[o],u)})}return l}async function rX(e,t){let r="macos"===e.platform?await r1(t):await r2(e,t),n="macos"===e.platform?a.join(r,"Contents","Info.plist"):a.join(r,"Info.plist"),i=await e4(n,"CFBundleExecutable");if(!i)throw new c("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 rY(e,t){let r=await rZ(e,t),n=await rQ(e,t),a=await rQ(e,t),i=r0(await rJ(n.xml),r,t,e),o=r0(await rJ(a.xml),r,t,e),s=a.capturedAtMs-n.capturedAtMs;if(s<=0)throw new c("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 c("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 r5({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:rV,memoryMethod:rT})}async function rZ(e,t){let r=(await eR(e,"all")).find(e=>e.bundleId===t);if(!r)throw new c("APP_NOT_INSTALLED",`No iOS device app found for ${t}`,{appBundleId:t,deviceId:e.id});if(!r.url)throw new c("COMMAND_FAILED",`Missing app bundle URL for ${t}`,{appBundleId:t,deviceId:e.id});let n=r.url.replace(/\/$/,""),a=i(n),o=(await eL(e)).filter(e=>e.executable.startsWith(`${n}/`));if(0===o.length)throw new c("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 rQ(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 rK({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 rW(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 r0(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 c("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:r9(t.cpuTimeNs,e.cpuTimeNs),residentMemoryBytes:r9(t.residentMemoryBytes,e.residentMemoryBytes)})}let d=[...u.values()],p=d.map(e=>e.cpuTimeNs).filter(e=>null!==e),f=d.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:T(d.map(e=>e.processName))}}async function r1(e){let t=`kMDItemCFBundleIdentifier == "${e.replaceAll('"','\\"')}"`,r=await ex("mdfind",[t],{allowFailure:!0,timeoutMs:15e3});if(0!==r.exitCode)throw new c("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 c("APP_NOT_INSTALLED",`No macOS app found for ${e}`,{appBundleId:e});return n}async function r2(e,t){let r=eS(e,["get_app_container",e.id,t,"app"]),n=await p(r,{allowFailure:!0,timeoutMs:15e3});if(0!==n.exitCode)throw new c("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 c("APP_NOT_INSTALLED",`No iOS simulator app container found for ${t}`,{appBundleId:t});return a}async function r3(e,t){let r="macos"===e.platform?["-axo","pid=,%cpu=,rss=,command="]:eS(e,["spawn",e.id,"ps","-axo","pid=,%cpu=,rss=,command="]);return(function(e){let t=[];for(let r of eH(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),d=o.trim();Number.isFinite(s)&&Number.isFinite(l)&&Number.isFinite(u)&&t.push({pid:s,cpuPercent:l,rssKb:u,command:d})}return t})(("macos"===e.platform?await ex("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 r5(e){return{cpu:{usagePercent:tJ(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 r6(e){let t=e?.attributes.fmt?.trim()??"";return t?t.replace(/\s+\(\d+\)$/,"").trim():null}function r8(e,t){let r=L(e,t);if(r)return r;let n=`${e}
3
+ ${t}`.toLowerCase();return n.includes("no device matched")||n.includes("failed to find device")?en: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 r9(e,t){return null===e?t:null===t?e:Math.max(e,t)}async function r4(e,t={}){var r,n;let a,i,o,s,l=(o=(i=(a=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===tK&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:tK,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:i.durationMs,lastMeasuredAt:i.measuredAt,method:tK,sampleCount:a.length,samples:a}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:tK},{session:r.name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{startup:o,...{fps:ne(),memory:{available:!1,reason:tB},cpu:{available:!1,reason:tB}}},sampling:{startup:{method:tK,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:t8,description:"Memory snapshot from adb shell dumpsys meminfo <package>. Values are reported in kilobytes.",unit:"kB"},cpu:{method:t6,description:"Aggregated CPU usage for app processes matched from adb shell dumpsys cpuinfo.",unit:"percent"},fps:{method:tY,description:tZ,unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}};var t=e.device;let r=rq(t);if("ios"===t.platform&&"device"===t.kind)return{fps:r,memory:{method:rT,description:"Resident memory snapshot from a short xctrace Activity Monitor sample on the connected iOS device.",unit:"kB"},cpu:{method:rV,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:rE,description:`Resident memory snapshot from ${n}`,unit:"kB"},cpu:{method:rF,description:`Recent CPU usage snapshot from ${n}`,unit:"percent"}}}(r)}});return ni(e)&&(e.appBundleId?"android"===e.device.platform?await nt(l,e,e.appBundleId,t):await nr(l,e,e.appBundleId):(n=l,s=no(e),n.metrics.fps={available:!1,reason:s},n.metrics.memory={available:!1,reason:s},n.metrics.cpu={available:!1,reason:s})),l}async function r7(e,t={}){var r,n;let a={session:(r=e).name,platform:r.device.platform,device:r.device.name,deviceId:r.device.id,metrics:{fps:ne()},sampling:{fps:"android"===(n=r).device.platform?{method:tY,description:tZ,unit:"percent",primaryField:"droppedFramePercent",window:"since previous Android gfxinfo reset or app process start",resetsAfterRead:!0,relatedActionsLimit:12}:rq(n.device)}};return ni(e)&&(e.appBundleId?await na(a,e,e.appBundleId,t):a.metrics.fps={available:!1,reason:no(e)}),a}function ne(){return{available:!1,reason:"Dropped-frame sampling is currently available only on Android app sessions and connected iOS device app sessions."}}async function nt(e,t,r,n){let a=await ns(t,r,n);nn(e,t,a)}async function nr(e,t,r){let n=await nl(t,r);nn(e,t,n)}function nn(e,t,r){e.metrics.memory=nd(r.memory),e.metrics.cpu=nd(r.cpu),e.metrics.fps=nc(nd(r.fps),t)}async function na(e,t,r,n){let a="android"===t.device.platform?await nu(t3(t.device,r,{adb:n.androidAdb})):await nu(rG(t.device,r));e.metrics.fps=nc(nd(a),t)}function ni(e){return"android"===e.device.platform||"ios"===e.device.platform||"macos"===e.device.platform}function no(e){return"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."}async function ns(e,t,r){let n={adb:r.androidAdb},[a,i,o]=await Promise.allSettled([t4(e.device,t,n),t9(e.device,t,n),t3(e.device,t,n)]);return{memory:a,cpu:i,fps:o}}async function nl(e,t){let r=await nu(rG(e.device,t)),n=await nu(rU(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 nu(e){try{return{status:"fulfilled",value:await e}}catch(e){return{status:"rejected",reason:e}}}function nd(e){if("fulfilled"===e.status)return{available:!0,...e.value};let t=d(e.reason);return{available:!1,reason:t.message,error:t}}function nc(e,t){var r,n;let a,i;if(!0!==e.available)return e;let o=(r=t.actions,a=np((n=e).windowStartedAt),i=np(n.windowEndedAt)??np(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 np(e){if("string"!=typeof e)return;let t=Date.parse(e);return Number.isFinite(t)?t:void 0}let nf=["path","start","stop","doctor","mark","clear"],nm=`logs requires ${nf.slice(0,-1).join(", ")}, or ${nf.at(-1)}`,nh=["dump","log"],ng=`network requires ${nh.join(" or ")}`,nw=["summary","headers","body","all"],ny=`network include mode must be one of: ${nw.join(", ")}`,nv={path:({session:e,sessionName:t,sessionStore:r})=>(function(e,t,r){let n=r.resolveAppLogPath(t),a=K(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>'}}})(e,t,r),doctor:({session:e,sessionName:t,sessionStore:r})=>nI(e,t,r),mark:({req:e,sessionName:t,sessionStore:r})=>{var n,a,i;let o,s;return n=e,a=t,i=r,o=n.positionals?.slice(1).join(" ")??"",w(s=i.resolveAppLogPath(a),o),{ok:!0,data:{path:s,marked:!0}}},clear:({session:e,sessionName:t,sessionStore:r,restart:n})=>n_(e,t,r,n),start:({session:e,sessionName:t,sessionStore:r})=>nN(e,t,r),stop:({session:e,sessionName:t,sessionStore:r})=>nM(e,t,r)};async function nA(e){let{req:t}=e;return"perf"===t.command?nb(e):"logs"===t.command?nS(e):"network"===t.command?nx(e):null}async function nb(e){let{req:t,sessionName:r,sessionStore:n,androidAdbExecutor:a}=e,i=n.get(r);if(!i)return $("SESSION_NOT_FOUND","perf requires an active session. Run open first.");let o=(t.positionals?.[0]??"metrics").toLowerCase(),s=(t.positionals?.[1]??"sample").toLowerCase();if(!tr(o))return $("INVALID_ARGS",te);if(!e7(s))return $("INVALID_ARGS",tt);try{return{ok:!0,data:"frames"===o?await r7(i,{androidAdb:a}):await r4(i,{androidAdb:a})}}catch(e){return{ok:!1,error:d(e)}}}async function nS(e){var t;let r,n,{req:a,sessionName:i,sessionStore:o}=e,s=o.get(i);if(!s)return $("SESSION_NOT_FOUND","logs requires an active session");if(!eD("logs",s.device))return $("UNSUPPORTED_OPERATION","logs is not supported on this device");let l=(t=a,r=(t.positionals?.[0]??"path").toLowerCase(),n=!!t.flags?.restart,nf.includes(r)?n&&"clear"!==r?$("INVALID_ARGS","logs --restart is only supported with logs clear"):{ok:!0,action:r,restart:n}:$("INVALID_ARGS",nm));return l.ok?await nv[l.action]({...e,session:s,restart:l.restart}):l}async function nI(e,t,r){let n=r.resolveAppLogPath(t),a=await ef(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 n_(e,t,r,n){if(e.appLog&&!n)return $("INVALID_ARGS","logs clear requires logs to be stopped first; run logs stop");let a=r.resolveAppLogPath(t);if(!n)return{ok:!0,data:X(a)};let i=e.appBundleId;if(!i)return $("INVALID_ARGS","logs clear --restart requires an app session; run open <app> first");e.appLog&&await ew(e.appLog);let o=X(a),s=r.resolveAppLogPidPath(t);try{let n=await eF(e.device,i,a,s);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:{...o,restarted:!0}}}catch(n){return r.set(t,{...e,appLog:void 0}),{ok:!1,error:d(n)}}}async function nN(e,t,r){if(e.appLog)return $("INVALID_ARGS","app log already streaming; run logs stop first");if(!e.appBundleId)return $("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 eF(e.device,e.appBundleId,n,a);return r.set(t,{...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:n,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}}),{ok:!0,data:{path:n,started:!0}}}catch(e){return{ok:!1,error:d(e)}}}async function nM(e,t,r){if(!e.appLog)return $("INVALID_ARGS","no app log stream active");let n=e.appLog.outPath;return await ew(e.appLog),r.set(t,{...e,appLog:void 0}),{ok:!0,data:{path:n,stopped:!0}}}async function nx(e){let t=function(e){let{req:t,sessionName:r,sessionStore:n}=e,a=n.get(r);if(!a)return $("SESSION_NOT_FOUND","network requires an active session");if(!eD("network",a.device))return $("UNSUPPORTED_OPERATION","network is not supported on this device");let i=(t.positionals?.[0]??"dump").toLowerCase();if(!nh.includes(i))return $("INVALID_ARGS",ng);let o=t.positionals?.[1]?Number.parseInt(t.positionals[1],10):25;if(!Number.isInteger(o)||o<1||o>200)return $("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 $("INVALID_ARGS","network include mode was provided both positionally and via --include with different values");let n=(r??t??"summary").toLowerCase();return nw.includes(n)?{ok:!0,include:n}:$("INVALID_ARGS",ny)}(t);return s.ok?{ok:!0,session:a,maxEntries:o,include:s.include}:s}(e);if(!t.ok)return t;let{include:r,maxEntries:n,session:a}=t,i=await Q({device:a.device,appBundleId:a.appBundleId,appLogState:a.appLog?.getState(),appLogStartedAt:a.appLog?.startedAt,appLogPath:e.sessionStore.resolveAppLogPath(e.sessionName),maxEntries:n,include:r,maxPayloadChars:2048,maxScanLines:4e3});return{ok:!0,data:{...i.dump,active:!!a.appLog,state:a.appLog?.getState()??"inactive",backend:i.backend,notes:i.notes}}}let nk=/^[A-Z_][A-Z0-9_]*$/,nD=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,nR="AD_VAR_";function nO(e){return e.startsWith("AD_")}function nL(e){return new c("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function nP(e){let t={};for(let[r,n]of Object.entries(e)){if("string"!=typeof n||!r.startsWith(nR))continue;let e=r.slice(nR.length);0!==e.length&&nk.test(e)&&(nO(e)||(t[e]=n))}return t}function n$(e){let t={};for(let r of e){let e=r.indexOf("=");if(e<=0)throw new c("INVALID_ARGS",`Invalid -e entry "${r}": expected KEY=VALUE.`);let n=r.slice(0,e);if(!nk.test(n))throw new c("INVALID_ARGS",`Invalid -e key "${n}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(nO(n))throw nL(n);t[n]=r.slice(e+1)}return t}function nC(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 nE(e,t,r){return e.replace(nD,(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 c("INVALID_ARGS",`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function nV(e,t,r){return e?function e(t,r,n){return"string"==typeof t?nE(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 nT=new Set(["ios","android","macos","linux"]),nU=new Set(["mobile","tv","desktop"]);function nG(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(nq(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 c("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let a=r.slice(0,n);if(!nk.test(a))throw new c("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 c("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 c("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 c("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&&nT.has(e)&&nj(r,"platform",e)}let i=t.match(/(?:^|\s)target=([^\s]+)/);if(i){let e=i[1];e&&nU.has(e)&&nj(r,"target",e)}let o=t.match(/(?:^|\s)timeout=(\d+)/);if(o){let e=Number(o[1]);Number.isFinite(e)&&e>=1&&nj(r,"timeoutMs",Math.floor(e))}let s=t.match(/(?:^|\s)retries=(\d+)/);if(s){let e=Number(s[1]);Number.isFinite(e)&&e>=0&&nj(r,"retries",Math.floor(e))}}return r}function nq(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function nj(e,t,r){let n=e[t];if(void 0!==n)throw new c("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 nK(e){return!!e&&!Number.isNaN(Number(e))}function nB(e,t=[],r){return{ts:Date.now(),command:e,positionals:t,flags:r??{}}}function nH(e,t,r){let n=new Set(r),a=Object.keys(e).filter(e=>!n.has(e));if(a.length>0)throw n1(`Maestro ${t} field "${a[0]}" is not supported yet.`)}function nW(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function nz(e){return e.map((e,t)=>{if("string"==typeof e||nW(e))return e;throw new c("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function nJ(e,t){if(null==e)return{};if(!nW(e))throw new c("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 nW(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function nY(e,t){if(e.appId)return e.appId;throw new c("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function nZ(e,t){if("string"==typeof t)return t;throw new c("INVALID_ARGS",`${e} expects a string value.`)}function nQ(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 n0(e){throw n1(`Maestro command "${e}" is not supported yet.`)}function n1(e){throw new c("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${ej}. If this syntax matters for your flows, comment there or open a focused issue at ${eK}.`)}function n2(e,t,r){var n,a;if(null==e)return nB("open",[nQ(nY(t,"launchApp"),r)]);if("string"==typeof e)return nB("open",[nQ(e,r)]);if(!nW(e))throw new c("INVALID_ARGS","launchApp expects a string or map.");nH(e,"launchApp",["appId","stopApp","clearState","clearKeychain","arguments","permissions","launchArguments"]),n8(e,"permissions"),n8(e,"clearKeychain");let i=nQ("string"==typeof e.appId?e.appId:nY(t,"launchApp"),r),o=(n=e,a=r,[...n5(n.arguments,"launchApp.arguments",a),...n5(n.launchArguments,"launchApp.launchArguments",a)]),s=!0===e.clearState;return nB("open",[i],{...!s&&(!0===e.stopApp||o.length>0)?{relaunch:!0}:{},...s?{clearAppState:!0}:{},...o.length>0?{launchArgs:o}:{}})}function n3(e,t,r){if(null==e)return nB("close",[nQ(nY(t,"stopApp"),r)]);if("string"==typeof e)return nB("close",[nQ(e,r)]);throw new c("INVALID_ARGS","stopApp expects a string appId or no value.")}function n5(e,t,r){if(null==e)return[];if("string"==typeof e)return[nQ(e,r)];if(Array.isArray(e))return e.map((e,n)=>n6(e,`${t}[${n}]`,r));if(nW(e))return Object.entries(e).flatMap(([e,n])=>[nQ(e,r),n6(n,`${t}.${e}`,r)]);throw new c("INVALID_ARGS",`${t} expects a string, list, or map.`)}function n6(e,t,r){if("string"==typeof e)return nQ(e,r);if("number"==typeof e||"boolean"==typeof e)return String(e);throw new c("INVALID_ARGS",`${t} must be a string, number, or boolean.`)}function n8(e,t){if(void 0!==e[t])throw n1(`Maestro launchApp field "${t}" is not supported yet.`)}function n9(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw n1('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function n4(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 n1('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}let n7="__maestroRunScript",ae="__maestroAssertVisible",at="__maestroAssertNotVisible",ar="__maestroPressEnter",an="__maestroWaitForAnimationToEnd",aa="__maestroScrollUntilVisible",ai="__maestroSwipeScreen",ao="__maestroSwipeOn",as="__maestroTapOn",al="__maestroTapPointPercent";function au(e){if(null==e)return nB("type",["\b".repeat(50)]);if("number"==typeof e&&Number.isInteger(e)&&e>0)return nB("type",["\b".repeat(e)]);if(!nW(e))throw new c("INVALID_ARGS","eraseText expects empty, a positive count, or a map.");if(nH(e,"eraseText",["charactersToErase"]),void 0===e.charactersToErase)return nB("type",["\b".repeat(50)]);if("number"!=typeof e.charactersToErase||!Number.isInteger(e.charactersToErase)||e.charactersToErase<=0)throw new c("INVALID_ARGS","eraseText.charactersToErase must be a positive integer.");return nB("type",["\b".repeat(e.charactersToErase)])}function ad(e){return"number"==typeof e&&Number.isFinite(e)?String(Math.max(16,Math.floor(e))):void 0}function ac(e,t){let r=e.toLowerCase();switch(r){case"up":case"down":case"left":case"right":return r;default:throw n1(`Maestro ${t} must be UP, DOWN, LEFT, or RIGHT.`)}}function ap(e){return ac(e,"swipe direction")}function af(e,t,r=[],n){if("string"==typeof e)return am(nQ(e,n));if(!nW(e))throw new c("INVALID_ARGS",`${t} expects a string or selector map.`);nH(e,t,["id","text","enabled","selected",...r]);let a=[],i=[];if("boolean"==typeof e.enabled&&i.push(ag("enabled",String(e.enabled))),"boolean"==typeof e.selected&&i.push(ag("selected",String(e.selected))),"string"==typeof e.id&&a.push(ag("id",nQ(e.id,n)),...i),"string"==typeof e.text&&0===a.length)return am(nQ(e.text,n),i);if("string"==typeof e.label&&0===a.length&&a.push(ag("label",nQ(e.label,n)),...i),0===a.length&&i.length>0&&a.push(...i),0===a.length)throw new c("INVALID_ARGS",`${t} selector map must include one of id, text, label, enabled, or selected.`);return a.join(" ")}function am(e,t=[]){return[[ag("label",e),...t].join(" "),[ag("text",e),...t].join(" "),[ag("id",e),...t].join(" ")].join(" || ")}function ah(e){let t=ad(e.duration);return t?[t]:[]}function ag(e,t){return`${e}=${JSON.stringify(t)}`}function aw(e){var t,r;if(!nW(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 ay(e){let t=aw(e)??{};return{...t,maestro:{...t.maestro??{},allowNonHittableCoordinateFallback:!0}}}function av(e){let t={doubleTap:!0};return nW(e)&&"number"==typeof e.delay&&Number.isInteger(e.delay)&&(t.intervalMs=Math.max(0,e.delay)),t}class aA{index=0;tokens;context;constructor(e,t){this.tokens=e,this.context=t}parse(){let e=this.parseOr();if(this.peek())throw new c("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 c("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 c("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 c("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 c("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 c("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 ab(e,t,r){return{...nB(e,t),replayControl:r}}function aS(e,t,r){let n="string"==typeof e?nQ(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 c("INVALID_ARGS",`${r} must be a non-negative integer or \${VAR} resolving to one.`);return a}let aI=`
4
4
  const fs = require('node:fs');
5
5
  const input = JSON.parse(fs.readFileSync(0, 'utf8'));
6
6
  if (typeof fetch !== 'function') {
@@ -21,11 +21,11 @@ fetch(input.url, {
21
21
  console.error(error && error.stack ? error.stack : String(error));
22
22
  process.exit(1);
23
23
  });
24
- `;function al(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,au)}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 au(e,t){return"__proto__"===e||"constructor"===e||"prototype"===e?void 0:t}let ac={launchApp:({value:e,config:t,context:r})=>[nU(e,t,r)],tapOn:({value:e,context:t})=>[function(e,t){if("string"==typeof e)return nD(n1,[n4(nE(e,t))],ar(e));if(nR(e)&&"string"==typeof e.point){nO(e,"tapOn",["point","repeat","delay","optional","label"]);let t=nH(e.point);return"percent"===t.kind?nD(n2,[String(t.x),String(t.y)],at(e)):nD("click",[String(t.x),String(t.y)],at(e))}nR(e)&&nO(e,"tapOn",["id","text","childOf","enabled","index","selected","repeat","delay","optional","label"]);let r=ar(e);return nD(n1,[n9(e,"tapOn",["repeat","delay","optional","label","index","childOf"],t),...function(e,t){if(!nR(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=n9(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(nR(e)&&"string"==typeof e.point){nO(e,"doubleTapOn",["point","delay"]);let t=nB(e.point);return nD("click",[String(t.x),String(t.y)],an(e))}return nR(e)&&nO(e,"doubleTapOn",["id","text","enabled","selected","delay"]),nD("click",[n9(e,"doubleTapOn",["delay"],t)],an(e))}(e,t)],longPressOn:({value:e,context:t})=>[function(e,t){if(nR(e)&&"string"==typeof e.point){nO(e,"longPressOn",["point"]);let t=nB(e.point);return nD("longpress",[String(t.x),String(t.y),"3000"])}return nR(e)&&nO(e,"longPressOn",["id","text","enabled","selected"]),nD("click",[n9(e,"longPressOn",[],t)],{holdMs:3e3})}(e,t)],inputText:({value:e,context:t})=>[nD("type",[nE(function(e){if("string"==typeof e)return e;if(!nR(e))throw new d("INVALID_ARGS","inputText expects a string or map.");if(nO(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})=>[n3(e)],pasteText:({value:e,context:t,name:r})=>[nD("type",[nE(nC(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=nE((l=a,u=s,"string"==typeof l?l:nR(l)?(nO(l,u,["link"]),nC(`${u}.link`,l.link)):nC(u,l)),o),("ios"===o.platform||"android"===o.platform)&&i.appId?nD("open",[nE(nF(i,s),o),c],"ios"===o.platform?{maestro:{prewarmRunnerBeforeOpen:!0}}:void 0):nD("open",[c]))]},assertVisible:({value:e,context:t,name:r})=>[nD(nz,[n9(e,r,[],t),"7000"])],assertNotVisible:({value:e,context:t,name:r})=>[nD(nJ,[n9(e,r,[],t)])],extendedWaitUntil:({value:e,context:t})=>(function(e,t){if(!nR(e))throw new d("INVALID_ARGS","extendedWaitUntil expects a map.");nO(e,"extendedWaitUntil",["visible","notVisible","timeout"]);let r=e.visible??e.notVisible;if(void 0===r)throw nT("Only Maestro extendedWaitUntil.visible/notVisible is supported.");let n=n9(r,"extendedWaitUntil",[],t),a=String(n$(e,3e4));return void 0!==e.notVisible?[nD(nJ,[n,a])]:[nD(nz,[n,a],{maestro:{allowAlreadyPastLoading:!0}})]})(e,t),takeScreenshot:({value:e,context:t,name:r})=>[nD("screenshot",[nE(nC(r,e),t)])],scroll:({value:e})=>[function(e){if(null!=e)throw nT("Maestro scroll options are not supported yet.");return nD("scroll",["down"])}(e)],scrollUntilVisible:({value:e,context:t})=>(function(e,t){if("string"==typeof e)return[nD(nZ,[n4(nE(e,t)),"5000","down"])];if(!nR(e))throw new d("INVALID_ARGS","scrollUntilVisible expects a string or map.");nO(e,"scrollUntilVisible",["element","direction","timeout"]);let r=n9(e.element,"scrollUntilVisible.element",[],t),n="string"==typeof e.direction?n6(e.direction,"scrollUntilVisible.direction"):"down";return[nD(nZ,[r,String(n$(e,5e3)),n])]})(e,t),swipe:({value:e,context:t})=>[function(e,t){var r,n,a;let i;if(!nR(e))throw new d("INVALID_ARGS","swipe expects a map.");nO(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=n8("string"==typeof r.direction?r.direction:"up"),nD(n0,[n9(n,"swipe.from",[],a),i,...n7(r)])):"string"==typeof e.direction?nD(nQ,["direction",n8(e.direction),...n7(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 nT("Only Maestro swipe start/end coordinates are supported.")}(e);var n=t,a=r,i=n5(e.duration);if("absolute"===n.kind&&"absolute"===a.kind)return nD("swipe",[String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);if("percent"===n.kind&&"percent"===a.kind)return nD(nQ,["percent",String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);throw nT("Maestro swipe start/end must both be absolute pixels or both be percentages.")}(e)}(e,t)],hideKeyboard:()=>[nD("keyboard",["dismiss"])],pressKey:({value:e})=>[function(e){let t=nC("pressKey",e).toLowerCase();if("back"===t)return nD("back");if("enter"===t||"return"===t)return nD(nX);if("home"===t)return nD("home");throw nT(`Maestro pressKey "${t}" is not supported yet.`)}(e)],back:()=>[nD("back")],waitForAnimationToEnd:({value:e})=>[nD(nY,[String(n$(e,15e3))])],stopApp:({value:e,config:t,context:r})=>[nG(e,t,r)],runScript:({value:e,context:t})=>{let r;return[nD(nW,[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:nE(e,t),env:{}};if(!nR(e))throw new d("INVALID_ARGS","runScript expects a file path string or map.");return nO(e,"runScript",["file","env"]),{file:nE(nC("runScript.file",e.file),t),env:Object.fromEntries(Object.entries(nP(e.env,"runScript.env")).map(([e,r])=>[e,nE(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(nE(e,r),r).actions;if(!nR(e))throw new d("INVALID_ARGS","runFlow expects a file path string or map.");nO(e,"runFlow",["file","commands","env","when","label"]);let i=function(e,t){var r,n;if(null==e)return{shouldRun:!0};if(!nR(e))throw new d("INVALID_ARGS","runFlow.when expects a map.");return(nO(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 aa(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=nE(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:n9(r.visible,"runFlow.when.visible",[],n)}:{},...void 0!==r.notVisible?{notVisibleSelector:n9(r.notVisible,"runFlow.when.notVisible",[],n)}:{}})}}(e.when,r);if(!i.shouldRun)return[];let o={...r,env:{...r.env,...nP(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 nT("Maestro runFlow.when cannot combine visible and notVisible yet.");let a=r?"visible":"notVisible",i=r??n??"";return[ai("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(nE(e.file,r),r).actions;if(Array.isArray(e.commands))return a(nL(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,af),repeat:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i;if(!nR(e))throw new d("INVALID_ARGS","repeat expects a map.");if(nO(e,"repeat",["times","commands","while"]),void 0!==e.while)throw nT("Maestro repeat.while is not supported yet. Only deterministic repeat.times is supported.");let o=(i=e.times,ao(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=nL(e.commands);return Array.from({length:o}).flatMap(()=>a(s,t,r,n))})(e,t,r,n,af),retry:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i,o;if(!nR(e))throw new d("INVALID_ARGS","retry expects a map.");if(nO(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:ao(i,o,"retry.maxRetries")),l=a(nL(e.commands),t,r,n);return[ai("retry",[String(s)],{kind:"retry",maxRetries:s,actions:l})]})(e,t,r,n,af)},ad={launchApp:(e,t)=>[nU(void 0,e,t)],scroll:()=>[nD("scroll",["down"])],hideKeyboard:()=>[nD("keyboard",["dismiss"])],eraseText:()=>[n3(void 0)],back:()=>[nD("back")],waitForAnimationToEnd:()=>[nD(nY,["15000"])],stopApp:(e,t)=>[nG(void 0,e,t)]};function ap(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=ad[a])?n(i,o):nV(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=ac[l];return c?c({value:u,config:t,context:r,deps:n,name:l}):nV(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 af(e,t,r,n){return e.flatMap((e,a)=>ap(e,t,a+1,r,n))}function am(e,t){let{config:r,commands:n}=aw(ah(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=ap(r,t,n,a,{parseRunFlowFile:ag});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!==nX||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!==n1)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 ah(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 aw(e){if(0===e.length)throw new d("INVALID_ARGS","Maestro flow is empty.");if(Array.isArray(e[0]))return{config:{},commands:nL(e[0])};let t=function(e){if(!nR(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}:{},...nR(e.env)?{env:nP(e.env,"env")}:{},...Array.isArray(e.onFlowStart)?{onFlowStart:nL(e.onFlowStart)}:{},...Array.isArray(e.onFlowComplete)?{onFlowComplete:nL(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:nL(r)}}function ag(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),am(i,{...r,baseDir:a.dirname(n),visitedPaths:o})}let ay=/[*?[\]{}]/;function av(e){return"maestro"===e}let aA=["failed to start daemon","runner did not accept connection","xcodebuild exited early","device is offline","device offline","device unauthorized"];function ab(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&&eW(i)||(n=s.code,a=s.message,o=`${n}
25
- ${a}`.toLowerCase(),aA.some(e=>o.includes(e))))}async function aS(e){let r,n,{filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:d,artifactsDir:p,runReplay:f,cleanupSession:m}=e;L(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),aN(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(()=>{ev(s)});try{return n="number"==typeof l?await Promise.race([v,new Promise(e=>{r=setTimeout(()=>{w=!0,em(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,aN(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 aI(v)||((A=n)&&!A.ok&&(A.error.details={...A.error.details??{},reason:"timeout_cleanup_pending",timeoutCleanupPending:!0}),e8({level:"warn",phase:"test_timeout_cleanup_race",data:{session:o,requestId:s,graceMs:2e3}}),a_({replayPromise:v,cleanupSession:m,sessionName:o,requestId:s})));let e=Date.now();try{aN(y,{type:"replay_test_cleanup_start",ts:new Date().toISOString(),session:o}),await m(o),aN(y,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!0,durationMs:Date.now()-e})}catch(r){let t=c(r);aN(y,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!1,durationMs:Date.now()-e,errorCode:t.code}),e8({level:"warn",phase:"test_cleanup_failed",data:{session:o,error:t.message}})}}}async function aI(e){return await Promise.race([e.then(()=>!0),l(2e3).then(()=>!1)])}async function a_(e){let{replayPromise:t,cleanupSession:r,sessionName:n,requestId:a}=e;try{await t}finally{try{await r(n)}catch(e){e8({level:"warn",phase:"test_late_cleanup_failed",data:{session:n,requestId:a,error:c(e).message}})}}}function aN(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
26
- `)}async function aM(e){let{req:r,sessionName:n,runReplay:i,cleanupSession:o}=e;if((r.positionals?.length??0)===0)return P("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(av(r)?[".ad",".yaml",".yml"]:[".ad"])),h=c??process.cwd(),w=[...new Set(u.flatMap(e=>(function(e,r,n){var i,o;let s=ei.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,!ay.test(i)&&(o=s,!ay.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=nN(r),c=(n=r,i=e,o=f,av(o)&&".ad"!==a.extname(i)?function(e){let{config:t}=aw(ah(e));return t.name}(n):void 0);if(!p){g.push({kind:"run",path:e,title:c,metadata:u});continue}if(!u.platform){av(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=ei.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){e$({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 ax({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||ab(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 P(e.code,e.message)}}async function ax(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 eu(`${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 aS({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:_}),ab(A)||e>=f))break;e$({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 e$({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 e$({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 ak={maestro:{parse:function(e,t={}){var r;let n;return am(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 aD(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=e9(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 aO(e){let{action:t,sessionName:r,logPath:n,sessionStore:a}=e;if(!(M(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),M(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&&aR(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}=tt(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=aD(e.positionals??[]);r&&t.push(r)}return V(t).filter(e=>e.trim().length>0)})(t).map(e=>tr(e)).filter(e=>null!==e);if(0===o.length)return null;let s=M(t.command)||"fill"===t.command,l=M(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await aL(i,t,n,s,a);for(let e of o){let r=ta(u.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let n=ti(r.node,i.device.platform,{action:"fill"===t.command?"fill":M(t.command)?"click":"get"}).join(" || ");if(M(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&&aR(t)?t:void 0}(e.positionals??[]);return r?[t,r]:[t]}(t,n):[n]};if("fill"===t.command){let e=b(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}=tt(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}=aD(t.positionals??[]),r=[n];return e&&r.push(e),{...t,positionals:r}}}return null}function aR(e){return void 0!==e&&""!==e.trim()&&Number.isFinite(Number(e))}async function aL(e,t,r,n,a){let i=er(await m(e.device,"snapshot",[],t.flags?.out,{...en(r,{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n},e.appBundleId,e.trace?.outPath)}),{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n});return B(e,i),a.set(e.name,e),i}let aP=new WeakMap,a$=new WeakMap;function aF(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}async function aC(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(aE(a.data)))&&aP.set(t,r)),a}function aE(e){return Array.isArray(e?.nodes)?e:void 0}function aV(e){return e.flags?.platform==="ios"}function aT(e,t){e8({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 aG(e,t,r,n){let a=aB(e,t,r,{allowLeadingCompositeLabelMatch:!1}),i=aq({nodes:e.nodes,matches:a,platform:r}),o=az(e.nodes,i.matches,void 0,aK(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 aq(e){let t=e.matches.filter(t=>tm({predicate:"visible",node:t,nodes:e.nodes,platform:e.platform}).pass),r=function(e,t,r){let n=tg(e);if(!n.detected||!n.redBox)return{matches:t,blockedByReactNativeOverlay:!1};let a=tw(n),i=a.filter(t=>tm({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 aj(e){return e?.platform==="android"?"android":"ios"}function aK(e){let t=tn(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 aB(e,t,r,n={}){for(let a of tn(t).selectors){let t=e.nodes.filter(e=>(function(e,t,r,n){return!!ts(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?ts(e,{raw:t.key,terms:[t]},r):aH((i=e,"id"===(o=t.key)?i.identifier:"label"===o?i.label:"value"===o?i.value:e4(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=tu(a),o=tu(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 aW(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 az(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=to(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=aW(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===a5(e.node,r));if(a.length>=2){let t=aX(e,a,r,n);if(t)return t}let i=t.filter(e=>1===a5(e.node,r));return a.length>0||i.length<2?null:aX(e,i,r,n)}(o,s,l,c)??aJ(o,s,l,c):aJ(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=tl(n.node.type??""))||"other"===b||"scrollview"===b||"scroll-area"===b)&&!(n.rect.width<120)&&!(n.rect.height<32)&&!(n.rect.height>80)&&1>=a5(n.node,a)))return null;let D=(i=e,o=t,s=r,l=to(e),i.filter(e=>{var t,r,n;let a;return e.index!==o.node.index&&!!e.rect&&te(i,e,o.node,l)&&(t=e,r=o.rect,n=s,!("button"!==(a=tl(t.type??""))&&"cell"!==a&&"other"!==a||1>=a5(t,n))&&!(t.rect.width<16)&&!(t.rect.height<16)&&!!a2(r,t.rect)&&a0(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"===tl(h.node.type??"")&&1>=a5(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,(a1(_.node)?null:e7(I,_.node,N,e=>{if(!a1(e))return null;let t=aW(I,e,N);return t&&function(e,t,r){var n,a;if(!a2(t,e)||(n=e,!((a=t).height<32||a.height>80||n.height<.75*a.height||.75>a0(n,a))&&!(a.width<240)&&a.width>=3*n.width))return!1;let i=aZ(t),o=aZ(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 aJ(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===a5(e.node,r));if(l.length<2)return t;let u=to(e),c=l.map(t=>({candidate:t,container:aY(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&&a3(t.container.rect,e.container.rect)>=.6)});if(d.length<2)return t;let p=(o=Math.max(...i=(a=d).map(e=>aZ(e.container.rect))),(s=Math.min(...i))<=0||o<1.2*s?[]:a.filter(e=>aZ(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=aY(e,r.node,n),i=a&&a2(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>a3(e.rect,r.rect)?1/0:Math.abs(e.index-r.index);if(a3(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=a5(e.node,r)-a5(t.node,r);if(0!==n)return n}let n=aQ(e.node)-aQ(t.node);if(0!==n)return n;let a=Number(e.inheritedRect)-Number(t.inheritedRect);if(0!==a)return a;let i=r&&aQ(e.node)===aQ(t.node)?aZ(t.rect)-aZ(e.rect):aZ(e.rect)-aZ(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 aX(e,t,r,n){let a=to(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||!a2(i.rect,o.rect)||aZ(i.rect)<2*aZ(o.rect))&&te(n,o.node,i.node,s)})});return aJ(e,i,r,n)}function aY(e,t,r){return e7(e,t,r,e=>{let t;return!e.rect||"scrollview"!==(t=tl(e.type??""))&&"scroll-area"!==t&&"list"!==t||e.rect.width<240||e.rect.height<320?null:e})}function aZ(e){return e.width*e.height}function aQ(e){return aU.get(tl(e.type??""))??3}function a0(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 a1(e){let t=tl(e.type??"");return!0===e.hittable||"button"===t||"link"===t||"cell"===t||"textfield"===t||"searchfield"===t||"switch"===t||"slider"===t}function a2(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 a3(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(aZ(e),aZ(t)))}function a5(e,t){let r=[e.label,e4(e),e.identifier,e.value].filter(e=>!!e);return r.some(e=>e===t)?0:r.some(e=>tu(e)===tu(t))?1:r.some(e=>aH(e,t))?2:3}async function a6(e){var t,r,n;let a=ie(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:aK(r));return i?await a8(e,a,i):await a4(e,a)}async function a8(e,t,r){let n=Date.now(),a=await a9(e,t,r);return a.ok?io({ok:!0,data:{selector:t.selector,nativeWait:!0,query:r,response:a.data}},t.selector,n):a}async function a9(e,t,r){return await e.invoke({...e.baseReq,command:"wait",positionals:[r,String(t.timeoutMs)]})}async function a4(e,r){let n,i,o=Date.now(),s=r.timeoutMs+1e3,l=!1;for(;;){let t=Date.now(),a=await it(e,r.selector,"assertVisible",{rawFallback:!0});if(a.visible)return io(a.response,r.selector,o);n=a.response,i=a.snapshot??i;let u=function(e,t,r,n){var a,i,o,s,l,u;return a7(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=ia(aK(e));if(!ii(r))return!1;let n=t.nodes.flatMap(e=>[e.label,e.value,e.identifier]).filter(e=>!!e?.trim()).map(e=>ia(e));return!n.some(e=>e.includes("something went wrong"))&&n.some(e=>e!==r&&!ii(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,r,a,o);if("return"===u.kind)return u.response;let c=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:t,capturedAfterDeadline:l,startedAt:o,deadlineMs:s});if("capture-again"===c){l=!0;continue}if("finish"===c)break;await tA(250)}return function(e,r,n){var i;if(e.ok||!r)return e;let o="string"==typeof n.flags?.artifactsDir?n.flags.artifactsDir:void 0;if(!o)return e;let s=function(e,r){try{t.mkdirSync(r,{recursive:!0});let n=a.join(r,"failure-snapshot.json"),i=a.join(r,"failure-snapshot.txt");t.writeFileSync(n,`${JSON.stringify(e,null,2)}
28
- `);let o=tv(e.nodes,{summarizeTextSurfaces:!0}).map(e=>e.text);return t.writeFileSync(i,`${o.join("\n")}
29
- `),[n,i]}catch{return[]}}(r,o);return 0===s.length?e:{ok:!1,error:{...e.error,details:{...e.error.details??{},artifactPaths:[...new Set([...Array.isArray(i=e.error.details?.artifactPaths)?i.filter(e=>"string"==typeof e):[],...s])]}}}}(n??aF("COMMAND_FAILED",`Expected visible but did not match: ${r.selector}`,{selector:r.selector,timeoutMs:r.timeoutMs}),i,e.baseReq)}function a7(e){return!e.ok&&"COMMAND_FAILED"===e.error.code&&e.error.message.includes("React Native overlay")}function ie(e,t){let[r,n=String(t.defaultTimeoutMs)]=e;if(!r)return{ok:!1,response:aF("INVALID_ARGS",`${t.command} requires a selector.`)};let a=Number(n);return!Number.isFinite(a)||a<0?{ok:!1,response:aF("INVALID_ARGS",`${t.command} timeout must be a non-negative number.`)}:{ok:!0,selector:r,timeoutMs:a}}async function it(e,t,r,n={}){let a=await aC(e),i=ir(e,t,r,a);if(i.visible||i.infrastructureFailure||!n.rawFallback||!aV(e.baseReq)||a7(i.response))return i;aT(r,t);let o=await aC({...e,mode:"raw"});return ir(e,t,r,o)}function ir(e,t,r,n){var a;if(!n.ok)return{visible:!1,response:n,infrastructureFailure:!0};let i=aE(n.data);if(!i)return{visible:!1,response:aF("COMMAND_FAILED",`Unable to read snapshot data for ${r}.`),infrastructureFailure:!0};let o=aG(i,t,aj(e.baseReq.flags),H(i));return o.ok?(a=e.scope,a&&a$.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:aF("COMMAND_FAILED",o.message,{selector:t}),infrastructureFailure:!1,snapshot:i}}function ia(e){return e?.trim().toLowerCase().replace(/\u2026/g,"...")??""}function ii(e){return"loading"===e||"loading..."===e}function io(e,t,r){return e.ok?{ok:!0,data:{selector:t,...e.data,waitedMs:Date.now()-r}}:e}async function is(e){let t,r=ie(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 it(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 tA(250)}return a>0?{ok:!0,data:{pass:!0,selector:r.selector,stableSamples:a,waitedMs:Date.now()-n,timeoutMs:r.timeoutMs}}:aF("COMMAND_FAILED",`Expected not visible but matched: ${r.selector}`,{selector:r.selector,timeoutMs:r.timeoutMs,lastResponse:t})}async function il(e){let t,r,n=Number(e.positionals[0]??15e3);if(!Number.isFinite(n)||n<0)return aF("INVALID_ARGS","waitForAnimationToEnd timeout must be a number.");let a=Date.now();for(;Date.now()-a<n;){let a=await aC(e),i=function(e,t,r){let n=function(e){if(!e.ok)return null;let t=aE(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 tA(250)}return r?.ok===!1?r:{ok:!0,data:{stable:!1,timeoutMs:n}}}let iu=.35,ic=120,id=360,ip=8,im={minWidth:120,minHeight:70,maxHeight:200,width:168,height:48};function ih(e,t){return Math.round(Math.min(id,Math.max(ic,"number"==typeof e?e*iu:0,1.5*t)))}async function iw(e){var t,r,n;let[a,i="5000",o="down"]=e.positionals;if(!a)return aF("INVALID_ARGS","scrollUntilVisible requires a selector.");let s=Number(i);if(!Number.isFinite(s)||s<=0)return aF("INVALID_ARGS","scrollUntilVisible timeout must be a positive number.");let l=aK(a),u=Math.max(1,Math.ceil(s/500)),c=null;for(let t=0;t<u;t+=1){let r=await iN(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}`}}:aF("COMMAND_FAILED",`scrollUntilVisible timed out after ${n}ms for selector: ${r}`)}async function ig(e){let[t,r]=e.positionals,n=Number(t),a=Number(r);if(!Number.isFinite(n)||!Number.isFinite(a))return aF("INVALID_ARGS","tapOn percentage point requires numeric x/y values.");let i=await aC(e);if(!i.ok)return i;let o=aE(i.data);if(!o)return aF("COMMAND_FAILED","Unable to read snapshot data for Maestro percentage point tap.");let s=H(o);if(!s)return aF("COMMAND_FAILED","Unable to resolve screen size for Maestro percentage point tap.");let l=tc(s,n,a);return await e.invoke({...e.baseReq,command:"click",positionals:[String(l.x),String(l.y)],flags:{...e.baseReq.flags,postGestureStabilization:!0}})}async function iy(e){let t=await iv(e);if(t)return t;let r=await iI(e);return r.ok?await iS(e,r,r.durationMs):r.response}async function iv(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 iA(e){var t,r,n,a;let i,[o,s]=e.positionals;if(!o)return aF("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:aF("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 iM(e,o,l.value??{});if(!t.retry)return t.response;i=t.response,await tA(250)}return r=e,n=o,a=i,r.baseReq.flags?.maestro?.optional===!0?{ok:!0,data:{skipped:!0,optional:!0,selector:n}}:a??aF("COMMAND_FAILED",`tapOn timed out for selector: ${n}`)}async function ib(e){let[t,r="up",n]=e.positionals;if(!t)return aF("INVALID_ARGS","swipe.label requires a label selector.");let a=await iO(e,t,{},"swipe.label",{promoteTapTarget:!1});if(!a.ok)return a.response;let i=function(e,t){let r=th(e.rect),n=e.frame,a=ih(n?.referenceWidth,e.rect.width),i=ih(n?.referenceHeight,e.rect.height),o=ip,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 iS(e,i,n):aF("INVALID_ARGS",i.message)}async function iS(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 iI(e){var t;let r=((t=e.scope)?aP.get(t):void 0)??await i_(e);if(!r)return{ok:!1,response:aF("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:aF("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:ty({x:(s=tp({direction:a,amount:.6,referenceWidth:i.referenceWidth,referenceHeight:i.referenceHeight})).x1,y:s.y1},i,8),end:ty({x:s.x2,y:s.y2},i,8),durationMs:o};default:return{ok:!1,response:aF("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:aF("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:tc(t,m,y.startY,{marginPx:1}),end:tc(t,w,y.endY,{marginPx:1}),durationMs:p}}(a,r,aj(e.baseReq.flags)):{ok:!1,response:aF("INVALID_ARGS","Maestro screen swipe requires direction or percent.")}}async function i_(e){let t=await aC(e);if(t.ok)return H(aE(t.data))}async function iN(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 iM(e,t,r){let n=aK(t),a=await ix(e,t,r);return a.response.ok?{retry:!1,response:a.response}:a.targetResolved&&n?await iD(e,n):{retry:!0,response:a.response}}async function ix(e,t,r){let n=await iO(e,t,r,"tapOn",{promoteTapTarget:!0});return n.ok?await ik(e,t,n.target):{response:n.response,targetResolved:!1}}async function ik(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>=im.minWidth&&o.height>=im.minHeight&&o.height<=im.maxHeight&&("cell"===(l=tl(n.type??""))||"other"===l||"scrollview"===(s=l)||"scroll-area"===s))?{x:tf(e.rect.x,Math.min(e.rect.width,im.width)),y:tf(e.rect.y,Math.min(e.rect.height,im.height))}:th(e.rect)}(r,null!==aK(t),{allowLargeContainerBias:"raw"===r.snapshotMode});e8({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},postGestureStabilization:!0}});return i.ok&&(n=e.scope)&&a$.delete(n),{response:i,targetResolved:!0}}async function iD(e,t){let r=await e.invoke({...e.baseReq,command:"find",positionals:[t,"click"],flags:{...e.baseReq.flags,findFirst:!0,interactionOutcome:{retryOnNoChange:!0},postGestureStabilization:!0}});return(e8({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 iO(e,t,r,n,a){let i=await aC({...e,mode:"interactive"}),o=iR(e,t,r,n,a,i,"interactive");if(o.ok||!i.ok||!aV(e.baseReq))return o;aT(n,t);let s=await aC({...e,mode:"raw"});return iR(e,t,r,n,a,s,"raw")}function iR(e,t,r,n,a,i,o){if(!i.ok)return{ok:!1,response:i};let s=aE(i.data);if(!s)return{ok:!1,response:aF("COMMAND_FAILED",`Unable to read snapshot data for ${n}.`)};let l=H(s),u=aj(e.baseReq.flags),c=function(e,t,r,n){var a;let i=(a=e.scope)?a$.get(a):void 0;if(!i)return;let o=aG(t,i.selector,r,n);if(o.ok)return e8({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=aB(e,t,n);if(r.childOf){let t=aB(e,r.childOf,n);if(0===t.length)return{ok:!1,message:`Maestro childOf parent did not match: ${r.childOf}`};let a=to(e.nodes);o=o.filter(r=>t.some(t=>te(e.nodes,r,t,a)))}let s=aq({nodes:e.nodes,matches:o,platform:n}),l=az(e.nodes,s.matches,r.index,aK(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=aK(t);if(e){let t=function(e,t,r,n,a={}){let i=function(e,t){let r=tu(t);if(!r)return[];let n=[],a=[];for(let t of e.nodes){let e=[t.label,e4(t),t.identifier,t.value].filter(e=>!!e).map(e=>tu(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=aq({nodes:e.nodes,matches:i,platform:r}),s=az(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:aF("ELEMENT_NOT_FOUND",d.message,{selector:t,options:r,command:n})}}async function iL(e){switch(e.command){case nz:return await a6(e);case nJ:return await is(e);case nX:return await iP(e);case nY:return await il(e);case nZ:return await iw(e);case nQ:return await iy(e);case n0:return await ib(e);case n1:return await iA(e);case n2:return await ig(e);case nW:return function(e){let[r]=e.positionals;if(!r)return aF("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:al,http:{post:(e,t)=>(function(e,t,r){let n=e6(process.execPath,["-e",as],{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 aF(e.code,e.message,e.details)}}(e);default:return}}async function iP(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 i$(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 iF(e){let t;for(let r=0;r<=e.maxRetries;r+=1){let n=await i$({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 iC(e){let t=await iE(e,e.control);return t.ok?t.matched?await iG(e):{ok:!0,data:{skipped:!0,condition:e.control.mode,selector:e.control.selector}}:t.response}async function iE(e,t){if("visible"===t.mode)return await iV(e,t);let r=await iT(e,t.selector);return r.ok?{ok:!0,matched:!r.matched}:{ok:!1,response:r.response}}async function iV(e,t){let r=Date.now();for(;;){let n=await iT(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 tA(250)}}async function iT(e,t){let r=await aC(e);if(!r.ok)return{ok:!1,response:r};let n=iU(e,t,r);if(!n.ok||n.matched||!aV(e.baseReq))return n;aT("runFlow.when",t);let a=await aC({...e,mode:"raw"});return a.ok?iU(e,t,a):{ok:!1,response:a}}function iU(e,t,r){let n=aE(r.data);return n?{ok:!0,matched:aG(n,t,aj(e.baseReq.flags),H(n)).ok}:{ok:!1,response:aF("COMMAND_FAILED","Unable to read snapshot data for runFlow.when.")}}async function iG(e){let t=await i$({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 iq(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=>nb(e,i,t)),flags:nS(a.flags,i,t)??{},runtime:nS(a.runtime,i,t),replayControl:function(e,t,r){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:nb(e.selector,t,r)}}return e}(a.replayControl,i,t)}),p=Date.now();iB(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 ij({req:r,sessionName:n,resolved:d,scope:i,line:s,step:l,invoke:c,invokeReplayAction:e=>iq({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 iB(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 ij(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,e0(t,{...a.flags??{}})),d={token:r.token,session:n,flags:c,runtime:a.runtime,meta:r.meta},p=await iK({control:a.replayControl,baseReq:d,line:o,step:s,invoke:l,invokeReplayAction:u})??await iL({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 iK(e){let{control:t,baseReq:r,line:n,step:a,invoke:i,invokeReplayAction:o}=e;if(t){switch(t.kind){case"retry":return await iF({actions:t.actions,maxRetries:t.maxRetries,line:n,step:a,invokeReplayAction:o});case"maestroRunFlowWhen":return await iC({baseReq:r,control:t,line:n,step:a,invoke:i,invokeReplayAction:o})}return t}}function iB(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
30
- `)}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 P("INVALID_ARGS","replay requires a path");let p="",f=new Set;try{var m,h;p=ei.expandHome(c,r.meta?.cwd);let e=t.readFileSync(p,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return P("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=ak[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,{...ng(nA(n?.replayShellEnv)),...ny(nv(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(nM(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=C(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a.runtime=e.runtime,a}if("runtime"===r){let e=K(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a}if(k(r)){let e=eS(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 nk(i)&&nk(o)&&e.positionals.length>=2?a.positionals=[i,o]:a.positionals=[e.positionals.join(" ")],a}if("fill"===r){let e=eS(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=eS(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=e5({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:nN(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 P("INVALID_ARGS",w.updateUnsupportedMessage);if(r.flags?.replayUpdate===!0&&g.env&&Object.keys(g.env).length>0)return P("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(iX(t.flags)||iX(t.runtime))return!0}return!1}(v))return P("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let b=function(e){let t={};if(e.builtins)for(let[r,n]of Object.entries(e.builtins))t[r]=n;for(let r of[e.fileEnv,e.shellEnv,e.cliEnv])if(r)for(let[e,n]of Object.entries(r)){if(nh(e))throw nw(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:ng(nA(r.flags?.replayShellEnv)),cliEnv:ny(nv(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 iq({req:y,sessionName:n,action:t,scope:b,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l});if(r.ok){iz(r).forEach(e=>f.add(e));continue}if(iz(r).forEach(e=>f.add(e)),!I)return iW(r,t,e,p,[...f]);let a=await aO({action:t,sessionName:n,logPath:i,sessionStore:o});if(!a)return iW(r,t,e,p,[...f]);if(v[e]=a,!(r=await iq({req:y,sessionName:n,action:a,scope:b,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l})).ok)return iz(r).forEach(e=>f.add(e)),iW(r,a,e,p,[...f]);iz(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=${eo(n.device.name)}${e} theme=unknown`)}for(let e of r){var i;a.push((i=e,S(i,{runtimeIncludeAllPositionals:!0})))}let o=`${a.join("\n")}
31
- `,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 P(e.code,e.message,f.size>0?{artifactPaths:[...f]}:void 0)}}function iW(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} (${es(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 iz(e){if(!e.ok){let t=e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e&&iJ(e)))]:[]}if(!e.data)return[];let t=[];if("string"==typeof e.data.path&&t.push(e.data.path),"string"==typeof e.data.outPath&&t.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let r of e.data.artifacts){if(!r||"object"!=typeof r)continue;let e="string"==typeof r.localPath?r.localPath:void 0,n="string"==typeof r.path?r.path:void 0;e?t.push(e):n&&t.push(n)}return[...new Set(t.filter(e=>iJ(e)))]}function iJ(e){try{return t.statSync(e).isFile()}catch{return!1}}function iX(e){return"string"==typeof e?e.includes("${"):Array.isArray(e)?e.some(iX):!!e&&"object"==typeof e&&Object.values(e).some(iX)}async function iY(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 aM({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&&iz(t).forEach(e=>c.add(e)),t}})},cleanupSession:async e=>{a.get(e)&&await z({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:n,sessionStore:a})}}):null}async function iZ(e){var t,r,n,a,i,o,s,l;let u,c,{req:d,sessionName:p,logPath:f,sessionStore:m}=e,h=d.positionals?.[0]??"";if("ios-runner"!==h)return P("INVALID_ARGS","prepare requires a subcommand: ios-runner");let w=m.get(p),g=d.flags??{},v=N(tS.prepare,w,g);if(v)return v;let A=await y({session:w,flags:g,ensureReady:!0});if(!ek(A.platform))return P("UNSUPPORTED_OPERATION","prepare ios-runner is only supported on Apple runner platforms");let b=Date.now(),S=await X(A,(t=d,r=w,n=f,c=(a=t,"number"==typeof(u=a.flags?.timeoutMs)&&Number.isFinite(u)&&u>0?u:3e5),{verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,cleanStaleBundles:!0,startupTimeoutMs:function(e){if("number"==typeof e&&Number.isFinite(e)&&!(e<=0))return Math.max(45e3,Math.floor(e))}(t.flags?.timeoutMs),requestId:t.meta?.requestId,buildTimeoutMs:c,healthTimeoutMs:Math.min(c,9e4)}));return{ok:!0,data:(i=h,o=A,s=Math.max(0,Date.now()-b),l=S,{action:i,platform:o.platform,deviceId:o.id,deviceName:o.name,kind:o.kind,durationMs:s,...l,message:`Prepared Apple runner: ${o.name}`})}}async function iQ(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=N(i,u,c);if(d)return d;let p=await y({session:u,flags:c,ensureReady:!0});if(!ex(i,p))return P("UNSUPPORTED_OPERATION",`${i} is not supported on this device`);let f=await m(p,i,o,t.flags?.out,{...en(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 i0(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,i=a.get(r),o=t.flags??{},s=N(tS.clipboard,i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return P("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await y({session:i,flags:o,ensureReady:!0});if(!ex(tS.clipboard,u))return P("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let c=await m(u,tS.clipboard,t.positionals??[],t.flags?.out,{...en(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 i1(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i,invokeReplayAction:o,androidAdbExecutor:s}=e;if("inventory"===A(t.command))return await rf({req:t,sessionName:r,sessionStore:a});if("runtime"===t.command)return await tC({req:t,sessionName:r,sessionStore:a});if("state"===A(t.command))return await ry({req:t,sessionName:r,sessionStore:a});if(t.command===tS.clipboard)return await i0({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===tS.keyboard){let e=a.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i&&"enter"!==i&&"return"!==i||"ios"!==eO((t.flags??{}).platform)?await iQ({req:t,sessionName:r,logPath:n,sessionStore:a,command:tS.keyboard,positionals:t.positionals??[]}):P("SESSION_NOT_FOUND","iOS keyboard action requires an active session so the target app stays foregrounded. Run open first.")}if("observability"===A(t.command))return await na({req:t,sessionName:r,sessionStore:a,androidAdbExecutor:s});if(t.command===tS.prepare)return await iZ({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===tS.install||t.command===tS.reinstall)return await rd({req:t,command:t.command,sessionName:r,sessionStore:a,deployOps:t.command===tS.install?rc:ru});if(t.command===tb.installSource)return await tk({req:t,sessionName:r,sessionStore:a});if(t.command===tb.releaseMaterializedPaths)return await tD({req:t});if(t.command===tS.push){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await iQ({req:t,sessionName:r,logPath:n,sessionStore:a,command:tS.push,positionals:[i,"file"===(e=ep(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>ei.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):P("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return t.command===tS.triggerAppEvent?await iQ({req:t,sessionName:r,logPath:n,sessionStore:a,command:tS.triggerAppEvent,positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,n=r?await t4(e.device,r,e.appBundleId,t8)??e.appBundleId:e.appBundleId;return{...e,appBundleId:n}}}):t.command===tS.open?await rl({req:t,sessionName:r,logPath:n,sessionStore:a}):"replay"===A(t.command)?await iY({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o??i}):t.command===tS.batch?await rp(t,r,i):t.command===tS.close?await z({req:t,sessionName:r,logPath:n,sessionStore:a}):null}export{t_ as session_namespaceObject};
24
+ `;function a_(e){if("string"!=typeof e)throw new c("COMMAND_FAILED",`Maestro runScript json() expected a string body, received ${typeof e}.`);if(0===e.trim().length)throw new c("COMMAND_FAILED","Maestro runScript json() received an empty body. Check the preceding http response status and setup server output.");try{return JSON.parse(e,aN)}catch(t){throw new c("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 aN(e,t){return"__proto__"===e||"constructor"===e||"prototype"===e?void 0:t}let aM={launchApp:({value:e,config:t,context:r})=>[n2(e,t,r)],tapOn:({value:e,context:t})=>[function(e,t){if("string"==typeof e)return nB(as,[am(nQ(e,t))],ay(e));if(nW(e)&&"string"==typeof e.point){nH(e,"tapOn",["point","repeat","delay","optional","label"]);let t=n4(e.point);return"percent"===t.kind?nB(al,[String(t.x),String(t.y)],aw(e)):nB("click",[String(t.x),String(t.y)],aw(e))}nW(e)&&nH(e,"tapOn",["id","text","childOf","enabled","index","selected","repeat","delay","optional","label"]);let r=ay(e);return nB(as,[af(e,"tapOn",["repeat","delay","optional","label","index","childOf"],t),...function(e,t){if(!nW(e))return[];let r={};if(void 0!==e.index){if("number"!=typeof e.index||!Number.isInteger(e.index)||e.index<0)throw new c("INVALID_ARGS","tapOn.index must be a non-negative integer.");r.index=e.index}return void 0!==e.childOf&&(r.childOf=af(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(nW(e)&&"string"==typeof e.point){nH(e,"doubleTapOn",["point","delay"]);let t=n9(e.point);return nB("click",[String(t.x),String(t.y)],av(e))}return nW(e)&&nH(e,"doubleTapOn",["id","text","enabled","selected","delay"]),nB("click",[af(e,"doubleTapOn",["delay"],t)],av(e))}(e,t)],longPressOn:({value:e,context:t})=>[function(e,t){if(nW(e)&&"string"==typeof e.point){nH(e,"longPressOn",["point"]);let t=n9(e.point);return nB("longpress",[String(t.x),String(t.y),"3000"])}return nW(e)&&nH(e,"longPressOn",["id","text","enabled","selected"]),nB("click",[af(e,"longPressOn",[],t)],{holdMs:3e3})}(e,t)],inputText:({value:e,context:t})=>[nB("type",[nQ(function(e){if("string"==typeof e)return e;if(!nW(e))throw new c("INVALID_ARGS","inputText expects a string or map.");if(nH(e,"inputText",["text","label"]),"string"!=typeof e.text)throw new c("INVALID_ARGS","inputText map requires a string text field.");return e.text}(e),t)])],eraseText:({value:e})=>[au(e)],pasteText:({value:e,context:t,name:r})=>[nB("type",[nQ(nZ(r,e),t)])],openLink:({value:e,config:t,context:r,name:n})=>{var a,i,o,s,l,u;let d;return[(a=e,i=t,o=r,s=n,d=nQ((l=a,u=s,"string"==typeof l?l:nW(l)?(nH(l,u,["link"]),nZ(`${u}.link`,l.link)):nZ(u,l)),o),("ios"===o.platform||"android"===o.platform)&&i.appId?nB("open",[nQ(nY(i,s),o),d],"ios"===o.platform?{maestro:{prewarmRunnerBeforeOpen:!0}}:void 0):nB("open",[d]))]},assertVisible:({value:e,context:t,name:r})=>[nB(ae,[af(e,r,[],t),"17000"])],assertNotVisible:({value:e,context:t,name:r})=>[nB(at,[af(e,r,[],t)])],extendedWaitUntil:({value:e,context:t})=>(function(e,t){if(!nW(e))throw new c("INVALID_ARGS","extendedWaitUntil expects a map.");nH(e,"extendedWaitUntil",["visible","notVisible","timeout"]);let r=e.visible??e.notVisible;if(void 0===r)throw n1("Only Maestro extendedWaitUntil.visible/notVisible is supported.");let n=af(r,"extendedWaitUntil",[],t),a=String(nX(e,17e3));return void 0!==e.notVisible?[nB(at,[n,a])]:[nB(ae,[n,a],{maestro:{allowAlreadyPastLoading:!0}})]})(e,t),takeScreenshot:({value:e,context:t,name:r})=>[nB("screenshot",[nQ(nZ(r,e),t)])],scroll:({value:e})=>[function(e){if(null!=e)throw n1("Maestro scroll options are not supported yet.");return nB("scroll",["down"])}(e)],scrollUntilVisible:({value:e,context:t})=>(function(e,t){if("string"==typeof e)return[nB(aa,[am(nQ(e,t)),"5000","down"])];if(!nW(e))throw new c("INVALID_ARGS","scrollUntilVisible expects a string or map.");nH(e,"scrollUntilVisible",["element","direction","timeout"]);let r=af(e.element,"scrollUntilVisible.element",[],t),n="string"==typeof e.direction?ac(e.direction,"scrollUntilVisible.direction"):"down";return[nB(aa,[r,String(nX(e,5e3)),n])]})(e,t),swipe:({value:e,context:t})=>[function(e,t){var r,n,a;let i;if(!nW(e))throw new c("INVALID_ARGS","swipe expects a map.");nH(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=ap("string"==typeof r.direction?r.direction:"up"),nB(ao,[af(n,"swipe.from",[],a),i,...ah(r)])):"string"==typeof e.direction?nB(ai,["direction",ap(e.direction),...ah(e)]):function(e){let{start:t,end:r}=function(e){if("string"==typeof e.start&&"string"==typeof e.end)return{start:n4(e.start),end:n4(e.end)};throw n1("Only Maestro swipe start/end coordinates are supported.")}(e);var n=t,a=r,i=ad(e.duration);if("absolute"===n.kind&&"absolute"===a.kind)return nB("swipe",[String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);if("percent"===n.kind&&"percent"===a.kind)return nB(ai,["percent",String(n.x),String(n.y),String(a.x),String(a.y),...i?[i]:[]]);throw n1("Maestro swipe start/end must both be absolute pixels or both be percentages.")}(e)}(e,t)],hideKeyboard:()=>[nB("keyboard",["dismiss"])],pressKey:({value:e})=>[function(e){let t=nZ("pressKey",e).toLowerCase();if("back"===t)return nB("back");if("enter"===t||"return"===t)return nB(ar);if("home"===t)return nB("home");throw n1(`Maestro pressKey "${t}" is not supported yet.`)}(e)],back:()=>[nB("back")],waitForAnimationToEnd:({value:e})=>[nB(an,[String(nX(e,15e3))])],stopApp:({value:e,config:t,context:r})=>[n3(e,t,r)],runScript:({value:e,context:t})=>{let r;return[nB(n7,[function(e,t){if(a.isAbsolute(e))return e;if(!t.baseDir)throw new c("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:nQ(e,t),env:{}};if(!nW(e))throw new c("INVALID_ARGS","runScript expects a file path string or map.");return nH(e,"runScript",["file","env"]),{file:nQ(nZ("runScript.file",e.file),t),env:Object.fromEntries(Object.entries(nJ(e.env,"runScript.env")).map(([e,r])=>[e,nQ(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(nQ(e,r),r).actions;if(!nW(e))throw new c("INVALID_ARGS","runFlow expects a file path string or map.");nH(e,"runFlow",["file","commands","env","when","label"]);let i=function(e,t){var r,n;if(null==e)return{shouldRun:!0};if(!nW(e))throw new c("INVALID_ARGS","runFlow.when expects a map.");return(nH(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 c("INVALID_ARGS","runFlow.when.true expects a boolean or expression string.");return new aA(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 c("INVALID_ARGS",`Unsupported runFlow.when.true expression near "${i.slice(0,24)}".`)}return t}((r=nQ(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 c("INVALID_ARGS",`${t} expects Android, iOS, or Web.`);let r=e.trim().toLowerCase();if("android"===r||"ios"===r||"web"===r)return r;throw new c("INVALID_ARGS",`${t} expects Android, iOS, or Web.`)}(e.platform,"runFlow.when.platform");if(!t.platform)throw new c("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:af(r.visible,"runFlow.when.visible",[],n)}:{},...void 0!==r.notVisible?{notVisibleSelector:af(r.notVisible,"runFlow.when.notVisible",[],n)}:{}})}}(e.when,r);if(!i.shouldRun)return[];let o={...r,env:{...r.env,...nJ(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 n1("Maestro runFlow.when cannot combine visible and notVisible yet.");let a=r?"visible":"notVisible",i=r??n??"";return[ab("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(nQ(e.file,r),r).actions;if(Array.isArray(e.commands))return a(nz(e.commands),t,r,n);throw new c("INVALID_ARGS","runFlow map requires either file or commands.")}(e,t,o,n,a),i)})(e,t,r,n,aD),repeat:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i;if(!nW(e))throw new c("INVALID_ARGS","repeat expects a map.");if(nH(e,"repeat",["times","commands","while"]),void 0!==e.while)throw n1("Maestro repeat.while is not supported yet. Only deterministic repeat.times is supported.");let o=(i=e.times,aS(i,r,"repeat.times"));if(!Array.isArray(e.commands))throw new c("INVALID_ARGS","repeat requires a commands list.");if(o>1e3)throw new c("INVALID_ARGS","repeat.times must be <= 1000 for deterministic replay expansion.");let s=nz(e.commands);return Array.from({length:o}).flatMap(()=>a(s,t,r,n))})(e,t,r,n,aD),retry:({value:e,config:t,context:r,deps:n})=>(function(e,t,r,n,a){var i,o;if(!nW(e))throw new c("INVALID_ARGS","retry expects a map.");if(nH(e,"retry",["maxRetries","commands"]),!Array.isArray(e.commands))throw new c("INVALID_ARGS","retry requires a commands list.");let s=(i=e.maxRetries,o=r,void 0===i?1:aS(i,o,"retry.maxRetries")),l=a(nz(e.commands),t,r,n);return[ab("retry",[String(s)],{kind:"retry",maxRetries:s,actions:l})]})(e,t,r,n,aD)},ax={launchApp:(e,t)=>[n2(void 0,e,t)],scroll:()=>[nB("scroll",["down"])],hideKeyboard:()=>[nB("keyboard",["dismiss"])],eraseText:()=>[au(void 0)],back:()=>[nB("back")],waitForAnimationToEnd:()=>[nB(an,["15000"])],stopApp:(e,t)=>[n3(void 0,e,t)]};function ak(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=ax[a])?n(i,o):n0(a)}let s=Object.entries(e);if(1!==s.length)throw new c("INVALID_ARGS","Maestro command maps must contain exactly one command.");let[l,u]=s[0],d=aM[l];return d?d({value:u,config:t,context:r,deps:n,name:l}):n0(l)}(e,t,n,a)}catch(e){if(e instanceof c&&!/\bline \d+\b/.test(e.message))throw new c(e.code,`${e.message} (line ${r})`,e.details);throw e}}function aD(e,t,r,n){return e.flatMap((e,a)=>ak(e,t,a+1,r,n))}function aR(e,t){let{config:r,commands:n}=aL(aO(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=ak(r,t,n,a,{parseRunFlowFile:aP});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!==ar||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!==as)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:d}=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:[d,d,t[r+2]??d],consumed:3}:{actions:[function(e){let t={...e.flags?.maestro??{}};return delete t.allowNonHittableCoordinateFallback,{...e,flags:{...e.flags??{},maestro:{...t}}}}(i)],actionLines:[d],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 aO(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 c("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return t.map(e=>e.toJSON()).filter(e=>null!==e)}function aL(e){if(0===e.length)throw new c("INVALID_ARGS","Maestro flow is empty.");if(Array.isArray(e[0]))return{config:{},commands:nz(e[0])};let t=function(e){if(!nW(e))throw new c("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}:{},...nW(e.env)?{env:nJ(e.env,"env")}:{},...Array.isArray(e.onFlowStart)?{onFlowStart:nz(e.onFlowStart)}:{},...Array.isArray(e.onFlowComplete)?{onFlowComplete:nz(e.onFlowComplete)}:{}}}(e[0]),r=e[1];if(!Array.isArray(r))throw new c("INVALID_ARGS","Maestro flow must contain a command list after the YAML document separator.");return{config:t,commands:nz(r)}}function aP(e,r){let n=function(e,t){if(a.isAbsolute(e))return e;if(!t.baseDir)throw new c("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 c("INVALID_ARGS",`Maestro runFlow cycle detected at ${n}.`);let i=t.readFileSync(n,"utf8"),o=new Set(r.visitedPaths);return o.add(n),aR(i,{...r,baseDir:a.dirname(n),visitedPaths:o})}let a$=/[*?[\]{}]/;function aC(e,t){return"number"==typeof e?e:t}function aF(e,t){let r="number"==typeof e?e:t;return"number"!=typeof r?0:Math.max(0,Math.min(3,r))}function aE(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 aT(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&&eX(i)||(n=s.code,a=s.message,o=`${n}
25
+ ${a}`.toLowerCase(),aV.some(e=>o.includes(e))))}async function aU(e){let r,n,{filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:c,artifactsDir:p,shard:f,runReplay:m,cleanupSession:h}=e;P(s);let g=new Set,w=!1,y=Date.now(),v=function(e){let{artifactsDir:r,artifactPaths:n,filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:d}=e;if(!r)return;let c=a.join(r,"replay-timing.ndjson");return t.mkdirSync(a.dirname(c),{recursive:!0}),t.writeFileSync(c,""),n.add(c),aj(c,{type:"replay_test_attempt_start",ts:new Date().toISOString(),replayPath:i,session:o,requestId:s,timeoutMs:l,platform:u,target:d}),c}({artifactsDir:p,artifactPaths:g,filePath:i,sessionName:o,requestId:s,timeoutMs:l,platform:u,target:c}),A=m({filePath:i,sessionName:o,platform:u,target:c,requestId:s,artifactsDir:p,artifactPaths:g,tracePath:v,shard:f}).catch(e=>({ok:!1,error:d(e)})).finally(()=>{eb(s)});try{return n="number"==typeof l?await Promise.race([A,new Promise(e=>{r=setTimeout(()=>{w=!0,eg(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,[...g]))},l)})]):await A,aj(v,{type:"replay_test_attempt_stop",ts:new Date().toISOString(),session:o,ok:n.ok,timedOut:w,durationMs:Date.now()-y,errorCode:n.ok?void 0:n.error.code}),n}finally{var b;r&&clearTimeout(r),w&&(await aG(A)||((b=n)&&!b.ok&&(b.error.details={...b.error.details??{},reason:"timeout_cleanup_pending",timeoutCleanupPending:!0}),e3({level:"warn",phase:"test_timeout_cleanup_race",data:{session:o,requestId:s,graceMs:2e3}}),aq({replayPromise:A,cleanupSession:h,sessionName:o,requestId:s})));let e=Date.now();try{aj(v,{type:"replay_test_cleanup_start",ts:new Date().toISOString(),session:o}),await h(o),aj(v,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!0,durationMs:Date.now()-e})}catch(r){let t=d(r);aj(v,{type:"replay_test_cleanup_stop",ts:new Date().toISOString(),session:o,ok:!1,durationMs:Date.now()-e,errorCode:t.code}),e3({level:"warn",phase:"test_cleanup_failed",data:{session:o,error:t.message}})}}}async function aG(e){return await Promise.race([e.then(()=>!0),l(2e3).then(()=>!1)])}async function aq(e){let{replayPromise:t,cleanupSession:r,sessionName:n,requestId:a}=e;try{await t}finally{try{await r(n)}catch(e){e3({level:"warn",phase:"test_late_cleanup_failed",data:{session:n,requestId:a,error:d(e).message}})}}}function aj(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
26
+ `)}async function aK(e,t,r){let n=function(e){let t=aB(e?.shardAll,"--shard-all"),r=aB(e?.shardSplit,"--shard-split");if(void 0!==t&&void 0!==r)throw new c("INVALID_ARGS","--shard-all and --shard-split are mutually exclusive");return void 0!==t?{kind:"all",count:t}:void 0!==r?{kind:"split",count:r}:void 0}(e);if(!n||0===t.length)return;let a=await aH(e,n.count);return{mode:n.kind,shardCount:n.count,total:r+("all"===n.kind?t.length*n.count:t.length),shards:a.map((e,r)=>({shardIndex:r,shardCount:n.count,device:e,entries:"all"===n.kind?t:t.filter((e,t)=>t%n.count===r)}))}}function aB(e,t){if(void 0!==e){if("number"!=typeof e||!Number.isInteger(e)||e<1)throw new c("INVALID_ARGS",`${t} requires a positive integer`);return e}}async function aH(e,t){var r,n,a,i,o,s,l,u,d;let p,m,h=(r=e,"string"!=typeof(p=r?.device)||0===p.trim().length?[]:p.split(",").map(e=>e.trim()).filter(Boolean)),g=(a=await eo((n=e,m=eZ(n?.androidDeviceAllowlist),{platform:n?.platform,target:n?.target,iosSimulatorSetPath:f({simulatorSetPath:eW(n?.iosSimulatorDeviceSet),platform:n?.platform,target:n?.target}),androidSerialAllowlist:m?Array.from(m).sort():void 0})),i=h,o=e,i.length>0?(s=a,l=i,u=o,l.map(e=>{let t=az(e),r=s.find(r=>aW(r,u)&&(r.id===e||az(r.name)===t));if(!r)throw new c("DEVICE_NOT_FOUND",`No shard device matched ${e}`);return r})):a.filter(e=>{var t;return!!aW(t=e,o)&&("ios"===t.platform||"android"===t.platform)&&!1!==t.booted}).sort(aJ));if(g.length<t){throw new c("DEVICE_NOT_FOUND",`test sharding requires ${(d=t,`${d} device${1===d?"":"s"}`)}, but only ${g.length} matched`)}return g.slice(0,t)}function aW(e,t){return!(!ek(e.platform,t?.platform)||t?.target&&(e.target??"mobile")!==t.target)}function az(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}function aJ(e,t){return e.id.localeCompare(t.id)}async function aX(e){let{req:r,sessionName:n,runReplay:i,cleanupSession:o}=e;if((r.positionals?.length??0)===0)return $("INVALID_ARGS","test requires at least one path or glob");try{var s,l,d,p;let e,u,f,m,h,g=function(e){var r,n,i,o,s,l;let{inputs:u,cwd:d,platformFilter:p,replayBackend:f}=e,m=(r=f,new Set(aE(r)?[".ad",".yaml",".yml"]:[".ad"])),h=d??process.cwd(),g=[...new Set(u.flatMap(e=>(function(e,r,n){var i,o;let s=es.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 c("INVALID_ARGS",`test does not support this file type: ${e}`);return[s]}return[]}if(i=e,!a$.test(i)&&(o=s,!a$.test(o)))throw new c("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)),w=[];for(let e of g){let r=t.readFileSync(e,"utf8"),u=nG(r),d=(n=r,i=e,o=f,aE(o)&&".ad"!==a.extname(i)?function(e){let{config:t}=aL(aO(e));return t.name}(n):void 0);if(!p){w.push({kind:"run",path:e,title:d,metadata:u});continue}if(!u.platform){aE(f)?w.push({kind:"run",path:e,title:d,metadata:u}):w.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)&&w.push({kind:"run",path:e,title:d,metadata:u})}if(0===w.filter(e=>"run"===e.kind).length){let e=p?` for --platform ${p}`:"";throw new c("INVALID_ARGS",`No replay tests matched${e}.`)}return w}({inputs:r.positionals,cwd:r.meta?.cwd,platformFilter:r.flags?.platform,replayBackend:r.flags?.replayBackend}),w=(s=r.meta?.requestId,(s?.trim()||`${process.pid}-${Date.now().toString(36)}`).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"suite"),y=function(e){let{artifactsDir:t,cwd:r,suiteInvocationId:n}=e,i=es.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:w}),v=Date.now(),A=g.filter(e=>"skip"===e.kind),b=g.filter(e=>"run"===e.kind),S=await aK(r.flags,b,A.length),I=S?function(e){let{entries:t,total:r}=e,n=[];for(let[e,a]of t.entries())"skip"===a.kind&&(eE({type:"replay-test",file:a.path,status:"skip",index:e+1,total:r,message:a.message}),n.push({file:a.path,status:"skipped",durationMs:0,reason:a.reason,message:a.message}));return n}({entries:g,total:S.total}):[];S?I.push(...await aY({shards:S.shards,sessionName:n,suiteInvocationId:w,cwd:r.meta?.cwd,requestId:r.meta?.requestId,flags:r.flags,suiteArtifactsDir:y,suiteTotal:S.total,runReplay:i,cleanupSession:o})):I.push(...await a0({discoveryEntries:g,sessionName:n,suiteInvocationId:w,cwd:r.meta?.cwd,requestId:r.meta?.requestId,flags:r.flags,suiteArtifactsDir:y,suiteTotal:g.length,runReplay:i,cleanupSession:o}));let _=(l=S?.total??g.length,d=I,p=Date.now()-v,e=d.filter(e=>"passed"===e.status).length,f=(u=d.filter(e=>"failed"===e.status)).length,m=d.filter(e=>"skipped"===e.status).length,h=e+f,{total:l,executed:h,passed:e,failed:f,skipped:m,notRun:Math.max(0,l-h-m),durationMs:p,failures:u,tests:d});return{ok:!0,data:_}}catch(t){let e=u(t);return $(e.code,e.message)}}async function aY(e){return(await Promise.allSettled(e.shards.map(async t=>await aZ({...e,shard:t})))).flatMap((t,r)=>{var n,a;let i;if("fulfilled"===t.status)return t.value;let o=e.shards[r];return o?[(n=o,a=e.sessionName,i=d(t.reason),{file:n.entries[0]?.path??`shard-${n.shardIndex+1}`,session:aQ(a,n),status:"failed",durationMs:0,attempts:1,error:{code:i.code,message:i.message,hint:i.hint,diagnosticId:i.diagnosticId,logPath:i.logPath,details:i.details},shardIndex:n.shardIndex,shardCount:n.shardCount,deviceId:n.device.id})]:[]})}async function aZ(e){let{shard:t,sessionName:r}=e;return await a1({...e,entries:t.entries,sessionName:aQ(r,t),shard:t})}function aQ(e,t){return`${e}:shard-${t.shardIndex+1}`}async function a0(e){let{discoveryEntries:t,sessionName:r,suiteInvocationId:n,cwd:a,requestId:i,flags:o,suiteArtifactsDir:s,suiteTotal:l,runReplay:u,cleanupSession:d}=e,c=[],p=0;for(let[e,f]of t.entries()){if("skip"===f.kind){eE({type:"replay-test",file:f.path,status:"skip",index:e+1,total:l,message:f.message}),c.push({file:f.path,status:"skipped",durationMs:0,reason:f.reason,message:f.message});continue}p+=1;let t=await a2({entry:f,sessionName:r,suiteInvocationId:n,caseIndex:p-1,cwd:a,requestId:i,retries:aF(o?.retries,f.metadata.retries),timeoutMs:aC(o?.timeoutMs,f.metadata.timeoutMs),suiteArtifactsDir:s,suiteIndex:e+1,suiteTotal:l,runReplay:u,cleanupSession:d});if(c.push(t),o?.failFast===!0||aT(t))break}return c}async function a1(e){let{entries:t,sessionName:r,suiteInvocationId:n,cwd:a,requestId:i,flags:o,suiteArtifactsDir:s,suiteTotal:l,shard:u,runReplay:d,cleanupSession:c}=e,p=[];for(let[e,f]of t.entries()){let t=await a2({entry:f,sessionName:r,suiteInvocationId:n,caseIndex:e,cwd:a,requestId:i,retries:aF(o?.retries,f.metadata.retries),timeoutMs:aC(o?.timeoutMs,f.metadata.timeoutMs),suiteArtifactsDir:s,suiteIndex:e+1,suiteTotal:l,shard:u,runReplay:d,cleanupSession:c});if(p.push(t),o?.failFast===!0||aT(t))break}return p}async function a2(e){var r,n;let i,o,{entry:s,sessionName:l,suiteInvocationId:u,caseIndex:d,cwd:c,requestId:p,retries:f,timeoutMs:m,suiteArtifactsDir:h,suiteIndex:g,suiteTotal:w,shard:y,runReplay:v,cleanupSession:A}=e,b=Date.now(),S=a.join(h,...y?[`shard-${y.shardIndex+1}`]:[],(r=s.path,(0===(o=c?a.relative(c,r):a.basename(r)).length||o.startsWith("..")?a.basename(r):o).toLowerCase().replace(/[\\/]+/g,"__").replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"test")),I="",_=0,N=0,M=[];for(let e=0;e<=f;e+=1){_=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,d,e),c=a.join(S,`attempt-${_}`);n=s.path,t.mkdirSync(c,{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,c);let h=function(e){let{requestId:t,suiteInvocationId:r,filePath:n,caseIndex:i,attemptIndex:o,shardIndex:s}=e,l=void 0===s?"":`:shard:${s+1}`;return ec(`${t??r}${l}:test:${i+1}:${a.basename(n)}:attempt:${o+1}`,r)}({requestId:p,suiteInvocationId:u,filePath:s.path,caseIndex:d,attemptIndex:e,shardIndex:y?.shardIndex}),b=await aU({filePath:s.path,sessionName:o,requestId:h,timeoutMs:m,platform:s.metadata.platform,target:s.metadata.target,artifactsDir:c,shard:y,runReplay:v,cleanupSession:A});if(N=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 d=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),c=[`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;c.push(`replayed: ${e}`,`healed: ${t}`)}else c.push(`code: ${r.error.code}`,`message: ${r.error.message}`),r.error.hint&&c.push(`hint: ${r.error.hint}`),r.error.diagnosticId&&c.push(`diagnosticId: ${r.error.diagnosticId}`),r.error.logPath&&c.push(`logPath: ${r.error.logPath}`),r.error.details?.reason==="timeout"&&c.push("timeoutMode: cooperative");d.length>0&&c.push(`copiedArtifacts: ${d.map(e=>a.basename(e)).join(", ")}`);let p=a.join(l,"result.txt"),f=`${c.join("\n")}
27
+ `;t.writeFileSync(p,f),r.ok||t.writeFileSync(a.join(l,"failure.txt"),f)}({response:b,filePath:s.path,sessionName:o,attempts:_,maxAttempts:f+1,attemptArtifactsDir:c}),i=b,I=o,b.ok||(M.push({attempt:_,message:b.error.message,durationMs:N}),aT(b)||e>=f))break;eE({type:"replay-test",file:s.path,title:s.title,status:"fail",index:g,total:w,attempt:_,maxAttempts:f+1,durationMs:N,retrying:!0,message:b.error.message})}let x=Date.now()-b;if(i?.ok)return eE({type:"replay-test",file:s.path,title:s.title,status:"pass",index:g,total:w,attempt:_,maxAttempts:f+1,durationMs:x,artifactsDir:S}),{file:s.path,title:s.title,session:I,status:"passed",durationMs:x,finalAttemptDurationMs:N,attempts:_,artifactsDir:S,replayed:"number"==typeof i.data?.replayed?i.data.replayed:0,healed:"number"==typeof i.data?.healed?i.data.healed:0,...a3(y),...M.length>0?{attemptFailures:M}:{}};let k=i?.ok?{code:"COMMAND_FAILED",message:"Unknown replay test failure"}:i?.error??{code:"COMMAND_FAILED",message:"Unknown replay test failure"};return eE({type:"replay-test",file:s.path,title:s.title,status:"fail",index:g,total:w,attempt:_,maxAttempts:f+1,durationMs:x,artifactsDir:S,message:k.message}),{file:s.path,title:s.title,session:I,status:"failed",durationMs:x,attempts:_,artifactsDir:S,error:k,...a3(y)}}function a3(e){return e?{shardIndex:e.shardIndex,shardCount:e.shardCount,deviceId:e.device.id}:{}}let a5={maestro:{parse:function(e,t={}){var r;let n;return aR(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 a6(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=ti(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 a8(e){let{action:t,sessionName:r,logPath:n,sessionStore:a}=e;if(!(M(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),M(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&&a9(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}=tu(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=a6(e.positionals??[]);r&&t.push(r)}return T(t).filter(e=>e.trim().length>0)})(t).map(e=>td(e)).filter(e=>null!==e);if(0===o.length)return null;let s=M(t.command)||"fill"===t.command,l=M(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",u=await a4(i,t,n,s,a);for(let e of o){let r=tp(u.nodes,e,{platform:i.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!r)continue;let n=tf(r.node,i.device.platform,{action:"fill"===t.command?"fill":M(t.command)?"click":"get"}).join(" || ");if(M(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&&a9(t)?t:void 0}(e.positionals??[]);return r?[t,r]:[t]}(t,n):[n]};if("fill"===t.command){let e=b(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}=tu(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}=a6(t.positionals??[]),r=[n];return e&&r.push(e),{...t,positionals:r}}}return null}function a9(e){return void 0!==e&&""!==e.trim()&&Number.isFinite(Number(e))}async function a4(e,t,r,n,a){let i=ea(await m(e.device,"snapshot",[],t.flags?.out,{...ei(r,{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n},e.appBundleId,e.trace?.outPath)}),{...t.flags??{},snapshotInteractiveOnly:n,snapshotCompact:n});return H(e,i),a.set(e.name,e),i}let a7=new WeakMap,ie=new WeakMap;function it(e,t,r){return{ok:!1,error:{code:e,message:t,...r?{details:r}:{}}}}async function ir(e){var t;let r,n=!0===e.raw||"1"===process.env.AGENT_DEVICE_MAESTRO_RAW_SNAPSHOTS,a=await e.invoke({...e.baseReq,command:"snapshot",positionals:[],flags:{...e.baseReq.flags,noRecord:!0,...n?{snapshotRaw:!0}:{}}});return a.ok&&e.scope&&(t=e.scope,(r=W(ia(a.data)))&&a7.set(t,r)),a}function ia(e){return Array.isArray(e?.nodes)?e:void 0}let ii=new Map([["button",0],["link",0],["textfield",0],["textview",0],["searchfield",0],["switch",0],["slider",0],["cell",1],["statictext",2]]);function io(e,t,r,n){let a=id(e,t,r,{allowLeadingCompositeLabelMatch:!1}),i=is({nodes:e.nodes,matches:a,platform:r}),o=im(e.nodes,i.matches,void 0,iu(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 is(e){let t=e.matches.filter(t=>tb({predicate:"visible",node:t,nodes:e.nodes,platform:e.platform}).pass),r=function(e,t,r){let n=t_(e);if(!n.detected||!n.redBox)return{matches:t,blockedByReactNativeOverlay:!1};let a=tI(n),i=a.filter(t=>tb({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 il(e){return e?.platform==="android"?"android":"ios"}function iu(e){let t=tc(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 id(e,t,r,n={}){for(let a of tc(t).selectors){let t=e.nodes.filter(e=>(function(e,t,r,n){return!!th(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?th(e,{raw:t.key,terms:[t]},r):ic((i=e,"id"===(o=t.key)?i.identifier:"label"===o?i.label:"value"===o?i.value:to(i)),t.value,n)})(e,t,r,n))})(e,a,r,n));if(t.length>0)return t}return[]}function ic(e,t,r={}){var n;let a=e??"",i=tw(a),o=tw(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 ip(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 im(e,t,r,n,a,i=!1,o=!1,s){var l,u,d,c,p,f,m,h,g,w,y,v,A,b,S,I,_,N,M;let x,k,D,R,O=tm(e),L=(l=e,u=t,d=O,c=n,p=r,f=a,m=i,D=(k=(x=u.map(e=>{var t;let r;return(r=ip(l,t=e,d))?{node:t,rect:r.rect,inheritedRect:r.inherited}:null}).filter(e=>!!e)).filter(e=>!e.inheritedRect)).length>0?k:x,c&&void 0===p?(h=D,g=f,w=m,R=h.filter(e=>{var t,r;let n,a;return t=e.rect,r=g,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}),w||R.length>0?R:h):x),P=function(e,t,r,n,a,i){var o,s,l,u,d,c,p;if(void 0!==r)return t[r]??null;let f=(o=e,s=t,l=n,u=a,d=i,u&&l?function(e,t,r,n){let a=t.filter(e=>0===i_(e.node,r));if(a.length>=2){let t=ig(e,a,r,n);if(t)return t}let i=t.filter(e=>1===i_(e.node,r));return a.length>0||i.length<2?null:ig(e,i,r,n)}(o,s,l,d)??ih(o,s,l,d):ih(o,s,l,d));return(c=f,p=n,a&&p&&c)?function(e,t,r){var n,a,i,o,s,l,u,d,c,p,f,m,h,g,w,y,v,A;let b,S,I,_,N,M,x,k;if(n=t,a=r,!(("cell"===(b=tg(n.node.type??""))||"other"===b||"scrollview"===b||"scroll-area"===b)&&!(n.rect.width<120)&&!(n.rect.height<32)&&!(n.rect.height>80)&&1>=i_(n.node,a)))return null;let D=(i=e,o=t,s=r,l=tm(e),i.filter(e=>{var t,r,n;let a;return e.index!==o.node.index&&!!e.rect&&tl(i,e,o.node,l)&&(t=e,r=o.rect,n=s,!("button"!==(a=tg(t.type??""))&&"cell"!==a&&"other"!==a||1>=i_(t,n))&&!(t.rect.width<16)&&!(t.rect.height<16)&&!!iS(r,t.rect)&&iA(r,t.rect)>=.5)}).sort((e,t)=>e.rect.x-t.rect.x));if(0===D.length)return null;let R=(I=Math.floor((S=[...D.map(e=>e.rect.width)].sort((e,t)=>e-t)).length/2),S[I]??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)),L=(u=t,d=r,c=O,p=R,M=c.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=d,_=c.find(e=>1>Math.abs(e.x-f.rect.x)),N=Math.max(48,Math.min(220,8*m.length+24)),(h=f,g=m,w=_,y=N,w&&"scrollview"===tg(h.node.type??"")&&1>=i_(h.node,g)&&h.rect.width>=240&&h.rect.height>=32&&h.rect.height<=80&&w.width<=.55*h.rect.width&&w.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=O,b=o,S=a,v?b?(I=y,_=v,N=A,M=S,(ib(_.node)?null:ts(I,_.node,N,e=>{if(!ib(e))return null;let t=ip(I,e,N);return t&&function(e,t,r){var n,a;if(!iS(t,e)||(n=e,!((a=t).height<32||a.height>80||n.height<.75*a.height||.75>iA(n,a))&&!(a.width<240)&&a.width>=3*n.width))return!1;let i=iy(t),o=iy(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 ih(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===i_(e.node,r));if(l.length<2)return t;let u=tm(e),d=l.map(t=>({candidate:t,container:iw(e,t.node,u)})).filter(e=>!!e.container);if(d.length<2||d.length!==l.length)return t;let c=d.filter(e=>{var t;return t=e,d.some(e=>e!==t&&t.container.index!==e.container.index&&iI(t.container.rect,e.container.rect)>=.6)});if(c.length<2)return t;let p=(o=Math.max(...i=(a=c).map(e=>iy(e.container.rect))),(s=Math.min(...i))<=0||o<1.2*s?[]:a.filter(e=>iy(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=iw(e,r.node,n),i=a&&iS(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>iI(e.rect,r.rect)?1/0:Math.abs(e.index-r.index);if(iI(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,c,n,u);if(f.length>0)return f;let m=Math.max(...c.map(e=>e.container.index)),h=c.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=i_(e.node,r)-i_(t.node,r);if(0!==n)return n}let n=iv(e.node)-iv(t.node);if(0!==n)return n;let a=Number(e.inheritedRect)-Number(t.inheritedRect);if(0!==a)return a;let i=r&&iv(e.node)===iv(t.node)?iy(t.rect)-iy(e.rect):iy(e.rect)-iy(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 ig(e,t,r,n){let a=tm(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||!iS(i.rect,o.rect)||iy(i.rect)<2*iy(o.rect))&&tl(n,o.node,i.node,s)})});return ih(e,i,r,n)}function iw(e,t,r){return ts(e,t,r,e=>{let t;return!e.rect||"scrollview"!==(t=tg(e.type??""))&&"scroll-area"!==t&&"list"!==t||e.rect.width<240||e.rect.height<320?null:e})}function iy(e){return e.width*e.height}function iv(e){return ii.get(tg(e.type??""))??3}function iA(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 ib(e){let t=tg(e.type??"");return!0===e.hittable||"button"===t||"link"===t||"cell"===t||"textfield"===t||"searchfield"===t||"switch"===t||"slider"===t}function iS(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 iI(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(iy(e),iy(t)))}function i_(e,t){let r=[e.label,to(e),e.identifier,e.value].filter(e=>!!e);return r.some(e=>e===t)?0:r.some(e=>tw(e)===tw(t))?1:r.some(e=>ic(e,t))?2:3}async function iN(e){var t,r;let n=iO(e.positionals,{command:"assertVisible",defaultTimeoutMs:17e3});if(!n.ok)return n.response;let a=(t=e.baseReq,r=n.selector,t.flags?.platform!=="ios"&&t.flags?.platform!=="android"?null:iu(r));return a?await iM(e,n,a):await ik(e,n)}async function iM(e,t,r){let n=Date.now(),a=await ix(e,t,r);return a.ok?iC({ok:!0,data:{selector:t.selector,nativeWait:!0,query:r,response:a.data}},t.selector,n):await iD(e,t,a,n)}async function ix(e,t,r){return await e.invoke({...e.baseReq,command:"wait",positionals:[r,String(t.timeoutMs)]})}async function ik(e,t){let r,n,a=Date.now(),i=t.timeoutMs+1e3,o=!1;for(;;){let s=Date.now(),l=await iL(e,t.selector,"assertVisible");if(l.visible)return iC(l.response,t.selector,a);r=l.response,n=l.snapshot??n;let u=iR(e.baseReq,t,l,a);if("return"===u.kind)return u.response;let d=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:s,capturedAfterDeadline:o,startedAt:a,deadlineMs:i});if("capture-again"===d){o=!0;continue}if("finish"===d)break;await tx(250)}return iF(r??it("COMMAND_FAILED",`Expected visible but did not match: ${t.selector}`,{selector:t.selector,timeoutMs:t.timeoutMs}),n,e.baseReq)}async function iD(e,t,r,n){let a=await iL(e,t.selector,"assertVisible");if(a.visible)return iC(a.response,t.selector,n);let i=iR(e.baseReq,t,a,n);return"return"===i.kind?i.response:iF(r,a.snapshot,e.baseReq)}function iR(e,t,r,n){var a,i,o,s,l,u,d;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=iP(iu(e));if(!i$(r))return!1;let n=t.nodes.flatMap(e=>[e.label,e.value,e.identifier]).filter(e=>!!e?.trim()).map(e=>iP(e));return!n.some(e=>e.includes("something went wrong"))&&n.some(e=>e!==r&&!i$(e))}(o,s))?{kind:"return",response:(l=t.selector,u=t.timeoutMs,d=n,{ok:!0,data:{selector:l,alreadyPastLoading:!0,waitedMs:Date.now()-d,timeoutMs:u}})}:{kind:"continue"}}function iO(e,t){let[r,n=String(t.defaultTimeoutMs)]=e;if(!r)return{ok:!1,response:it("INVALID_ARGS",`${t.command} requires a selector.`)};let a=Number(n);return!Number.isFinite(a)||a<0?{ok:!1,response:it("INVALID_ARGS",`${t.command} timeout must be a non-negative number.`)}:{ok:!0,selector:r,timeoutMs:a}}async function iL(e,t,r){let n=await ir(e);return function(e,t,r,n){var a;if(!n.ok)return{visible:!1,response:n,infrastructureFailure:!0};let i=ia(n.data);if(!i)return{visible:!1,response:it("COMMAND_FAILED",`Unable to read snapshot data for ${r}.`),infrastructureFailure:!0};let o=io(i,t,il(e.baseReq.flags),W(i));return o.ok?(a=e.scope,a&&ie.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:it("COMMAND_FAILED",o.message,{selector:t}),infrastructureFailure:!1,snapshot:i}}(e,t,r,n)}function iP(e){return e?.trim().toLowerCase().replace(/\u2026/g,"...")??""}function i$(e){return"loading"===e||"loading..."===e}function iC(e,t,r){return e.ok?{ok:!0,data:{selector:t,...e.data,waitedMs:Date.now()-r}}:e}function iF(e,r,n){var i;if(e.ok||!r)return e;let o="string"==typeof n.flags?.artifactsDir?n.flags.artifactsDir:void 0;if(!o)return e;let s=function(e,r){try{t.mkdirSync(r,{recursive:!0});let n=a.join(r,"failure-snapshot.json"),i=a.join(r,"failure-snapshot.txt");t.writeFileSync(n,`${JSON.stringify(e,null,2)}
28
+ `);let o=tM(e.nodes,{summarizeTextSurfaces:!0}).map(e=>e.text);return t.writeFileSync(i,`${o.join("\n")}
29
+ `),[n,i]}catch{return[]}}(r,o);return 0===s.length?e:{ok:!1,error:{...e.error,details:{...e.error.details??{},artifactPaths:[...new Set([...Array.isArray(i=e.error.details?.artifactPaths)?i.filter(e=>"string"==typeof e):[],...s])]}}}}async function iE(e){let t,r=iO(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 iL(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 tx(250)}return a>0?{ok:!0,data:{pass:!0,selector:r.selector,stableSamples:a,waitedMs:Date.now()-n,timeoutMs:r.timeoutMs}}:it("COMMAND_FAILED",`Expected not visible but matched: ${r.selector}`,{selector:r.selector,timeoutMs:r.timeoutMs,lastResponse:t})}async function iV(e){let t,r,n=Number(e.positionals[0]??15e3);if(!Number.isFinite(n)||n<0)return it("INVALID_ARGS","waitForAnimationToEnd timeout must be a number.");let a=Date.now();for(;Date.now()-a<n;){let a=await ir(e),i=function(e,t,r){let n=function(e){if(!e.ok)return null;let t=ia(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 tx(250)}return r?.ok===!1?r:{ok:!0,data:{stable:!1,timeoutMs:n}}}let iT=.35,iU=120,iG=360,iq=8;function ij(e,t){return Math.round(Math.min(iG,Math.max(iU,"number"==typeof e?e*iT:0,1.5*t)))}async function iK(e){var t,r,n;let[a,i="5000",o="down"]=e.positionals;if(!a)return it("INVALID_ARGS","scrollUntilVisible requires a selector.");let s=Number(i);if(!Number.isFinite(s)||s<=0)return it("INVALID_ARGS","scrollUntilVisible timeout must be a positive number.");let l=iu(a),u=Math.max(1,Math.ceil(s/500)),d=null;for(let t=0;t<u;t+=1){let r=await iQ(e,a,l,Math.min(500,Math.max(1,s-500*t)));if(r.ok)return r;if(d=r,t===u-1)break;let n=await e.invoke({...e.baseReq,command:"scroll",positionals:[o]});if(!n.ok)return n}return t=d,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}`}}:it("COMMAND_FAILED",`scrollUntilVisible timed out after ${n}ms for selector: ${r}`)}async function iB(e){let[t,r]=e.positionals,n=Number(t),a=Number(r);if(!Number.isFinite(n)||!Number.isFinite(a))return it("INVALID_ARGS","tapOn percentage point requires numeric x/y values.");let i=await ir(e);if(!i.ok)return i;let o=ia(i.data);if(!o)return it("COMMAND_FAILED","Unable to read snapshot data for Maestro percentage point tap.");let s=W(o);if(!s)return it("COMMAND_FAILED","Unable to resolve screen size for Maestro percentage point tap.");let l=ty(s,n,a);return await e.invoke({...e.baseReq,command:"click",positionals:[String(l.x),String(l.y)],flags:{...e.baseReq.flags,postGestureStabilization:!0}})}async function iH(e){let t=await iW(e);if(t)return t;let r=await iY(e);return r.ok?await iX(e,r,r.durationMs):r.response}async function iW(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 iz(e){var t,r,n,a;let i,[o,s]=e.positionals;if(!o)return it("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:it("INVALID_ARGS","tapOn runtime options must be valid JSON.")}}}(s);if(!l.ok)return l.response;let u=Date.now(),d=(t=e,t.baseReq.flags?.maestro?.optional===!0?3e3:3e4);for(;Date.now()-u<d;){let t=await i0(e,o,l.value??{});if(!t.retry)return t.response;i=t.response,await tx(250)}return r=e,n=o,a=i,r.baseReq.flags?.maestro?.optional===!0?{ok:!0,data:{skipped:!0,optional:!0,selector:n}}:a??it("COMMAND_FAILED",`tapOn timed out for selector: ${n}`)}async function iJ(e){let[t,r="up",n]=e.positionals;if(!t)return it("INVALID_ARGS","swipe.label requires a label selector.");let a=await i5(e,t,{},"swipe.label",{promoteTapTarget:!1});if(!a.ok)return a.response;let i=function(e,t){let r=tS(e.rect),n=e.frame,a=ij(n?.referenceWidth,e.rect.width),i=ij(n?.referenceHeight,e.rect.height),o=iq,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:tv(r.y-i,o,l)}};case"down":return{ok:!0,start:r,end:{x:r.x,y:tv(r.y+i,o,l)}};case"left":return{ok:!0,start:r,end:{x:tv(r.x-a,o,s),y:r.y}};case"right":return{ok:!0,start:r,end:{x:tv(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 iX(e,i,n):it("INVALID_ARGS",i.message)}async function iX(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 iY(e){var t;let r=((t=e.scope)?a7.get(t):void 0)??await iZ(e);if(!r)return{ok:!1,response:it("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:it("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:tN({x:(s=tA({direction:a,amount:.6,referenceWidth:i.referenceWidth,referenceHeight:i.referenceHeight})).x1,y:s.y1},i,8),end:tN({x:s.x2,y:s.y2},i,8),durationMs:o};default:return{ok:!1,response:it("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,d,c,p]=e,f=[l,u,d,c].map(Number);if(f.some(e=>!Number.isFinite(e)))return{ok:!1,response:it("INVALID_ARGS","Maestro percentage swipe requires numeric points.")};let[m,h,g,w]=f,y=(n=r,a=m,i=h,o=g,s=w,"android"!==n||i!==s||50!==i||30>Math.abs(o-a)?{startY:i,endY:s}:{startY:65,endY:65});return{ok:!0,start:ty(t,m,y.startY,{marginPx:1}),end:ty(t,g,y.endY,{marginPx:1}),durationMs:p}}(a,r,il(e.baseReq.flags)):{ok:!1,response:it("INVALID_ARGS","Maestro screen swipe requires direction or percent.")}}async function iZ(e){let t=await ir(e);if(t.ok)return W(ia(t.data))}async function iQ(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 i0(e,t,r){let n=iu(t),a=await i1(e,t,r);return a.response.ok?{retry:!1,response:a.response}:a.targetResolved&&n?await i3(e,n):{retry:!0,response:a.response}}async function i1(e,t,r){let n=await i5(e,t,r,"tapOn",{promoteTapTarget:!0});return n.ok?await i2(e,t,n.target):{response:n.response,targetResolved:!1}}async function i2(e,t,r){var n;let a=tS(r.rect);e3({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,postGestureStabilization:!0}});return i.ok&&(n=e.scope)&&ie.delete(n),{response:i,targetResolved:!0}}async function i3(e,t){let r=await e.invoke({...e.baseReq,command:"find",positionals:[t,"click"],flags:{...e.baseReq.flags,findFirst:!0,postGestureStabilization:!0}});return(e3({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 i5(e,t,r,n,a){let i=await ir(e);return function(e,t,r,n,a,i){if(!i.ok)return{ok:!1,response:i};let o=ia(i.data);if(!o)return{ok:!1,response:it("COMMAND_FAILED",`Unable to read snapshot data for ${n}.`)};let s=W(o),l=il(e.baseReq.flags),u=function(e,t,r,n){var a;let i=(a=e.scope)?ie.get(a):void 0;if(!i)return;let o=io(t,i.selector,r,n);if(o.ok)return e3({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),d=function(e,t,r,n,a,i={}){let o=id(e,t,n);if(r.childOf){let t=id(e,r.childOf,n);if(0===t.length)return{ok:!1,message:`Maestro childOf parent did not match: ${r.childOf}`};let a=tm(e.nodes);o=o.filter(r=>t.some(t=>tl(e.nodes,r,t,a)))}let s=is({nodes:e.nodes,matches:o,platform:n}),l=im(e.nodes,s.matches,r.index,iu(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}}(o,t,r,l,s,{...a,preferredContext:u,requireOnScreen:!0});if(!d.ok){let e=iu(t);if(e){let t=function(e,t,r,n,a={}){let i=function(e,t){let r=tw(t);if(!r)return[];let n=[],a=[];for(let t of e.nodes){let e=[t.label,to(t),t.identifier,t.value].filter(e=>!!e).map(e=>tw(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=is({nodes:e.nodes,matches:i,platform:r}),s=im(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}`}}(o,e,l,s,{...a,preferredContext:u,requireOnScreen:!0});if(t.ok)return{ok:!0,target:{node:t.node,rect:t.rect,frame:s}}}}return d.ok?{ok:!0,target:{node:d.node,rect:d.rect,frame:s}}:{ok:!1,response:it("ELEMENT_NOT_FOUND",d.message,{selector:t,options:r,command:n})}}(e,t,r,n,a,i)}async function i6(e){switch(e.command){case ae:return await iN(e);case at:return await iE(e);case ar:return await i8(e);case an:return await iV(e);case aa:return await iK(e);case ai:return await iH(e);case ao:return await iJ(e);case as:return await iz(e);case al:return await iB(e);case n7:return function(e){let[r]=e.positionals;if(!r)return it("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:a_,http:{post:(e,t)=>(function(e,t,r){let n=ta(process.execPath,["-e",aI],{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 c("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 c("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 c("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 c("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 it(e.code,e.message,e.details)}}(e);default:return}}async function i8(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 i9(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 i4(e){let t;for(let r=0;r<=e.maxRetries;r+=1){let n=await i9({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 i7(e){let t=await oe(e,e.control);return t.ok?t.matched?await on(e):{ok:!0,data:{skipped:!0,condition:e.control.mode,selector:e.control.selector}}:t.response}async function oe(e,t){if("visible"===t.mode)return await ot(e,t);let r=await or(e,t.selector);return r.ok?{ok:!0,matched:!r.matched}:{ok:!1,response:r.response}}async function ot(e,t){let r=Date.now();for(;;){let n=await or(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 tx(250)}}async function or(e,t){var r,n;let a,i=await ir(e);return i.ok?(r=e,n=t,(a=ia(i.data))?{ok:!0,matched:io(a,n,il(r.baseReq.flags),W(a)).ok}:{ok:!1,response:it("COMMAND_FAILED","Unable to read snapshot data for runFlow.when.")}):{ok:!1,response:i}}async function on(e){let t=await i9({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 oa(e){var t;let{req:r,sessionName:n,action:a,scope:i,filePath:o,line:s,step:l,tracePath:u,invoke:d}=e,c=(t={file:o,line:s},{...a,positionals:(a.positionals??[]).map(e=>nE(e,i,t)),flags:nV(a.flags,i,t)??{},runtime:nV(a.runtime,i,t),replayControl:function(e,t,r){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:nE(e.selector,t,r)}}return e}(a.replayControl,i,t)}),p=Date.now();os(u,{type:"replay_action_start",ts:new Date(p).toISOString(),replayPath:o,line:s,step:l,command:c.command,positionals:c.positionals??[]});let f=await oi({req:r,sessionName:n,resolved:c,scope:i,line:s,step:l,invoke:d,invokeReplayAction:e=>oa({req:r,sessionName:n,action:e.action,scope:i,filePath:o,line:e.line,step:e.step,tracePath:u,invoke:d})}),m=Date.now();return os(u,{type:"replay_action_stop",ts:new Date(m).toISOString(),replayPath:o,line:s,step:l,command:c.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 oi(e){var t;let{req:r,sessionName:n,resolved:a,scope:i,line:o,step:s,invoke:l,invokeReplayAction:u}=e,d=(t=r.flags,e6(t,{...a.flags??{}})),c={token:r.token,session:n,flags:d,runtime:a.runtime,meta:r.meta},p=await oo({control:a.replayControl,baseReq:c,line:o,step:s,invoke:l,invokeReplayAction:u})??await i6({command:a.command,baseReq:c,positionals:a.positionals??[],scope:i,line:o,step:s,invoke:l,invokeReplayAction:u})??await l({...c,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 oo(e){let{control:t,baseReq:r,line:n,step:a,invoke:i,invokeReplayAction:o}=e;if(t){switch(t.kind){case"retry":return await i4({actions:t.actions,maxRetries:t.maxRetries,line:n,step:a,invokeReplayAction:o});case"maestroRunFlowWhen":return await i7({baseReq:r,control:t,line:n,step:a,invoke:i,invokeReplayAction:o})}return t}}function os(e,r){e&&t.appendFileSync(e,`${JSON.stringify(r)}
30
+ `)}async function ol(e){let{req:r,sessionName:n,logPath:i,sessionStore:o,tracePath:s,invoke:l}=e,d=r.positionals?.[0];if(!d)return $("INVALID_ARGS","replay requires a path");let p="",f=new Set;try{var m,h;p=es.expandHome(d,r.meta?.cwd);let e=t.readFileSync(p,"utf8"),u=e.trimStart()[0];if("{"===u||"["===u)return $("INVALID_ARGS","replay accepts .ad script files. JSON replay payloads are no longer supported.");let g=function(e,t,r={}){var n;let a=function(e){let t=e?.replayBackend;if("string"!=typeof t)return;let r=a5[t];if(!r)throw new c("INVALID_ARGS",`Unsupported replay backend "${t}".`);return r}(t);return a?{...a.parse(e,{...r,platform:t?.platform,env:(n=t,{...nP(nF(n?.replayShellEnv)),...n$(nC(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(nq(n)){if(a)throw new c("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 c("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=E(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a.runtime=e.runtime,a}if("runtime"===r){let e=B(n);return a.positionals=e.positionals,Object.assign(a.flags,e.flags),a}if(D(r)){let e=e_(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 nK(i)&&nK(o)&&e.positionals.length>=2?a.positionals=[i,o]:a.positionals=[e.positionals.join(" ")],a}if("fill"===r){let e=e_(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=e_(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=tn({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:nG(e)}}(e,r.flags,{sourcePath:p}),w=g.metadata,y=w.platform||w.target?{...r,flags:(m=r.flags,h=w,{...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=g.actions,A=g.actionLines;if(r.flags?.replayUpdate===!0&&g.updateUnsupportedMessage)return $("INVALID_ARGS",g.updateUnsupportedMessage);if(r.flags?.replayUpdate===!0&&w.env&&Object.keys(w.env).length>0)return $("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(op(t.flags)||op(t.runtime))return!0}return!1}(v))return $("INVALID_ARGS","replay -u does not yet preserve ${VAR} substitutions. Resolve or inline the variables before running with -u.");let b=function(e){let t={};if(e.builtins)for(let[r,n]of Object.entries(e.builtins))t[r]=n;for(let r of[e.fileEnv,e.shellEnv,e.cliEnv])if(r)for(let[e,n]of Object.entries(r)){if(nO(e))throw nL(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 d=o.target??n.target;d&&(l.AD_TARGET=d);let c=o.device;"string"==typeof c&&c.length>0&&(l.AD_DEVICE=c);let p="string"==typeof o.serial?o.serial:o.udid;"string"==typeof p&&p.length>0&&(l.AD_DEVICE_ID=p),"number"==typeof o.shardIndex&&(l.AD_SHARD_INDEX=String(o.shardIndex)),"number"==typeof o.shardCount&&(l.AD_SHARD_COUNT=String(o.shardCount));let f=o.artifactsDir;return"string"==typeof f&&f.length>0&&(l.AD_ARTIFACTS=f),l}({req:y,sessionName:n,metadata:w,resolvedPath:p}),fileEnv:w.env,shellEnv:nP(nF(r.flags?.replayShellEnv)),cliEnv:n$(nC(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 oa({req:y,sessionName:n,action:t,scope:b,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l});if(r.ok){od(r).forEach(e=>f.add(e));continue}if(od(r).forEach(e=>f.add(e)),!I)return ou(r,t,e,p,[...f]);let a=await a8({action:t,sessionName:n,logPath:i,sessionStore:o});if(!a)return ou(r,t,e,p,[...f]);if(v[e]=a,!(r=await oa({req:y,sessionName:n,action:a,scope:b,filePath:p,line:A[e]??0,step:e+1,tracePath:_,invoke:l})).ok)return od(r).forEach(e=>f.add(e)),ou(r,a,e,p,[...f]);od(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=${el(n.device.name)}${e} theme=unknown`)}for(let e of r){var i;a.push((i=e,S(i,{runtimeIncludeAllPositionals:!0})))}let o=`${a.join("\n")}
31
+ `,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 $(e.code,e.message,f.size>0?{artifactPaths:[...f]}:void 0)}}function ou(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} (${eu(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 od(e){if(!e.ok){let t=e.error.details?.artifactPaths;return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e&&oc(e)))]:[]}if(!e.data)return[];let t=[];if("string"==typeof e.data.path&&t.push(e.data.path),"string"==typeof e.data.outPath&&t.push(e.data.outPath),Array.isArray(e.data.artifacts))for(let r of e.data.artifacts){if(!r||"object"!=typeof r)continue;let e="string"==typeof r.localPath?r.localPath:void 0,n="string"==typeof r.path?r.path:void 0;e?t.push(e):n&&t.push(n)}return[...new Set(t.filter(e=>oc(e)))]}function oc(e){try{return t.statSync(e).isFile()}catch{return!1}}function op(e){return"string"==typeof e?e.includes("${"):Array.isArray(e)?e.some(op):!!e&&"object"==typeof e&&Object.values(e).some(op)}async function of(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}=e;return"replay"===t.command?await ol({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i}):"test"===t.command?await aX({req:t,sessionName:r,runReplay:async({filePath:e,sessionName:r,platform:o,target:s,requestId:l,artifactsDir:u,artifactPaths:d,tracePath:c,shard:p})=>{let f=function(e){let{parentFlags:t,platform:r,target:n,artifactsDir:a,shard:i}=e;if(void 0===r&&void 0===n&&void 0===a&&void 0===i)return t;var o={...t??{},...void 0!==r?{platform:r}:{},...void 0!==n?{target:n}:{},...void 0!==a?{artifactsDir:a}:{}};if(!i)return o;let s={...o??{},device:void 0,udid:void 0,serial:void 0,platform:i.device.platform,target:i.device.target,shardAll:void 0,shardSplit:void 0,shardCount:i.shardCount,shardIndex:i.shardIndex};return"android"===i.device.platform?{...s,serial:i.device.id}:{...s,udid:i.device.id}}({parentFlags:t.flags,platform:o,target:s,artifactsDir:u,shard:p});return await ol({req:{...t,command:"replay",session:r,positionals:[e],flags:f,meta:l?{...t.meta??{},requestId:l}:t.meta},sessionName:r,logPath:n,sessionStore:a,tracePath:c,invoke:async e=>{var t;return t=await i(e),d&&od(t).forEach(e=>d.add(e)),t}})},cleanupSession:async e=>{a.get(e)&&await J({req:{token:t.token,session:e,command:"close",positionals:[],flags:{},meta:t.meta},sessionName:e,logPath:n,sessionStore:a})}}):null}async function om(e){var t,r,n,a,i,o,s,l;let u,d,{req:c,sessionName:p,logPath:f,sessionStore:m}=e,h=c.positionals?.[0]??"";if("ios-runner"!==h)return $("INVALID_ARGS","prepare requires a subcommand: ios-runner");let g=m.get(p),w=c.flags??{},v=N(tD.prepare,g,w);if(v)return v;let A=await y({session:g,flags:w,ensureReady:!0});if(!eO(A.platform))return $("UNSUPPORTED_OPERATION","prepare ios-runner is only supported on Apple runner platforms");let b=Date.now(),S=await Y(A,(t=c,r=g,n=f,d=(a=t,"number"==typeof(u=a.flags?.timeoutMs)&&Number.isFinite(u)&&u>0?u:3e5),{verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,cleanStaleBundles:!0,startupTimeoutMs:function(e){if("number"==typeof e&&Number.isFinite(e)&&!(e<=0))return Math.max(45e3,Math.floor(e))}(t.flags?.timeoutMs),requestId:t.meta?.requestId,buildTimeoutMs:d,healthTimeoutMs:Math.min(d,9e4)}));return{ok:!0,data:(i=h,o=A,s=Math.max(0,Date.now()-b),l=S,{action:i,platform:o.platform,deviceId:o.id,deviceName:o.name,kind:o.kind,durationMs:s,...l,message:`Prepared Apple runner: ${o.name}`})}}async function oh(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,command:i,positionals:o,recordPositionals:s,deriveNextSession:l}=e,u=a.get(r),d=t.flags??{},c=N(i,u,d);if(c)return c;let p=await y({session:u,flags:d,ensureReady:!0});if(!eD(i,p))return $("UNSUPPORTED_OPERATION",`${i} is not supported on this device`);let f=await m(p,i,o,t.flags?.out,{...ei(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 og(e){let{req:t,sessionName:r,logPath:n,sessionStore:a}=e,i=a.get(r),o=t.flags??{},s=N(tD.clipboard,i,o);if(s)return s;let l=(t.positionals?.[0]??"").toLowerCase();if("read"!==l&&"write"!==l)return $("INVALID_ARGS","clipboard requires a subcommand: read or write");let u=await y({session:i,flags:o,ensureReady:!0});if(!eD(tD.clipboard,u))return $("UNSUPPORTED_OPERATION","clipboard is not supported on this device");let d=await m(u,tD.clipboard,t.positionals??[],t.flags?.out,{...ei(n,t.flags,i?.appBundleId,i?.trace?.outPath)});return i&&a.recordAction(i,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:d??{}}),{ok:!0,data:{platform:u.platform,...d??{}}}}async function ow(e){let{req:t,sessionName:r,logPath:n,sessionStore:a,invoke:i,invokeReplayAction:o,androidAdbExecutor:s}=e;if("inventory"===A(t.command))return await rb({req:t,sessionName:r,sessionStore:a});if("runtime"===t.command)return await tj({req:t,sessionName:r,sessionStore:a});if("state"===A(t.command))return await rM({req:t,sessionName:r,sessionStore:a});if(t.command===tD.clipboard)return await og({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===tD.keyboard){let e=a.get(r),i=t.positionals?.[0]?.trim().toLowerCase();return e||"dismiss"!==i&&"enter"!==i&&"return"!==i||"ios"!==eP((t.flags??{}).platform)?await oh({req:t,sessionName:r,logPath:n,sessionStore:a,command:tD.keyboard,positionals:t.positionals??[]}):$("SESSION_NOT_FOUND","iOS keyboard action requires an active session so the target app stays foregrounded. Run open first.")}if("observability"===A(t.command))return await nA({req:t,sessionName:r,sessionStore:a,androidAdbExecutor:s});if(t.command===tD.prepare)return await om({req:t,sessionName:r,logPath:n,sessionStore:a});if(t.command===tD.install||t.command===tD.reinstall)return await rv({req:t,command:t.command,sessionName:r,sessionStore:a,deployOps:t.command===tD.install?ry:rw});if(t.command===tk.installSource)return await tC({req:t,sessionName:r,sessionStore:a});if(t.command===tk.releaseMaterializedPaths)return await tF({req:t});if(t.command===tD.push){let e,i=t.positionals?.[0]?.trim(),o=t.positionals?.[1]?.trim();return i&&o?await oh({req:t,sessionName:r,logPath:n,sessionStore:a,command:tD.push,positionals:[i,"file"===(e=em(o,{subject:"Push payload",cwd:t.meta?.cwd,expandPath:(e,t)=>es.expandHome(e,t)})).kind?e.path:e.text],recordPositionals:[i,o]}):$("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>")}return t.command===tD.triggerAppEvent?await oh({req:t,sessionName:r,logPath:n,sessionStore:a,command:tD.triggerAppEvent,positionals:t.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,n=r?await ro(e.device,r,e.appBundleId,ra)??e.appBundleId:e.appBundleId;return{...e,appBundleId:n}}}):t.command===tD.open?await rg({req:t,sessionName:r,logPath:n,sessionStore:a}):"replay"===A(t.command)?await of({req:t,sessionName:r,logPath:n,sessionStore:a,invoke:o??i}):t.command===tD.batch?await rA(t,r,i):t.command===tD.close?await J({req:t,sessionName:r,logPath:n,sessionStore:a}):null}export{tO as session_namespaceObject};