agent-device 0.17.6 → 0.17.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +3 -3
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.6.apk → agent-device-android-multitouch-helper-0.17.8.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.8.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.6.manifest.json → agent-device-android-multitouch-helper-0.17.8.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.6.apk → agent-device-android-snapshot-helper-0.17.8.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.8.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.6.manifest.json → agent-device-android-snapshot-helper-0.17.8.manifest.json} +6 -6
  8. package/dist/src/2133.js +1 -1
  9. package/dist/src/2577.js +1 -0
  10. package/dist/src/2948.js +1 -1
  11. package/dist/src/4291.js +1 -2
  12. package/dist/src/4428.js +3 -3
  13. package/dist/src/4723.js +1 -1
  14. package/dist/src/5910.js +2 -0
  15. package/dist/src/6311.js +18 -18
  16. package/dist/src/7244.js +1 -1
  17. package/dist/src/8184.js +1 -1
  18. package/dist/src/8358.js +4 -0
  19. package/dist/src/9581.js +22 -1
  20. package/dist/src/9722.js +36 -36
  21. package/dist/src/9873.js +1 -1
  22. package/dist/src/9919.js +5 -5
  23. package/dist/src/android-adb.d.ts +1 -1
  24. package/dist/src/batch.d.ts +1 -1
  25. package/dist/src/cli-help.js +140 -30
  26. package/dist/src/cli-output.js +4 -4
  27. package/dist/src/cli.js +28 -17
  28. package/dist/src/contracts.d.ts +1 -1
  29. package/dist/src/index.d.ts +7 -4
  30. package/dist/src/interaction.js +1 -1
  31. package/dist/src/internal/bin.js +1 -1
  32. package/dist/src/provider.js +1 -0
  33. package/dist/src/record-trace-recording.js +3 -3
  34. package/dist/src/remote-config.d.ts +1 -1
  35. package/dist/src/selector-runtime.js +1 -1
  36. package/dist/src/selectors.d.ts +2 -2
  37. package/dist/src/session.js +8 -8
  38. package/dist/src/snapshot.js +1 -1
  39. package/dist/src/web.js +1 -0
  40. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +6 -6
  41. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +1 -1
  42. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +9 -5
  43. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +0 -2
  44. package/ios-runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +44 -8
  45. package/ios-runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +59 -16
  46. package/ios-runner/RUNNER_PROTOCOL.md +1 -1
  47. package/package.json +5 -2
  48. package/server.json +2 -2
  49. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.6.apk.sha256 +0 -1
  50. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.6.apk.sha256 +0 -1
  51. package/dist/src/2892.js +0 -4
  52. package/dist/src/5299.js +0 -1
package/README.md CHANGED
@@ -15,11 +15,11 @@
15
15
 
16
16
  Mobile app verification for AI agents.
17
17
 
18
- A device automation CLI for real apps on iOS, Android, TV, and desktop. Agents get token-efficient snapshots, semantic refs, and evidence captured only when needed.
18
+ A device automation CLI for real apps on iOS, Android, TV, web, and desktop. Agents get token-efficient snapshots, semantic refs, and evidence captured only when needed.
19
19
 
20
20
  `agent-device` lets coding agents open apps, inspect the current UI, interact with visible elements, and collect debugging evidence through one CLI. Use it when an agent needs to verify what actually happens on a device, not just reason about code.
21
21
 
22
- If you know Vercel's [agent-browser](https://github.com/vercel-labs/agent-browser), `agent-device` is the same idea for mobile, TV, and desktop apps.
22
+ If you know Vercel's [agent-browser](https://github.com/vercel-labs/agent-browser), `agent-device` is the same idea for mobile, TV, and desktop apps. Minimal `--platform web` support reuses `agent-browser` when a browser session needs to fit into the same command/session/replay loop.
23
23
 
24
24
  It works with native iOS and Android apps, plus apps built with Expo, Flutter, and React Native, as long as the target can run on a supported device, simulator, emulator, or desktop environment.
25
25
 
@@ -56,7 +56,7 @@ agent-device help workflow
56
56
 
57
57
  The installed CLI help is the source of truth for agents. Start with `agent-device help workflow`, then follow the topic-specific help when a task needs dogfooding, debugging, replay, or React Native profiling.
58
58
 
59
- Prerequisites depend on the target platform: Node.js 22+, Xcode for iOS/tvOS/macOS targets, Android SDK + ADB for Android, and macOS Accessibility permission for desktop automation. See [Installation](https://oss.callstack.com/agent-device/docs/installation) for platform setup.
59
+ Prerequisites depend on the target platform: Node.js 22+, Xcode for iOS/tvOS/macOS targets, Android SDK + ADB for Android, and macOS Accessibility permission for desktop automation. Web automation requires Node 24+. See [Installation](https://oss.callstack.com/agent-device/docs/installation) for platform setup.
60
60
 
61
61
  Try the basic loop:
62
62
 
@@ -0,0 +1 @@
1
+ 7babb1a8cfdc9ea488cb6d419067a5345cf287581532de6a388b3c0f6bb9f72f agent-device-android-multitouch-helper-0.17.8.apk
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "android-multitouch-helper",
3
- "version": "0.17.6",
4
- "assetName": "agent-device-android-multitouch-helper-0.17.6.apk",
5
- "sha256": "b6bd66b2aa684d61d48ed2159b34ec9cde449b101b806af149ca6874a4ad9090",
3
+ "version": "0.17.8",
4
+ "assetName": "agent-device-android-multitouch-helper-0.17.8.apk",
5
+ "sha256": "7babb1a8cfdc9ea488cb6d419067a5345cf287581532de6a388b3c0f6bb9f72f",
6
6
  "packageName": "com.callstack.agentdevice.multitouchhelper",
7
- "versionCode": 17006,
7
+ "versionCode": 17008,
8
8
  "instrumentationRunner": "com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation",
9
9
  "statusProtocol": "android-multitouch-helper-v1"
10
10
  }
@@ -0,0 +1 @@
1
+ 95eff5dda23179abb7da5bcf1650fb4e9ebcf40ae08871936683233aee152914 agent-device-android-snapshot-helper-0.17.8.apk
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "android-snapshot-helper",
3
- "version": "0.17.6",
4
- "releaseTag": "v0.17.6",
5
- "assetName": "agent-device-android-snapshot-helper-0.17.6.apk",
3
+ "version": "0.17.8",
4
+ "releaseTag": "v0.17.8",
5
+ "assetName": "agent-device-android-snapshot-helper-0.17.8.apk",
6
6
  "apkUrl": null,
7
- "sha256": "a71a58df7650a62b7e10acd668fe3b60039cbb8e2203d7e31de60c848aee34ab",
8
- "checksumName": "agent-device-android-snapshot-helper-0.17.6.apk.sha256",
7
+ "sha256": "95eff5dda23179abb7da5bcf1650fb4e9ebcf40ae08871936683233aee152914",
8
+ "checksumName": "agent-device-android-snapshot-helper-0.17.8.apk.sha256",
9
9
  "packageName": "com.callstack.agentdevice.snapshothelper",
10
- "versionCode": 17006,
10
+ "versionCode": 17008,
11
11
  "instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
12
12
  "minSdk": 23,
13
13
  "targetSdk": 36,
package/dist/src/2133.js CHANGED
@@ -1 +1 @@
1
- import{AppError as e}from"./733.js";let t={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",close:"close",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",gesture:"gesture",get:"get",home:"home",install:"install",installFromSource:"install-from-source",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",open:"open",perf:"perf",prepare:"prepare",press:"press",push:"push",record:"record",reactNative:"react-native",reinstall:"reinstall",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",shutdown:"shutdown",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"},s={installSource:"install_source",leaseAllocate:"lease_allocate",leaseHeartbeat:"lease_heartbeat",leaseRelease:"lease_release",releaseMaterializedPaths:"release_materialized_paths",runtime:"runtime",sessionList:"session_list"},a={auth:"auth",connect:"connect",connection:"connection",debug:"debug",disconnect:"disconnect",mcp:"mcp",metro:"metro",reactDevtools:"react-devtools",session:"session"},r=["pan","fling","swipe","pinch","rotate","transform"],o=`gesture requires one of: ${r.join(", ")}`,n=c(a.auth,a.connect,a.connection,a.disconnect,a.mcp,a.reactDevtools,t.prepare);function c(...e){return new Set(e)}function i(){return[...Object.values(t),...Object.values(a)].sort()}function l(e){return Object.values(t).includes(e)||e===a.debug||e===a.metro||e===a.session}function p(){return i().filter(e=>!n.has(e))}c(a.auth,a.connect,a.connection,a.debug,a.disconnect,a.mcp,a.metro,a.reactDevtools,a.session,t.appState,t.prepare,t.batch,t.devices,t.gesture,t.replay,t.test,t.trace);let u=[t.devices,t.boot,t.shutdown,t.apps,t.open,t.close,t.install,t.reinstall,t.installFromSource,t.push,t.triggerAppEvent,t.snapshot,t.screenshot,t.diff,t.wait,t.alert,t.settings,t.click,t.press,t.longPress,t.swipe,t.focus,t.type,t.fill,t.scroll,t.get,t.gesture,t.is,t.find,t.perf,t.logs,t.network,t.record,t.trace,t.test,t.appState,t.back,t.home,t.rotate,t.appSwitcher,t.keyboard,t.clipboard,t.reactNative],d=new Set(["batch","replay"]),m=["command","positionals","flags","runtime"],h=["platform","target","device","udid","serial","verbose","out"],f=new Set(u);function g(e){return"string"==typeof e?e.trim().toLowerCase():""}function _(t,s){let a=g(t);if(f.has(a))return a;throw new e("INVALID_ARGS",`Batch step ${s} command is not available through command batch: ${String(t)}`)}function S(t,s){if(d.has(t))throw new e("INVALID_ARGS",`Batch step ${s} cannot run ${t}.`)}export{d as BATCH_BLOCKED_COMMANDS,m as BATCH_DAEMON_STEP_KEYS,r as GESTURE_KINDS,o as GESTURE_SUBCOMMAND_ERROR,h as INHERITED_PARENT_FLAG_KEYS,s as INTERNAL_COMMANDS,t as PUBLIC_COMMANDS,u as STRUCTURED_BATCH_COMMAND_NAMES,S as assertBatchRuntimeCommandAllowed,l as isClientBackedCliCommandName,i as listCliCommandNames,p as listMcpExposedCommandNames,g as normalizeBatchCommandName,_ as readStructuredBatchCommandName};
1
+ import{AppError as e}from"./733.js";let t={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",close:"close",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",gesture:"gesture",get:"get",home:"home",install:"install",installFromSource:"install-from-source",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",open:"open",perf:"perf",prepare:"prepare",press:"press",push:"push",record:"record",reactNative:"react-native",reinstall:"reinstall",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",shutdown:"shutdown",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"},s={installSource:"install_source",leaseAllocate:"lease_allocate",leaseHeartbeat:"lease_heartbeat",leaseRelease:"lease_release",releaseMaterializedPaths:"release_materialized_paths",runtime:"runtime",sessionList:"session_list"},a={auth:"auth",connect:"connect",connection:"connection",debug:"debug",disconnect:"disconnect",mcp:"mcp",metro:"metro",proxy:"proxy",reactDevtools:"react-devtools",session:"session",web:"web"},r=["pan","fling","swipe","pinch","rotate","transform"],o=`gesture requires one of: ${r.join(", ")}`,n=c(a.auth,a.connect,a.connection,a.disconnect,a.mcp,a.proxy,a.reactDevtools,a.web,t.prepare);function c(...e){return new Set(e)}function i(){return[...Object.values(t),...Object.values(a)].sort()}function l(e){return Object.values(t).includes(e)||e===a.debug||e===a.metro||e===a.session}function p(){return i().filter(e=>!n.has(e))}c(a.auth,a.connect,a.connection,a.debug,a.disconnect,a.mcp,a.metro,a.proxy,a.reactDevtools,a.session,a.web,t.appState,t.prepare,t.batch,t.devices,t.gesture,t.replay,t.test,t.trace);let u=[t.devices,t.boot,t.shutdown,t.apps,t.open,t.close,t.install,t.reinstall,t.installFromSource,t.push,t.triggerAppEvent,t.snapshot,t.screenshot,t.diff,t.wait,t.alert,t.settings,t.click,t.press,t.longPress,t.swipe,t.focus,t.type,t.fill,t.scroll,t.get,t.gesture,t.is,t.find,t.perf,t.logs,t.network,t.record,t.trace,t.test,t.appState,t.back,t.home,t.rotate,t.appSwitcher,t.keyboard,t.clipboard,t.reactNative],d=new Set(["batch","replay"]),m=["command","positionals","flags","runtime"],h=["platform","target","device","udid","serial","verbose","out"],f=new Set(u);function g(e){return"string"==typeof e?e.trim().toLowerCase():""}function b(t,s){let a=g(t);if(f.has(a))return a;throw new e("INVALID_ARGS",`Batch step ${s} command is not available through command batch: ${String(t)}`)}function _(t,s){if(d.has(t))throw new e("INVALID_ARGS",`Batch step ${s} cannot run ${t}.`)}export{d as BATCH_BLOCKED_COMMANDS,m as BATCH_DAEMON_STEP_KEYS,r as GESTURE_KINDS,o as GESTURE_SUBCOMMAND_ERROR,h as INHERITED_PARENT_FLAG_KEYS,s as INTERNAL_COMMANDS,t as PUBLIC_COMMANDS,u as STRUCTURED_BATCH_COMMAND_NAMES,_ as assertBatchRuntimeCommandAllowed,l as isClientBackedCliCommandName,i as listCliCommandNames,p as listMcpExposedCommandNames,g as normalizeBatchCommandName,b as readStructuredBatchCommandName};
@@ -0,0 +1 @@
1
+ import e from"node:crypto";import t,{promises as n}from"node:fs";import a from"node:path";import{Worker as r}from"node:worker_threads";import{fileURLToPath as i}from"node:url";import s from"node:os";import{buildMobileSnapshotPresentation as o,isSparseSnapshotQualityVerdict as l,now as d,isNodeVisibleInEffectiveViewport as u,sleep as c,publicSnapshotCaptureAnnotations as p,scrollCommand as h,longPressCommand as f,appendScreenshotScriptFlags as m,successText as w,focusCommand as g,toBackendResult as b,swipeCommand as y,recordingQualityInputToExportQuality as k,resolveInteractionTarget as v,toBackendContext as x,snapshotCaptureAnnotationsFrom as A,requireIntInRange as M,formatReactNativeOverlayWarning as S,pinchCommand as I,renderSnapshotQualityWarnings as R}from"./9873.js";import{emitDiagnostic as P}from"./432.js";import{asAppError as N,toAppErrorCode as _,AppError as D}from"./733.js";import{computeScreenshotDiffPixels as O,PNG as E,toBuffer as T,decodePng as C}from"./4418.js";import{expandRect as U,intersectArea as L,unionRects as $,rectCenter as B,clamp as q,normalizedRect as G,squaredDistance as X}from"./6024.js";import{whichCmd as Y,runCmd as F}from"./8875.js";import{formatSnapshotLine as K,formatRole as j,displayLabel as H,buildSnapshotDisplayLines as V}from"./7244.js";import{normalizeRef as z,findNodeByRef as W,buildSnapshotPresentationKey as J,usesMobileSnapshotPresentation as Z}from"./4291.js";import{extractNodeText as Q,findSnapshotAncestor as ee,parseSelectorChain as et,isNodeVisible as en,buildSnapshotNodeByIndex as ea,isNodeEditable as er,findSelectorChainMatch as ei,buildSelectorChainForNode as es,resolveSelectorChain as eo,findNodeByLabel as el,resolveRefLabel as ed,extractReadableText as eu,formatSelectorFailure as ec,normalizeType as ep,isFillableType as eh}from"./9836.js";import{findBestMatchesByLocator as ef}from"./587.js";import{isProcessAlive as em,readProcessStartTime as ew}from"./5628.js";import{sleep as eg}from"./5560.js";import{resolveAppsFilter as eb,assertResolvedAppsFilter as ey}from"./2748.js";let ek=/^-?\d+(\.\d+)?$/,ev=/^[^\s"\\]+$/,ex=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),eA=new Map([["--count","count"],["--pause-ms","pauseMs"]]),eM=new Map([["--delay-ms","delayMs"]]);function eS(e){return"click"===e||"press"===e}function eI(e){return eS(e)||"longpress"===e}function eR(e){return"type"===e||"fill"===e}function eP(e){return e_(e,eD)}function eN(e){return JSON.stringify(e)}function e_(e,t){return t(e)?e:eN(e)}function eD(e){return eO(e)&&e.startsWith("@")||ek.test(e)}function eO(e){return ev.test(e)}function eE(e){let t=(e.positionals??[]).map(e=>eP(e));return[e.command,...t].join(" ")}function eT(e,t){let n=t.flags??{};if(eS(t.command)){"number"==typeof n.count&&e.push("--count",String(n.count)),"number"==typeof n.intervalMs&&e.push("--interval-ms",String(n.intervalMs)),"number"==typeof n.holdMs&&e.push("--hold-ms",String(n.holdMs)),"number"==typeof n.jitterPx&&e.push("--jitter-px",String(n.jitterPx)),!0===n.doubleTap&&e.push("--double-tap");let t=n.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof n.count&&e.push("--count",String(n.count)),"number"==typeof n.pauseMs&&e.push("--pause-ms",String(n.pauseMs)),("one-way"===n.pattern||"ping-pong"===n.pattern)&&e.push("--pattern",n.pattern);return}eR(t.command)&&"number"==typeof n.delayMs&&e.push("--delay-ms",String(n.delayMs))}function eC(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",e_(t.metroHost,eO)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",e_(t.bundleUrl,eO)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",e_(t.launchUrl,eO)))}function eU(e,t){let n=[],a={},r=eS(e)?ex:"swipe"===e?eA:eR(e)?eM:void 0;for(let i=0;i<t.length;i+=1){let s=t[i];if(eS(e)&&"--double-tap"===s){a.doubleTap=!0;continue}let o=t[i+1];if(eS(e)&&"--button"===s&&void 0!==o){("primary"===o||"secondary"===o||"middle"===o)&&(a.clickButton=o),i+=1;continue}let l=r?.get(s);if(l&&void 0!==o){let e=e$(o);if(null!==e){a[l]=e,i+=1;continue}}if("swipe"===e&&"--pattern"===s&&void 0!==o){("one-way"===o||"ping-pong"===o)&&(a.pattern=o),i+=1;continue}n.push(s)}return{positionals:n,flags:a}}function eL(e){let t=[],n={};for(let a=0;a<e.length;a+=1){let r=e[a],i=e[a+1];if("--platform"===r&&void 0!==i){("ios"===i||"android"===i)&&(n.platform=i),a+=1;continue}if("--metro-host"===r&&void 0!==i){n.metroHost=i,a+=1;continue}if("--metro-port"===r&&void 0!==i){let e=e$(i);null!==e&&(n.metroPort=e),a+=1;continue}if("--bundle-url"===r&&void 0!==i){n.bundleUrl=i,a+=1;continue}if("--launch-url"===r&&void 0!==i){n.launchUrl=i,a+=1;continue}t.push(r)}return{positionals:t,flags:n}}function e$(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function eB(e){var t;let n=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}n.push(t)}let r=eL(n);return{positionals:r.positionals,flags:a,runtime:(t=r.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?r.flags:void 0}}function eq(e,t={}){let n=[e.command];if("snapshot"===e.command)e.flags?.snapshotInteractiveOnly&&n.push("-i"),"number"==typeof e.flags?.snapshotDepth&&n.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&n.push("-s",eP(e.flags.snapshotScope)),e.flags?.snapshotRaw&&n.push("--raw");else if("open"===e.command){for(let t of e.positionals??[])n.push(eP(t));e.flags?.relaunch&&n.push("--relaunch"),eC(n,e.runtime)}else if("runtime"===e.command)!function(e,t,n={}){let a=t.positionals??[];for(let t of n.includeAllPositionals?a:a.slice(0,1))e.push(e_(t,eO));eC(e,t.flags)}(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals});else if("record"===e.command)!function(e,t){let[n,...a]=t.positionals??[];for(let t of(n&&e.push(e_(n,eO)),a))e.push(eP(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.screenshotMaxSize&&e.push("--max-size",String(t.flags.screenshotMaxSize)),("number"==typeof t.flags?.quality||"string"==typeof t.flags?.quality)&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}(n,e);else if("screenshot"===e.command){for(let t of e.positionals??[])n.push(eP(t));m(n,e.flags)}else{for(let t of e.positionals??[])n.push(eP(t));eT(n,e)}return n.join(" ")}function eG(t,n){let a=e.createHash("sha256").update(t).digest(),r=e.createHash("sha256").update(n).digest();return e.timingSafeEqual(a,r)}let eX=["status","get","dismiss","enter","return"];function eY(e){return eX.includes(e)}function eF(e){let t=e?.trim().split(/\s+/,1)[0];if(!t||!t.startsWith("@")||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}class eK extends Error{}let ej=null,eH=!1,eV=!1,ez=0,eW=new Map;function eJ(e){eH=!0,eV||(eV=!0,P({level:"warn",phase:"png_worker_unavailable",data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function eZ(e){let t=eW.get(e.id);t&&(eW.delete(e.id),e1(),e.ok?t.resolve(e.result):t.reject(new D(_(e.error.code),e.error.message,e.error.details)))}function eQ(e,t){ej===e&&(eJ(t.message),ej=null,e.terminate().catch(()=>{}),e0(new eK(`PNG worker failed: ${t.message}`)))}function e0(e){let t=[...eW.values()];for(let n of(eW.clear(),t))n.reject(e)}function e1(){ej&&(eW.size>0?ej.ref():ej.unref())}function e2(){if(eH)return null;if(ej)return ej;let e=function(e,n){try{let r=i(e),s=a.extname(r)||".js";return[a.join(a.dirname(r),`${n}${s}`),a.join(a.dirname(r),"internal",`${n}${s}`)].find(e=>t.existsSync(e))??null}catch{return null}}(import.meta.url,"png-worker");if(!e)return eJ("worker entry module not found next to the current module"),null;try{let t=new r(e,{execArgv:e.endsWith(".ts")?["--experimental-strip-types"]:[]});return t.on("message",eZ),t.on("error",e=>{eQ(t,e)}),t.on("exit",e=>{eQ(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),ej=t,t}catch(e){return eJ(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}async function e4(e,t){try{return await function(e){let t=e2();if(!t)return Promise.reject(new eK("PNG worker is unavailable"));let n=ez+=1;return new Promise((a,r)=>{eW.set(n,{resolve:a,reject:r}),e1();try{t.postMessage({...e,id:n})}catch(e){eW.delete(n),e1(),r(new eK(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}(e)}catch(e){if(e instanceof eK)return t();throw e}}function e3(){e2()}async function e5(){let e=ej;ej=null,e0(new eK("PNG worker terminated")),e&&await e.terminate()}async function e8(e,t){let n=await e4({kind:"decode",png:e,label:t},()=>{let n=C(e,t);return{kind:"decode",width:n.width,height:n.height,data:n.data}});return new E({width:n.width,height:n.height,data:T(n.data)})}async function e6(e){return T((await e4({kind:"encode",width:e.width,height:e.height,data:e.data},()=>({kind:"encode",png:E.sync.write(e)}))).png)}async function e7(e){let{kind:t,...n}=await e4({kind:"diff-pixels",...e},()=>({kind:"diff-pixels",...O(e)}));return{...n,diffData:T(n.diffData)}}let e9=[0,187,255,255];function te(e,t,n,a){if(t<0||t>=e.width||n<0||n>=e.height)return;let r=(n*e.width+t)*4;e.data[r]=a[0],e.data[r+1]=a[1],e.data[r+2]=a[2],e.data[r+3]=a[3]}function tt(e,t,n){return Math.min(Math.max(e,t),n)}let tn=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function ta(e){let{mask:t,width:n,height:a,hooks:r}=e,i=new Uint8Array(t.length),s=new Int32Array(t.length),o=[];for(let e=0;e<t.length;e+=1){var l,d;if(!tr(t,i,e))continue;let u=0,c=(l=s,i[d=e]=1,l[0]=d,1),p=r.create(e);for(;u<c;){let e=s[u];u+=1,r.visit(p,e),c=function(e){let{mask:t,visited:n,queue:a,width:r,height:i,pixelIndex:s}=e,o=s%r,l=Math.floor(s/r),d=e.queueEnd;for(let e of tn){var u,c,p,h;let s=o+e.x,f=l+e.y;if(u=s,c=f,p=r,h=i,!(u>=0)||!(u<p)||!(c>=0)||!(c<h))continue;let m=f*r+s;tr(t,n,m)&&(d=function(e,t,n,a){return t[a]=1,e[n]=a,n+1}(a,n,d,m))}return d}({mask:t,visited:i,queue:s,queueEnd:c,width:n,height:a,pixelIndex:e})}o.push(p)}return o}function tr(e,t,n){return 1===e[n]&&1!==t[n]}let ti={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},ts={leading:20,trailing:20,separator:10,unknown:0,background:-30};function to(e){return"background"!==e.likelyKind}function tl(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function td(e,t){let n,a=0;for(let r of t){let t=tf(e,r.rect);t<=a||(a=t,n=r)}return n}function tu(e){let t=[];for(let n of[...e].sort((e,t)=>e.rect.y-t.rect.y)){let e=t.find(e=>{var t,a;return t=e.rect,tf(t,a=n.rect)>0||Math.abs(B(t).y-B(a).y)<=.5*Math.max(t.height,a.height)});if(!e){t.push({rect:n.rect,blocks:[n]});continue}e.blocks.push(n),e.blocks.sort((e,t)=>e.rect.x-t.rect.x),e.rect=$([e.rect,n.rect])}return t}function tc(e,t){let n,a=B(e);for(let e of t){let t=Math.sqrt(X(a,B(e.rect)));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tp(e){let t=th(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function th(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tf(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}async function tm(e){if(await Y("tesseract"))try{let[t,n]=await Promise.all([tg(e.baselinePath),tg(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tw(t.stdout,e.width,e.height),r=tw(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tA(i.text),s=function(e,t,n,a){let r=null,i=1/0;for(let s=0;s<n.length;s+=1){if(a.has(s))continue;let o=n[s];if(tA(o.text)!==t)continue;let l=B(e.normalizedRect),d=X(l,B(o.normalizedRect));d>=i||(r=s,i=d)}return r}(i,e,t,n);if(null===s)continue;n.add(s);let o=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},a=tI(t.rect.width/e.rect.width),r=tI(t.rect.height/e.rect.height),i=Math.abs(a-1)>=.08||Math.abs(r-1)>=.12;return{text:e.text,baselineRect:e.rect,currentRect:t.rect,delta:n,confidence:Math.round(100*Math.min(e.confidence,t.confidence))/100,possibleTextMetricMismatch:i}}(i,t[s]);r=o,(Math.abs(r.delta.x)>=2||Math.abs(r.delta.y)>=2||Math.abs(r.delta.width)>=2||Math.abs(r.delta.height)>=2||r.possibleTextMetricMismatch)&&a.push(o)}return a.sort((e,t)=>tb(t)-tb(e)).slice(0,12)}(a,r),s=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-tM(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(ty).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tk(t)-tk(e)).slice(0,4)}(i);if(0===a.length&&0===r.length)return;return{provider:"tesseract",baselineBlocks:a.length,currentBlocks:r.length,baselineBlocksRaw:a,currentBlocksRaw:r,matches:i,...s.length>0?{movementClusters:s}:{}}}catch{return}}function tw(e,t,n){let[a,...r]=e.split(/\r?\n/);if(!a)return[];let i=new Map(a.split(" ").map((e,t)=>[e,t])),s=[];for(let e of r){var o;if(!e.trim())continue;let t=e.split(" "),n=tx(t,i,"level"),a=tv(t,i,"text").trim(),r=tx(t,i,"conf");if(5!==n||(o=a,!/[\p{L}\p{N}]/u.test(o))||r<0)continue;let l=tx(t,i,"left"),d=tx(t,i,"top"),u=tx(t,i,"width"),c=tx(t,i,"height");u<=0||c<=0||s.push({key:[tv(t,i,"page_num"),tv(t,i,"block_num"),tv(t,i,"par_num"),tv(t,i,"line_num")].join(":"),text:a,confidence:r,rect:{x:l,y:d,width:u,height:c}})}let l=new Map;for(let e of s){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],a=[];for(let e of t){let t=a.at(-1);if(!t){a.push(e);continue}if(e.rect.x-(t.rect.x+t.rect.width)>Math.max(48,2.5*Math.max(t.rect.height,e.rect.height))){n.push(a),a=[e];continue}a.push(e)}return a.length>0&&n.push(a),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let a=[...e].sort((e,t)=>e.rect.x-t.rect.x),r=$(a.map(e=>e.rect)),i=Math.round(100*tM(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:G({x:tS(r.x/t),y:tS(r.y/n),width:tS(r.width/t),height:tS(r.height/n)})}})(e,t,n)).filter(e=>null!==e)}function tg(e){return F("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tb(e){return Math.abs(e.delta.x)+Math.abs(e.delta.y)+Math.abs(e.delta.width)+Math.abs(e.delta.height)+25*!!e.possibleTextMetricMismatch}function ty(e){let t=e.map(e=>e.delta.x),n=e.map(e=>e.delta.y);return{texts:e.map(e=>e.text),xRange:{min:Math.min(...t),max:Math.max(...t)},yRange:{min:Math.min(...n),max:Math.max(...n)}}}function tk(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tv(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tx(e,t,n){let a=Number(tv(e,t,n));return Number.isFinite(a)?a:0}function tA(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tM(e){return e.reduce((e,t)=>e+t,0)/e.length}function tS(e){return Math.round(100*e*100)/100}function tI(e){return Math.round(1e3*e)/1e3}function tR(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tP(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tN(e){return`#${t_(e.r)}${t_(e.g)}${t_(e.b)}`}function t_(e){return e.toString(16).padStart(2,"0")}function tD(e){return Math.round(100*e*100)/100}let tO=255*Math.sqrt(3);async function tE(e,t,r={}){var i,s,o,l,d;let u,c,p,h;await tT(e,"Baseline image not found"),await tT(t,"Current screenshot not found");let f=r.outputPath,[m,w]=await Promise.all([n.readFile(e),n.readFile(t)]),[g,b]=await Promise.all([e8(m,"baseline screenshot"),e8(w,"current screenshot")]);tC(g.width,g.height,"baseline screenshot",r.maxPixels),tC(b.width,b.height,"current screenshot",r.maxPixels);let y=r.threshold??.1;if(g.width!==b.width||g.height!==b.height){let e=g.width*g.height;return await tU(r.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:g.width,height:g.height},actual:{width:b.width,height:b.height}}}}let k=g.width*g.height,{diffData:v,diffMask:x,differentPixels:A}=await e7({width:g.width,height:g.height,baselineData:g.data,currentData:b.data,maxColorDistance:y*tO}),M=A>0?(s=(u=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n;return ta({mask:t,width:r,height:i,hooks:{create:e=>{var t,n;let a,i;return a=(t=e)%(n=r),{minX:a,minY:i=Math.floor(t/n),maxX:a,maxY:i,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}},visit:(e,t)=>{var i,s,o,l,d;let u,c,p;return i=e,s=t,o=r,l=n,d=a,u=s%o,c=Math.floor(s/o),p=4*s,void(i.minX=Math.min(i.minX,u),i.minY=Math.min(i.minY,c),i.maxX=Math.max(i.maxX,u),i.maxY=Math.max(i.maxY,c),i.differentPixels+=1,i.baselineRed+=l.data[p],i.baselineGreen+=l.data[p+1],i.baselineBlue+=l.data[p+2],i.currentRed+=d.data[p],i.currentGreen+=d.data[p+1],i.currentBlue+=d.data[p+2])}}})}(i={diffMask:x,baseline:g,current:b,totalPixels:k,differentPixels:A,maxRegions:r.maxRegions})).length<=2e3?function(e){let t=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return 0!==n?n:e.minX-t.minX})){var n,a;let e=t.find(e=>{var t,n,a;return t=e,n=r,a=12,t.minX-a<=n.maxX&&n.minX-a<=t.maxX&&t.minY-a<=n.maxY&&n.minY-a<=t.maxY});if(!e){t.push({...r});continue}n=e,a=r,n.minX=Math.min(n.minX,a.minX),n.minY=Math.min(n.minY,a.minY),n.maxX=Math.max(n.maxX,a.maxX),n.maxY=Math.max(n.maxY,a.maxY),n.differentPixels+=a.differentPixels,n.baselineRed+=a.baselineRed,n.baselineGreen+=a.baselineGreen,n.baselineBlue+=a.baselineBlue,n.currentRed+=a.currentRed,n.currentGreen+=a.currentGreen,n.currentBlue+=a.currentBlue}return t}(u):u,s.flatMap(e=>{var t,n,a;let r;return(t=e,n=i.baseline.width,a=i.baseline.height,r=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*a))&&r>=.35*n)?function(e,t,n){var a;let r=function(e,t){let n=[],a=null;for(let r=0;r<e.length;r+=1){if(e[r]<=t){a??=r;continue}null!==a&&(r-a>=6&&n.push([a,r-1]),a=null)}return null!==a&&e.length-a>=6&&n.push([a,e.length-1]),n}((a=function(e,t,n){let a=[];for(let r=e.minY;r<=e.maxY;r+=1){let i=0;for(let a=e.minX;a<=e.maxX;a+=1)1===t[r*n+a]&&(i+=1);a.push(i)}return a}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,r=0,i=Math.max(0,t-3),s=Math.min(a.length-1,t+3);for(let e=i;e<=s;e+=1)n+=a[e],r+=1;return Math.round(n/r)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),i=function(e,t,n){let a=[],r=e.minY;for(let[i,s]of t){let t=e.minY+Math.round((i+s)/2);t-r+1<n||e.maxY-t<n||(a.push([r,t]),r=t+1)}return a.push([r,e.maxY]),a}(e,r,n);if(i.length<=1)return[e];let s=i.map(([n,a])=>(function(e,t,n,a){let r=null;for(let o=t;o<=n;o+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,s;let e=o*a.baseline.width+t;1===a.diffMask[e]&&function(e,t,n,a,r,i){let s=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,a),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,a),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}(r??={minX:i=t,minY:s=o,maxX:i,maxY:s,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,o,a.baseline,a.current)}return r})(e,n,a,t)).filter(e=>null!==e);return s.length>1?s:[e]}(e,i,Math.max(24,Math.round(.03*i.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,i.maxRegions??8)).map((e,t)=>{var n,a,r,s,o,l,d,u,c,p,h;let f,m,w,g,b,y,k,v,x,A,M,S,I,R,P,N,_;return n=e,a=t+1,r={width:i.baseline.width,height:i.baseline.height,totalPixels:i.totalPixels,differentPixels:i.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},k={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tR(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),x=tR(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),A=y.width*y.height,M=tD(n.differentPixels/A),S=Math.round(tP(v)),I=Math.round(tP(x)),R=(s=y,o=r.width,l=r.height,s.width>=.55*o&&s.height>=.12*l?"large-area":s.width>=2.5*s.height?"horizontal-band":s.height>=2.5*s.width?"vertical-band":"compact"),P=(f=A/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",N=(d=v,u=x,m=tP(d),Math.abs(w=tP(u)-m)>=12?w>0?"brighter":"darker":Math.max(Math.abs(u.r-d.r),Math.abs(u.g-d.g),Math.abs(u.b-d.b))>=12?"color-shift":"mixed"),_=(c=k,p=r.width,h=r.height,g=c.x<p/3?"left":c.x>2*p/3?"right":"center",b=c.y<h/3?"top":c.y>2*h/3?"bottom":"middle","center"===g&&"middle"===b?"center":`${b}-${g}`),{index:a,rect:y,normalizedRect:G({x:tD(y.x/r.width),y:tD(y.y/r.height),width:tD(y.width/r.width),height:tD(y.height/r.height)}),differentPixels:n.differentPixels,shareOfDiffPercentage:tD(n.differentPixels/r.differentPixels),densityPercentage:M,shape:R,size:P,location:_,averageBaselineColorHex:tN(v),averageCurrentColorHex:tN(x),baselineLuminance:S,currentLuminance:I,dominantChange:N}}):[];if(A>0&&f){let e=new E({width:g.width,height:g.height,data:v});for(let t of M)t.rect.width<4||t.rect.height<4||function(e,t){let n=tt(t.x,0,e.width-1),a=tt(t.y,0,e.height-1),r=tt(t.x+t.width-1,0,e.width-1),i=tt(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let s=n;s<=r;s+=1)te(e,s,a+t,e9),te(e,s,i-t,e9);for(let s=a;s<=i;s+=1)te(e,n+t,s,e9),te(e,r-t,s,e9)}}(e,t.rect);await n.mkdir(a.dirname(f),{recursive:!0}),await n.writeFile(f,await e6(e))}else await tU(r.outputPath);let S=A>0?await tm({baselinePath:e,currentPath:t,width:g.width,height:g.height}):void 0,I=S&&(S.matches.length>0||(S.movementClusters?.length??0)>0)?{provider:S.provider,baselineBlocks:S.baselineBlocks,currentBlocks:S.currentBlocks,matches:S.matches,...S.movementClusters?{movementClusters:S.movementClusters}:{}}:void 0,R=A>0&&S?(c=function(e){let t=[];for(let n of e.sort((e,t)=>e.minY-t.minY||e.minX-t.minX)){let e=t.find(e=>{var t,a,r;return t=e,a=n,r=10,t.minX-r<=a.maxX&&a.minX-r<=t.maxX&&t.minY-r<=a.maxY&&a.minY-r<=t.maxY});if(!e){t.push({...n});continue}e.minX=Math.min(e.minX,n.minX),e.minY=Math.min(e.minY,n.minY),e.maxX=Math.max(e.maxX,n.maxX),e.maxY=Math.max(e.maxY,n.maxY),e.differentPixels+=n.differentPixels}return t}((l=function(e,t,n,a){let r=new Uint8Array(e);if(!a)return r;for(let e of[...a.baselineBlocksRaw,...a.currentBlocksRaw])!function(e,t,n,a){let r=q(Math.floor(a.x),0,t-1),i=q(Math.floor(a.y),0,n-1),s=q(Math.ceil(a.x+a.width),0,t),o=q(Math.ceil(a.y+a.height),0,n);for(let n=i;n<o;n+=1)for(let a=r;a<s;a+=1)e[n*t+a]=0}(r,t,n,U(e.rect,8));return r}((o={diffMask:x,width:g.width,height:g.height,regions:M,ocr:S}).diffMask,o.width,o.height,o.ocr),d=o.width,ta({mask:l,width:d,height:o.height,hooks:{create:e=>{var t,n;let a,r;return a=(t=e)%(n=d),{minX:a,minY:r=Math.floor(t/n),maxX:a,maxY:r,differentPixels:0}},visit:(e,t)=>{var n,a,r;let i,s;return n=e,i=(a=t)%(r=d),s=Math.floor(a/r),void(n.minX=Math.min(n.minX,i),n.minY=Math.min(n.minY,s),n.maxX=Math.max(n.maxX,i),n.maxY=Math.max(n.maxY,s),n.differentPixels+=1)}}}))),p=tu(o.ocr?.currentBlocksRaw??[]),h=tu(o.ocr?.baselineBlocksRaw??[]),c.filter(tp).map(e=>{var t,n,a,r,i,s,l,d,u,c,f;let m,w,g,b,y,k,v,x,A,M;return t=e,n=o,a=p,r=h,b=function(e,t){let n,a=0;for(let r of t){let t=L(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(g=th(t),n.regions),y=function(e,t,n){let a=td(e,t);if(a)return tc(e,a.blocks);let r=td(e,n);return r?tc(e,r.blocks):void 0}(g,a,r),k=function(e,t,n){if(e.height<=3&&e.width>=.12*n)return"separator";if(!t)return e.width>=.4*n?"background":"unknown";if(e.width>=.4*n)return"background";let a=e.x+e.width/2,r=t.x+t.width/2;return a<r-t.width/2?"leading":a>r+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(g,y?.block.rect,n.width),v=(i=g,s=k,l=t.differentPixels,d=n,m=i.width/i.height,w=l/(i.width*i.height),"separator"===s?"separator":"background"===s?"background":"trailing"===s&&m>=1.5&&m<=3.8&&w>=.35?"toggle":"trailing"===s&&i.width<=.06*d.width&&i.height<=.04*d.height?"chevron":"leading"===s&&m>=.55&&m<=1.8?"icon":tl(i,d)?"background":"visual"),x={...b?{regionIndex:b}:{},slot:k,likelyKind:v,rect:g},{...b?{regionIndex:b}:{},slot:k,likelyKind:v,rect:g,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(u=x,c=t.differentPixels,f=n,A=tl(u.rect,f)?-35:0,M=20*!!u.regionIndex,ti[u.likelyKind]+ts[u.slot]+M+A+Math.min(20,c/200))}}).filter(e=>e.rect.y>=.08*o.height).filter(to).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,o.maxDeltas??12)).map((e,t)=>{var n;return n=e,{index:t+1,...n.regionIndex?{regionIndex:n.regionIndex}:{},slot:n.slot,likelyKind:n.likelyKind,rect:n.rect,...n.nearestText?{nearestText:n.nearestText}:{}}})):[],P=k>0?Math.round(A/k*1e4)/100:0;return{...A>0&&f?{diffPath:f}:{},...M.length>0?{regions:M}:{},...I?{ocr:I}:{},...R.length>0?{nonTextDeltas:R}:{},totalPixels:k,differentPixels:A,mismatchPercentage:P,match:0===A}}async function tT(e,t){try{await n.access(e)}catch{throw new D("INVALID_ARGS",`${t}: ${e}`)}}function tC(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new D("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function tU(e){if(e)try{await n.unlink(e)}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tL(e){return e.width*e.height}function t$(e){return Math.round(100*e*100)/100}async function tB(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new D("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw N(e)}}async function tq(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new D("INVALID_ARGS","Local output paths are not allowed by command policy");try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??"client-visible",requestedClientPath:t?.kind==="downloadableArtifact"?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw N(e)}}async function tG(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw N(e)}}let tX=async(e,t)=>{let n,a,r;if(!t.baseline)throw new D("INVALID_ARGS","diff screenshot requires a baseline image");let i=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new D("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),s=t.current??{kind:"live"};if(t.overlayRefs&&!tz(s))throw new D("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let o=await tB(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=tz(s)?(a=await tY(e,t)).path:(n=await tB(e,s,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await tq(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tE(o.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});tz(s)&&(u=await tF(e,t,r?.path,u,l));let c=u.diffPath?await r?.publish():void 0;return c&&l.push(c),u.diffPath||await r?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await r?.cleanup?.(),e}finally{await o.cleanup?.(),await n?.cleanup?.(),await a?.cleanup?.()}};async function tY(e,t){let n=await tG(e,{prefix:"agent-device-diff-current",ext:".png"});try{await tK(e,t,n.path,tj(t))}catch(e){throw await n.cleanup(),e}return n}async function tF(e,t,n,a,r){var i,s,o,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await tV(n),a;let d=(i=t,s=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:tH(s??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:tH(i.out.clientPath)}:{},...i.out.fileName?{fileName:tH(i.out.fileName)}:{}}:void 0),u=await tq(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await tK(e,t,u.path,{overlayRefs:!0,...tj(t)}),i=await u.publish();return i&&r.push(i),{...a,currentOverlayPath:n.path??u.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...a.regions&&n.overlayRefs?{regions:(o=a.regions,l=n.overlayRefs,o.map(e=>{var t,n;let a,r=(t=e,n=l,a=tL(t.rect),n.map(e=>{let n=e.overlayRect,r=L(t.rect,n);return r<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:n,overlayCoveragePercentage:t$(r/tL(n)),regionCoveragePercentage:t$(r/a)}}).filter(e=>null!==e).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return 0!==n?n:t.overlayCoveragePercentage-e.overlayCoveragePercentage}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage})));return r.length>0?{...e,currentOverlayMatches:r}:e}))}:{}}}catch(e){throw await u.cleanup?.(),e}}async function tK(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new D("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,a)??{}}function tj(e){return e.surface?{surface:e.surface}:{}}function tH(e){let t=a.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function tV(e){try{await n.unlink(tH(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tz(e){return"live"===e.kind}async function tW(e,t){if(!Number.isInteger(t)||t<1)throw new D("INVALID_ARGS","Screenshot max size must be a positive integer");let a=await e8(await n.readFile(e),"screenshot"),r=Math.max(a.width,a.height);if(r<=t)return;let i=t/r,s=Math.max(1,Math.round(a.width*i)),o=Math.max(1,Math.round(a.height*i)),l=function(e,t,n){let a=new E({width:t,height:n});for(let r=0;r<n;r+=1){let i=r*e.height/n,s=(r+1)*e.height/n;for(let n=0;n<t;n+=1){let o=n*e.width/t,l=(n+1)*e.width/t,d=0,u=0,c=0,p=0,h=0;for(let t=Math.floor(i);t<Math.ceil(s);t+=1){let n=Math.min(t+1,s)-Math.max(t,i);for(let a=Math.floor(o);a<Math.ceil(l);a+=1){let r=n*(Math.min(a+1,l)-Math.max(a,o)),i=(t*e.width+a)*4;d+=(e.data[i]??0)*r,u+=(e.data[i+1]??0)*r,c+=(e.data[i+2]??0)*r,p+=(e.data[i+3]??0)*r,h+=r}}let f=(r*a.width+n)*4;a.data[f]=Math.round(d/h),a.data[f+1]=Math.round(u/h),a.data[f+2]=Math.round(c/h),a.data[f+3]=Math.round(p/h)}}return a}(a,s,o);await n.writeFile(e,await e6(l))}let tJ=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new D("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await tq(e,t.out,{field:"path",ext:".png"});try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},a.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,stabilize:t.stabilize,surface:t.surface}),void 0!==t.maxSize&&await tW(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...w(`Saved screenshot: ${a.path}`)}};function tZ(e,t){let n=j(e.type??"Element"),a=H(e,n),r=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",s=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,a,r,i,s].join("|")}function tQ(e,t){return t.flatten?e.map(e=>({text:K(e,0,!1),comparable:tZ(e,0)})):V(e).map(e=>({text:e.text,comparable:tZ(e.node,e.depth)}))}function t0(e,t){return e.get(t)??0}function t1(e){return e.map(e=>({index:e.index,depth:e.depth,parentIndex:e.parentIndex,type:e.type,role:e.role,subrole:e.subrole,label:e.label,value:e.value,identifier:e.identifier,enabled:e.enabled,selected:e.selected,focused:e.focused,hittable:e.hittable,rect:e.rect,bundleId:e.bundleId,appName:e.appName,windowTitle:e.windowTitle,surface:e.surface,hiddenContentAbove:e.hiddenContentAbove,hiddenContentBelow:e.hiddenContentBelow,interactionBlocked:e.interactionBlocked,presentationHints:e.presentationHints}))}let t2=async(e,t)=>{var n;let a,r,i=await t3(e,t),s=function(e){var t,n,a,r,i;let{previous:s,current:o,options:l,identity:d}=e;if(!0===l.forceFull||!0===l.raw||!s||!1===s.comparisonSafe||!1===o.comparisonSafe||(t=s,n=o,a=d,t.backend&&n.backend&&t.backend!==n.backend||a?.previousAppBundleId&&a.currentAppBundleId&&a.previousAppBundleId!==a.currentAppBundleId)||!s.presentationKey||s.presentationKey!==o.presentationKey||(r=s,i=o,r.truncated!==i.truncated||JSON.stringify(t1(r.nodes))!==JSON.stringify(t1(i.nodes))))return;let u=l.scope?.trim();return{ageMs:Math.max(0,o.createdAt-s.createdAt),nodeCount:o.nodes.length,...!0===l.interactiveOnly?{interactiveOnly:!0}:{},...u?{scope:u}:{}}}({previous:i.session?.snapshot,current:i.snapshot,options:t,identity:{previousAppBundleId:i.session?.appBundleId,currentAppBundleId:i.result.appBundleId??i.session?.appBundleId}});return await e.sessions.set(t5(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){let{nodes:t,backend:n,snapshotRaw:a}=e;if(a||!Z(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let r=o(t),i=new Set;return r.hiddenCount>0&&i.add("offscreen-nodes"),r.nodes.some(e=>e.hiddenContentAbove)&&i.add("scroll-hidden-above"),r.nodes.some(e=>e.hiddenContentBelow)&&i.add("scroll-hidden-below"),{partial:i.size>0,visibleNodeCount:r.nodes.length,totalNodeCount:t.length,reasons:[...i]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...p({...i.annotations,warnings:i.warnings}),...s?{unchanged:s}:{},...i.result.snapshotDiagnostics?{snapshotDiagnostics:i.result.snapshotDiagnostics}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},t4=async(e,t)=>{let n=await t3(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=t5(t.session,n);if(!r){let t=function(e,t={}){return tQ(e,t).length}(n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let s=function(e,t,n={}){let a=function(e,t){let n=e.length,a=t.length,r=n+a,i=new Map,s=[];i.set(1,0);for(let o=0;o<=r;o+=1){s.push(new Map(i));for(let r=-o;r<=o;r+=2){let l=r===-o||r!==o&&t0(i,r-1)<t0(i,r+1)?t0(i,r+1):t0(i,r-1)+1,d=l-r;for(;l<n&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(r,l),l>=n&&d>=a)return function(e,t,n,a,r){let i=[],s=a,o=r;for(let a=e.length-1;a>=0;a-=1){let r=e[a],l=s-o,d=l===-a||l!==a&&t0(r,l-1)<t0(r,l+1)?l+1:l-1,u=t0(r,d),c=u-d;for(;s>u&&o>c;)i.push({kind:"unchanged",text:n[o-1].text}),s-=1,o-=1;if(0===a)break;s===u?(i.push({kind:"added",text:n[c].text}),o=c):(i.push({kind:"removed",text:t[u].text}),s=u)}return i.reverse(),i}(s,e,t,n,a)}}return[]}(tQ(e,n),tQ(t,n)),r={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(r.additions+=1),"removed"===e.kind&&(r.removals+=1),"unchanged"===e.kind&&(r.unchanged+=1);return{summary:r,lines:a}}(r.nodes,n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!1,summary:s.summary,lines:s.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function t3(e,t){var n,a,r,i,s,o,l;let u,c,p,h,f;if(!e.backend.captureSnapshot)throw new D("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let m=t.session??"default",w=await e.sessions.get(m),g=await e.backend.captureSnapshot({session:m,requestId:t.requestId,appId:w?.appId,appBundleId:w?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,depth:t.depth,scope:t.scope,raw:t.raw}),b=(a=g,r=e,n=a.snapshot?a.snapshot:{nodes:a.nodes??[],truncated:a.truncated,backend:a.backend,createdAt:d(r)},n.presentationKey?n:{...n,presentationKey:J(t)}),y=A(g),k=d(e);return{snapshot:b,result:g,session:w,annotations:y,warnings:(u=[...(i={result:g,annotations:y,snapshot:b,options:t,session:w,capturedAt:b.createdAt??k,runtimeNow:k}).annotations.warnings??[]],i.annotations.quality&&u.push(...R(i.annotations.quality,i.snapshot.nodes)),u.push(...function(e){let t=e.annotations.analysis;if("android"!==e.snapshot.backend||!0!==e.options.interactiveOnly||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return"number"==typeof e.options.depth&&"number"==typeof t.maxDepth&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}(i)),i.annotations.quality||(u.push(...function(e){if("xctest"!==e.snapshot.backend||!0!==e.options.interactiveOnly||1!==e.snapshot.nodes.length)return[];let t=e.snapshot.nodes[0];return t?.type!=="Application"?[]:["iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known."]}(i)),u.push(...(c=new Set((s=i.snapshot.nodes).map(e=>e.parentIndex).filter(e=>void 0!==e)),s.filter(e=>!(c.has(e.index)||(e.type?.toLowerCase()??"").includes("text"))&&(e.label??"").split(", ").length>10).map(e=>{let t=(e.label??"").split(", ").length,n=e.identifier?` (${e.identifier})`:"";return`@${e.ref} [${e.type??"element"}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})))),(p=function(e){if(e?.backend!=="uiautomator-dump")return;let t=e.fallbackReason?` Reason: ${e.fallbackReason}`:"";return`Android snapshot helper unavailable; using stock UIAutomator dump, which can time out on busy React Native UIs.${t}`}(i.annotations.androidSnapshot))&&u.push(p),(h=S(i.snapshot.nodes))&&u.push(h),(f=function(e){var t,n,a,r,i,s;let o=e.session?.snapshot;if(!e.annotations.freshness&&o&&(t=o,n=e.snapshot,void 0===t.presentationKey||void 0===n.presentationKey||t.presentationKey===n.presentationKey)&&(a=o,r=e.capturedAt,[r,e.runtimeNow].some(e=>{let t=e-a.createdAt;return t>=0&&t<=2e3}))&&(i=o.nodes.length,s=e.snapshot.nodes.length,!(i<12)&&s<=Math.floor(.2*i)))return t8}(i))&&u.push(f),u.push(...(o=i.annotations.freshness,l=i.snapshot.backend,o?.staleAfterRetries&&"android"===l?"stuck-route"===o.reason?[`Recent ${o.action} was followed by a nearly identical snapshot after ${o.retryCount} automatic retr${1===o.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`]:"sharp-drop"===o.reason?[t8]:[]:[])),Array.from(new Set(u)))}}function t5(e,t){let n=t.session?.name??e??"default";return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}let t8="Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.",t6=async(e,t)=>await nt(e,t,"press"),t7=async(e,t)=>await nt(e,t,"click"),t9=async(e,t)=>{var n;if(!t.text)throw new D("INVALID_ARGS","fill requires text");let a=await nr(e,t);if(a)return a;let r=await v(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new D("UNSUPPORTED_OPERATION","fill is not supported by this backend");let i=nn(r),s=b(await e.backend.fill(x(e,t),i,t.text,{delayMs:t.delayMs})),o="node"in r?r.node?.type??"":"",l=o&&!eh(o,e.backend.platform)?`fill target ${n=r,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${o}", attempting fill anyway.`:void 0;return{...r,text:t.text,...l?{warning:l}:{},...s?{backendResult:s}:{}}},ne=async(e,t)=>{let n=t.text;if(!n)throw new D("INVALID_ARGS","type requires text");let a=eF(n);if(a)throw new D("INVALID_ARGS",`type does not accept a target ref like "${a}"`,{hint:`Use fill ${a} "text" to target that field, or press ${a} then type "text" to append.`});if(!e.backend.typeText)throw new D("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=M(t.delayMs??0,"delay-ms",0,1e4),i=b(await e.backend.typeText(x(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...w(`Typed ${Array.from(n).length} chars`)}};async function nt(e,t,n){let a=await na(e,t,n);if(a)return a;let r=await v(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new D("UNSUPPORTED_OPERATION","tap is not supported by this backend");let i=nn(r),s=b(await e.backend.tap(x(e,t),i,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...r,...s?{backendResult:s}:{}}}function nn(e){if(!e.point)throw new D("COMMAND_FAILED","Interaction target resolved without coordinates");return e.point}async function na(e,t,n){var a;if("click"!==n||"ref"!==t.target.kind||!e.backend.tapTarget||void 0!==(a=t).count||void 0!==a.intervalMs||void 0!==a.holdMs||void 0!==a.jitterPx||void 0!==a.doubleTap||void 0!==a.button&&"primary"!==a.button)return null;let r=b(await e.backend.tapTarget(x(e,t),{kind:"ref",ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}}));return{kind:"ref",target:{kind:"ref",ref:t.target.ref},...r?{backendResult:r}:{}}}async function nr(e,t){if("ref"!==t.target.kind||!e.backend.fillTarget)return null;let n=b(await e.backend.fillTarget(x(e,t),{kind:"ref",ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}},t.text,{delayMs:t.delayMs}));return{kind:"ref",target:{kind:"ref",ref:t.target.ref},text:t.text,...n?{backendResult:n}:{}}}function ni(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function ns(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,s=Q(n),o=er(n,i),l=!0===n.selected,d="text"===t?en(n):function(e,t,n){var a,r,i;let s;if("android"===n&&!1===e.visibleToUser)return!1;if(no(e.rect))return function(e,t){return u(e,t)}(e,t);if(e.rect)return!1;if("android"!==n&&!0===e.hittable)return!0;let o=(a=e,r=t,i=n,s=ea(r),ee(r,a,s,e=>!function(e,t){if("android"===t&&!1===e.visibleToUser)return!1;let n=ep(e.type??"");return!(n.includes("application")||n.includes("window")||n.includes("scrollview")||n.includes("tableview")||n.includes("collectionview"))&&"table"!==n&&"list"!==n&&"listview"!==n&&("android"===t?!0===e.hittable&&no(e.rect):!0===e.hittable||no(e.rect))}(e,i)?null:e));return!!o&&(no(o.rect)?function(e,t){return u(e,t)}(o,t):"android"!==n&&!0===o.hittable)}(n,a,i),c=!1;switch(t){case"visible":c=d;break;case"hidden":c=!d;break;case"editable":c=o;break;case"selected":c=l;break;case"text":c=s===(r??"")}let p="text"===t?`expected="${r??""}" actual="${s}"`:`actual=${JSON.stringify({visible:d,editable:o,selected:l})}`;return{pass:c,actualText:s,details:p}}function no(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function nl(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new D("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new D("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function nd(e,t,n={updateSession:!0}){let a=e.backend.captureSnapshot;if(!a)throw new D("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",i=await e.sessions.get(r),s=await a(x(e,t),{interactiveOnly:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw,includeRects:n.includeRects}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,...s.quality?{snapshotQuality:s.quality}:{},createdAt:d(e)};return n.updateSession&&i&&!l(o.snapshotQuality)&&await e.sessions.set({...i,snapshot:o}),{sessionName:r,session:i,snapshot:o}}async function nu(e,t,n){if(e.backend.readText){let a=await e.backend.readText(x(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return eu(n)}let nc=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new D("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nk(e,t,n);let{capture:a,match:r}=await nv(e,t,n);if(!r)throw new D("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let i=`@${r.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:i,node:r}:{kind:"text",ref:i,text:await nu(e,a,r),node:r}},np=async(e,t)=>{if("ref"===t.target.kind){let n=await nl(e,t.session),a=function(e,t,n){let a=z(t);if(!a)throw new D("INVALID_ARGS",n.invalidRefMessage);let r=W(e,a)??(n.fallbackLabel.length>0?el(e,n.fallbackLabel):null);if(!r)throw new D("COMMAND_FAILED",n.notFoundMessage);return{ref:a,node:r}}(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??"",invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${t.target.ref} not found`}),r=es(a.node,e.backend.platform,{action:"get"}),i={kind:"ref",ref:`@${a.ref}`};return"attrs"===t.property?{kind:"attrs",target:i,node:a.node,selectorChain:r}:{kind:"text",target:i,text:await nu(e,n,a.node),node:a.node,selectorChain:r}}let n=await nS(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=es(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:a};let r=await nu(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},nh=async(e,t)=>{let n=await np(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new D("COMMAND_FAILED","getText returned non-text result");return n},nf=async(e,t)=>{let n=await np(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new D("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nm=async(e,t)=>{var n;if(!ni(t.predicate))throw new D("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new D("INVALID_ARGS","is text requires expected text value");let a="visible"===(n=t.predicate)||"hidden"===n,r=await nd(e,t,{updateSession:!0,includeRects:a}),i=et(t.selector);if("exists"===t.predicate){let n=ei(r.snapshot.nodes,i,{platform:e.backend.platform});if(!n)throw new D("COMMAND_FAILED",ec(i,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:n.selector.raw,matches:n.matches,selectorChain:i.selectors.map(e=>e.raw)}}let s=eo(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!s)throw new D("COMMAND_FAILED",ec(i,[],{unique:!0}),{command:"is",reason:"selector_not_found",predicate:t.predicate,selector:i.raw});let o=ns({predicate:t.predicate,node:s.node,nodes:r.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!o.pass)throw new D("COMMAND_FAILED",`is ${t.predicate} failed for selector ${s.selector.raw}: ${o.details}`,{command:"is",reason:"predicate_failed",predicate:t.predicate,selector:s.selector.raw,predicateDetails:o.details});return{predicate:t.predicate,pass:!0,selector:s.selector.raw,..."text"===t.predicate?{text:o.actualText}:{},selectorChain:i.selectors.map(e=>e.raw)}},nw=async(e,t)=>await nm(e,{...t,predicate:"visible",selector:t.target.selector}),ng=async(e,t)=>await nm(e,{...t,predicate:"hidden",selector:t.target.selector}),nb=async(e,t)=>{if("sleep"===t.target.kind)return await c(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await nl(e,t.session),a=z(t.target.ref);if(!a)throw new D("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=W(n.snapshot.nodes,a),i=r?ed(r,n.snapshot.nodes):void 0;if(!i)throw new D("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await nA(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nx(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new D("INVALID_ARGS","wait requires text");return await nA(e,t,t.target.text,t.target.timeoutMs)},ny=async(e,t)=>{let n=await nb(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new D("COMMAND_FAILED","waitForText returned non-text result");return n};async function nk(e,t,n){let a=t.timeoutMs??1e4,r=d(e);for(;d(e)-r<a;){let{match:a}=await nv(e,t,n);if(a)return{kind:"found",found:!0,waitedMs:d(e)-r};await c(e,300)}throw new D("COMMAND_FAILED","find wait timed out")}async function nv(e,t,n){let a=await nd(e,t,{updateSession:!0,scope:"text"===n||"label"===n||"any"===n?t.query:void 0});if(l(a.snapshot.snapshotQuality))throw new D("COMMAND_FAILED","find could not read the current accessibility tree",{reason:a.snapshot.snapshotQuality.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen."});let r=ef(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];return{capture:a,match:r}}async function nx(e,t,n,a){let r=a??1e4,i=d(e),s=et(n);for(;d(e)-i<r;){let n=ei((await nd(e,t,{updateSession:!0})).snapshot.nodes,s,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:d(e)-i};await c(e,300)}throw new D("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nA(e,t,n,a){let r=a??1e4,i=d(e);for(;d(e)-i<r;){if(e.backend.findText?(await e.backend.findText(x(e,t),n)).found:await nM(e,t,n))return{kind:"text",text:n,waitedMs:d(e)-i};await c(e,300)}throw new D("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nM(e,t,n){return!!el((await nd(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nS(e,t,n,a){let r=await nd(e,{...t,session:n},{updateSession:!0}),i=et(a.selector),s=eo(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!s)throw new D("COMMAND_FAILED",ec(i,[],{unique:!0}));return{capture:r,node:s.node,selector:s.selector.raw,ref:`@${s.node.ref}`}}function nI(e,t){if(void 0!==e)return nR(e,t)}function nR(e,t){let n=e?.trim();if(!n)throw new D("INVALID_ARGS",`${t} must be a non-empty string`);return n}let nP=async(e,t={})=>{if(!e.backend.listDevices)throw new D("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(x(e,t),t.filter)}},nN=async(e,t={})=>{if(!e.backend.bootDevice)throw new D("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=n$(t.target),a=b(await e.backend.bootDevice(x(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...w("Booted device")}},n_=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new D("UNSUPPORTED_OPERATION","admin.shutdown is not supported by this backend");let n=n$(t.target),a=b(await e.backend.shutdownDevice(x(e,t),n));return{kind:"deviceShutdown",...n?{target:n}:{},...a?{backendResult:a}:{},...w("Shutdown device")}},nD=async(e,t)=>await nT(e,t,"install"),nO=async(e,t)=>await nT(e,t,"reinstall"),nE=async(e,t)=>await nT(e,t,"installFromSource");async function nT(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new D("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?nR(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new D("INVALID_ARGS",`admin.${n} requires app`);let s=x(e,t),o=await nC(e,s,t.source);try{var l,d,u,c,p;let t,a,h,f,m,g,y,k,v=await r.call(e.backend,s,{...i?{app:i}:{},source:o.source});return l=n,d=i,u=o.source,c=v,t=b(c),a=nB(c,"appName"),h=nB(c,"appId"),f=nB(c,"bundleId"),m=nB(c,"packageName"),g=nB(c,"launchTarget"),y=nB(c,"installablePath"),k=nB(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...h?{appId:h}:{},...a?{appName:a}:{},...f?{bundleId:f}:{},...m?{packageName:m}:{},...g?{launchTarget:g}:{},...y?{installablePath:y}:{},...k?{archivePath:k}:{},...t?{backendResult:t}:{},...w(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??g??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await o.cleanup?.()}}async function nC(e,t,n){let a=nL(n),r=await nU(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nL(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function nU(e,t){if("url"===t.kind)return{source:t};let n=await tB(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nL(e){if(!e||"object"!=typeof e)throw new D("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nR(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nR(e.id,"source.id")};if("url"===e.kind){let t=nR(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new D("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new D("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new D("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function n$(e){if(!e)return;let t=nI(e.id,"target.id"),n=nI(e.name,"target.name"),a={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...void 0!==e.headless?{headless:e.headless}:{}};return Object.keys(a).length>0?a:void 0}function nB(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}let nq=/^[A-Za-z0-9_.:-]{1,64}$/,nG=async(e,t)=>{var n;if(!e.backend.openApp)throw new D("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=nI(e.app,"app"),a=nI(e.appId,"appId"),r=nI(e.bundleId,"bundleId"),i=nI(e.packageName,"packageName"),s=nI(e.url,"url"),o=nI(e.activity,"activity"),l={...n?{app:n}:{},...a?{appId:a}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...s?{url:s}:{},...o?{activity:o}:{}};if(!((t=l).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new D("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=b(await e.backend.openApp(nz(e,t),a,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...w(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},nX=async(e,t={})=>{if(!e.backend.closeApp)throw new D("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nI(t.app,"app"),a=b(await e.backend.closeApp(nz(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...w(n?`Closed: ${n}`:"Closed app")}},nY=async(e,t={})=>{if(!e.backend.listApps)throw new D("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nz(e,t),ey(t.filter))}},nF=async(e,t)=>{if(!e.backend.getAppState)throw new D("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nR(t.app,"app"),a=await e.backend.getAppState(nz(e,t),n);return{kind:"appState",app:n,state:a}},nK=async(e,t)=>{if(!e.backend.pushFile)throw new D("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nR(t.app,"app"),a=await nH(e,t.input);try{let r=await e.backend.pushFile(nz(e,t),a.backendInput,n),i=b(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...w(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},nj=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new D("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nR(e,"name");if(!nq.test(t))throw new D("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,a=`apps.triggerEvent payload for "${r}"`,void 0!==n&&nV(n,a,8192);let i=b(await e.backend.triggerAppEvent(nz(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...w(`Triggered app event: ${r}`)}};async function nH(e,t){if(!t||"object"!=typeof t)throw new D("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nV(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await tB(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nV(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new D("INVALID_ARGS",`${t} must be a JSON object`)}(e,t),Buffer.byteLength(function(e,t){try{let n=JSON.stringify(e);if("string"!=typeof n)throw new D("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new D("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new D("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nz(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}let nW=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,nJ=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function nZ(e){var t,n;let a=!1,r=e;return{value:(t=r=(r=(r=(r=(r=r.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(a=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,r)=>(a=!0,`${String(t)}[REDACTED]${String(r)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(nJ,()=>(a=!0,"[REDACTED]")),n=()=>{a=!0},r=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=nQ(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function nQ(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))nW.test(n)&&(e.searchParams.set(n,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",n=!0),{value:t.toString(),redacted:n}}catch{return}}let n0=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function n1(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(n0.test(a))n[a]="[REDACTED]",t=!0;else{let e=n5(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function n2(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=n3(t,nZ);return n8(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??n5(e,2048)}function n4(e){return n3(e,e=>n5(e,2048))}function n3(e,t){if(void 0===e)return{redacted:!1};if("string"==typeof e)return t(e);if(!e||"object"!=typeof e)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let a=n3(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(n0.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=n3(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function n5(e,t){if(void 0===e)return{redacted:!1};let n=nZ(e);return n8(n.value,t,n.redacted)}function n8(e,t,n){if(void 0===e)return{redacted:n};let a=e;return a.length>t&&(a=`${a.slice(0,t)}...[truncated]`,n=!0),{value:a,redacted:n}}let n6=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new D("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await ae(e,t),{...at(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:aa(a.levels,"levels")}:{},...void 0!==a.search?{search:nR(a.search,"search")}:{},...void 0!==a.source?{source:nR(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=n5(e.message,4096),n=n4(e.metadata);return r||=t.redacted||n.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:t.value??"",...e.source?{source:e.source}:{},...n.value?{metadata:n.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}},n7=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new D("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let s={...at(r=t,25,200,"network limit"),include:function(e){if(void 0===e)return"summary";if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new D("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await ae(e,t),s),a=s.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?nQ(t=e.url)??n5(t,2048):void 0,r="headers"===a||"all"===a?n1(e.requestHeaders):void 0,s="headers"===a||"all"===a?n1(e.responseHeaders):void 0,o="body"===a||"all"===a?n2(e.requestBody):void 0,l="body"===a||"all"===a?n2(e.responseBody):void 0,d=n4(e.metadata);return i||=(n?.redacted??!1)||(r?.redacted??!1)||(s?.redacted??!1)||(o?.redacted??!1)||(l?.redacted??!1)||d.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...n?{url:n.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...r?.value?{requestHeaders:r.value}:{},...s?.value?{responseHeaders:s.value}:{},...o?.value!==void 0?{requestBody:o.value}:{},...l?.value!==void 0?{responseBody:l.value}:{},...d.value?{metadata:d.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:i,...n.notes?{notes:n.notes}:{}}},n9=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new D("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await ae(e,t),{...an(a=t),...void 0!==a.sampleMs?{sampleMs:M(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:aa(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=n5(e.message,4096),n=n4(e.metadata);return r||=t.redacted||n.redacted,{name:e.name,...void 0!==e.value?{value:e.value}:{},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...void 0!==t.value?{message:t.value}:{},...n.value?{metadata:n.value}:{}}}),...n.startedAt?{startedAt:n.startedAt}:{},...n.endedAt?{endedAt:n.endedAt}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}};async function ae(e,t){let n=x(e,t),a=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??a?.appId?{appId:t.appId??a?.appId}:{},...t.appBundleId??a?.appBundleId?{appBundleId:t.appBundleId??a?.appBundleId}:{}}}function at(e,t,n,a){return{...an(e),...void 0!==e.cursor?{cursor:nR(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:M(e.limit,a,1,n)}}function an(e){return{...void 0!==e.since?{since:nR(e.since,"since")}:{},...void 0!==e.until?{until:nR(e.until,"until")}:{}}}function aa(e,t,n=50){if(!Array.isArray(e))throw new D("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new D("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>nR(e,`${t}[${n}]`))}let ar=async(e,t)=>{let n=as(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new D("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await tq(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,s,o,l,d,u,c;let p,h,f,m,w=(i=t,s=r?.path,p={},s&&(p.outPath=s),h=(o=i.fps,void 0===o?void 0:M(o,"fps",1,60)),void 0!==h&&(p.fps=h),f=(l=i.maxSize,void 0===l?void 0:M(l,"maxSize",1,Number.MAX_SAFE_INTEGER)),void 0!==f&&(p.maxSize=f),m=function(e){if(void 0===e)return;let t=k(e);if(void 0===t)throw new D("INVALID_ARGS","quality must be one of: medium, high (legacy numeric values 5-10 are accepted)");return t}(i.quality),void 0!==m&&(p.quality=m),void 0!==i.hideTouches&&(p.showTouches=!0!==i.hideTouches),p),g=await a.call(e.backend,x(e,t),w),b=await r?.publish();return d=n,u=g,c=b,{..."string"==typeof u.path?{path:u.path}:{},..."string"==typeof u.telemetryPath?{telemetryPath:u.telemetryPath}:{},..."string"==typeof u.warning?{warning:u.warning}:{},...ao(d,u,c,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},ai=async(e,t)=>{let n=as(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new D("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await tq(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var i,s,o;let l={...r?.path?{outPath:r.path}:{}},d=await a.call(e.backend,x(e,t),l),u=await r?.publish();return i=n,s=d,o=u,{..."string"==typeof s.outPath?{outPath:s.outPath}:{},...ao(i,s,o,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}};function as(e,t){if("start"===e||"stop"===e)return e;throw new D("INVALID_ARGS",`${t} action must be start or stop`)}function ao(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...w("start"===e?a.startMessage:a.stopMessage)}}let al=async(e,t={})=>{if(!e.backend.pressBack)throw new D("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new D("INVALID_ARGS","system.back mode must be in-app or system");let a=b(await e.backend.pressBack(x(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...w("Back")}},ad=async(e,t={})=>{if(!e.backend.pressHome)throw new D("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=b(await e.backend.pressHome(x(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...w("Home")}},au=async(e,t)=>{if(!e.backend.rotate)throw new D("UNSUPPORTED_OPERATION","system.rotate is not supported by this backend");let n=function(e){switch(e){case"portrait":case"portrait-upside-down":case"landscape-left":case"landscape-right":return e;default:throw new D("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=b(await e.backend.rotate(x(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...w(`Rotated to ${n}`)}},ac=async(e,t={})=>{var n,a,r,i,s,o,l;if(!e.backend.setKeyboard)throw new D("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let d=t.action??"status";if(!eY(d))throw new D("INVALID_ARGS","system.keyboard action must be status, get, dismiss, enter, or return");let u=await e.backend.setKeyboard(x(e,t),{action:d}),c=b(u),p=(n=u)&&"object"==typeof n?u:{};return"enter"===d||"return"===d?{kind:"keyboardEnterPressed",action:"enter",state:p,...(a=c)?{backendResult:a}:{},...w("Keyboard enter pressed")}:"dismiss"===d?(r=d,{kind:"keyboardDismissed",action:r,state:i=p,...(s=c)?{backendResult:s}:{},...w(!1===i.dismissed?"Keyboard already hidden":"Keyboard dismissed")}):(o=d,{kind:"keyboardState",action:o,state:p,...(l=c)?{backendResult:l}:{}})},ap=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new D("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(x(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new D("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new D("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new D("INVALID_ARGS","system.clipboard write requires text");let n=b(await e.backend.setClipboard(x(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...w("Clipboard updated")}},ah=async(e,t={})=>{if(!e.backend.openSettings)throw new D("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=nI(t.target,"target"),a=b(await e.backend.openSettings(x(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...w(n?`Opened settings: ${n}`:"Opened settings")}},af=async(e,t={})=>{var n,a;if(!e.backend.handleAlert)throw new D("UNSUPPORTED_OPERATION","system.alert is not supported by this backend");let r=t.action??"get";if("get"!==r&&"accept"!==r&&"dismiss"!==r&&"wait"!==r)throw new D("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let i=void 0===t.timeoutMs?void 0:M(t.timeoutMs,"timeoutMs",0,12e4),s=await e.backend.handleAlert(x(e,t),r,{timeoutMs:i});return n=r,a=s,"get"===n?function(e){if("alertStatus"!==e.kind)throw new D("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:"get",alert:e.alert}}(a):"wait"===n?function(e){if("alertWait"!==e.kind)throw new D("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:"wait",alert:e.alert,...void 0!==e.waitedMs?{waitedMs:e.waitedMs}:{},...void 0!==e.timedOut?{timedOut:e.timedOut}:{},...w(e.alert?"Alert visible":"Alert wait timed out")}}(a):function(e,t){if("alertHandled"!==t.kind)throw new D("COMMAND_FAILED",`system.alert ${e} returned an invalid backend result`);return{kind:"alertHandled",action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...w(t.handled?`Alert ${e}ed`:"No alert handled")}}(n,a)},am=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new D("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=b(await e.backend.openAppSwitcher(x(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...w("Opened app switcher")}};function aw(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,ag(e)]));return{get:e=>ag(t.get(e)),set:e=>{t.set(e.name,ag(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>ag(e))}}(),policy:e.policy??function(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,capture:{screenshot:e=>tJ(t,e),diffScreenshot:e=>tX(t,e),snapshot:e=>t2(t,e),diffSnapshot:e=>t4(t,e)},selectors:{find:e=>nc(t,e),get:e=>np(t,e),getText:(e,n={})=>nh(t,{...n,target:e}),getAttrs:(e,n={})=>nf(t,{...n,target:e}),is:e=>nm(t,e),isVisible:(e,n={})=>nw(t,{...n,target:e}),isHidden:(e,n={})=>ng(t,{...n,target:e}),wait:e=>nb(t,e),waitForText:(e,n={})=>ny(t,{...n,text:e})},interactions:{click:(e,n={})=>t7(t,{...n,target:e}),press:(e,n={})=>t6(t,{...n,target:e}),fill:(e,n,a={})=>t9(t,{...a,target:e,text:n}),typeText:(e,n={})=>ne(t,{...n,text:e}),focus:(e,n={})=>g(t,{...n,target:e}),longPress:(e,n={})=>f(t,{...n,target:e}),swipe:e=>y(t,e),scroll:e=>h(t,e),pinch:e=>I(t,e)},system:{back:e=>al(t,e),home:e=>ad(t,e),rotate:e=>au(t,e),keyboard:e=>ac(t,e),clipboard:e=>ap(t,e),settings:e=>ah(t,e),alert:e=>af(t,e),appSwitcher:e=>am(t,e)},apps:{open:e=>nG(t,e),close:e=>nX(t,e),list:(e={})=>nY(t,{...e,filter:eb(e.filter)}),state:e=>nF(t,e),push:e=>nK(t,e),triggerEvent:e=>nj(t,e)},admin:{devices:e=>nP(t,e),boot:e=>nN(t,e),shutdown:e=>n_(t,e),install:e=>nD(t,e),reinstall:e=>nO(t,e),installFromSource:e=>nE(t,e)},recording:{record:e=>ar(t,e),trace:e=>ai(t,e)},observability:{logs:e=>n6(t,e),network:e=>n7(t,e),perf:e=>n9(t,e)}}}function ag(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function ab(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}async function ay(e){let{lockDirPath:n,owner:r}=e,i=a.join(n,"owner.json"),s=Date.now()+(e.timeoutMs??3e4),o=e.pollMs??100,l=e.ownerGraceMs??5e3,d=e.description??"process lock";for(t.mkdirSync(a.dirname(n),{recursive:!0});Date.now()<s;)try{t.mkdirSync(n),function(e,n){let a=`${e}.${process.pid}.${Date.now()}.tmp`;t.writeFileSync(a,JSON.stringify(n),"utf8"),t.renameSync(a,e)}(i,r);let e=!1;return async()=>{e||(e=!0,t.rmSync(n,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,n,a){let r=null;try{r=t.statSync(e)}catch{return!0}let i=ak(n);if(i){var s;return!(Number.isInteger((s=i).pid)&&!(s.pid<=0)&&em(s.pid)&&(!s.startTime||ew(s.pid)===s.startTime))&&(t.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-r.mtimeMs<a)&&(t.rmSync(e,{recursive:!0,force:!0}),!0)}(n,i,l))continue;await eg(o)}throw new D("COMMAND_FAILED",`Timed out waiting for ${d}`,{lockDirPath:n,...function(e,n){let a,r=Date.now(),i=ak(n);try{a=Math.max(0,Math.round(r-t.statSync(e).mtimeMs))}catch{}return{...void 0!==a?{lockAgeMs:a}:{},...i?{ownerPid:i.pid,ownerStartTime:i.startTime,ownerAgeMs:Math.max(0,Math.round(r-i.acquiredAtMs))}:{}}}(n,i)})}function ak(e){try{return JSON.parse(t.readFileSync(e,"utf8"))}catch{return null}}let av="0.27.1",ax="agent-browser";async function aA(e){let t=aI(e);if(t.installed){var n=t;if(!n.installed)throw a_(n);return{command:n.binaryPath,env:aN(n,process.env)}}throw a_(t)}async function aM(e){let n=aI(e);var r,i=n.nodeMajor;if(!(i>=24))throw new D("UNSUPPORTED_OPERATION","Web automation requires Node 24 or newer.",{currentNode:process.version,requiredNodeMajor:24,hint:"Run agent-device with Node 24+ for web setup and web automation."});let s=await ay({lockDirPath:a.join(n.installDir,"..",".agent-browser-install.lock"),owner:{pid:process.pid,startTime:ew(process.pid),acquiredAtMs:Date.now()},timeoutMs:3e5,description:"managed agent-browser setup"});try{let n=aI(e);if(n.installed)return n;return t.mkdirSync(n.installDir,{recursive:!0}),await aR(n),await aP(n,["install"],{timeoutMs:3e5}),await aP(n,["doctor","--offline","--quick"],{timeoutMs:6e4}),r=n,t.writeFileSync(a.join(r.installDir,"manifest.json"),JSON.stringify({package:ax,version:av,node:process.version,installedAt:new Date().toISOString()},null,2),"utf8"),aI(e)}finally{await s()}}async function aS(e){let t=aI(e);if(!t.installed)throw a_(t);let n=await aP(t,["doctor","--offline","--quick"],{timeoutMs:6e4,allowFailure:!0});return{status:t,...n}}function aI(n){var r,i,o;let l,d,u=n.stateDir??process.env.AGENT_DEVICE_STATE_DIR??a.join(process.env.HOME??process.cwd(),".agent-device"),c=a.join(u,"tools","agent-browser",av),p=(r=c,l=a.join(r,"package"),a.join(l,"node_modules",".bin","win32"===process.platform?"agent-browser.cmd":"agent-browser")),h=a.join(c,"home"),f=function(t){if("win32"===process.platform)return a.join(t,"home");let n=e.createHash("sha1").update(t).digest("hex").slice(0,12);return a.join(s.tmpdir(),"agent-device-web",n)}(c),m=(i=c,d=e.createHash("sha1").update(i).digest("hex").slice(0,12),a.join(s.tmpdir(),"adw",d)),w=function(e){try{return t.accessSync(e,t.constants.X_OK),!0}catch{return!1}}(p)&&(o=c,t.existsSync(a.join(o,"manifest.json"))),g=Number.parseInt(process.versions.node.split(".")[0]??"0",10);return{version:av,stateDir:u,installDir:c,binaryPath:p,homeDir:h,runtimeHomeDir:f,socketDir:m,installed:w,nodeMajor:g,nodeSupported:g>=24}}async function aR(e){let n=a.join(e.installDir,"package");t.mkdirSync(n,{recursive:!0}),await F("npm",["install","--prefix",n,"--no-audit","--no-fund","--no-save",`${ax}@${av}`],{env:process.env,timeoutMs:3e5})}async function aP(e,t,n){return await F(e.binaryPath,t,{allowFailure:n.allowFailure,env:aN(e,process.env),timeoutMs:n.timeoutMs})}function aN(e,n){return t.mkdirSync(e.homeDir,{recursive:!0}),function(e){if(e.runtimeHomeDir!==e.homeDir){t.mkdirSync(a.dirname(e.runtimeHomeDir),{recursive:!0});try{let n=t.lstatSync(e.runtimeHomeDir);if(n.isSymbolicLink()&&t.readlinkSync(e.runtimeHomeDir)===e.homeDir||n.isDirectory())return;n.isSymbolicLink()&&t.unlinkSync(e.runtimeHomeDir)}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}try{t.symlinkSync(e.homeDir,e.runtimeHomeDir,"dir")}catch{t.mkdirSync(e.runtimeHomeDir,{recursive:!0})}}}(e),t.mkdirSync(e.socketDir,{recursive:!0}),{...n,HOME:e.runtimeHomeDir,AGENT_BROWSER_SOCKET_DIR:e.socketDir}}function a_(e){return new D("TOOL_MISSING","Managed web browser backend is not installed.",{version:av,installDir:e.installDir,hint:!1===e.nodeSupported?`Web automation requires Node 24+; current Node is ${process.version}.`:"Run `agent-device web setup` to install the managed web backend."})}function aD(e){let t=N(e);return"TOOL_MISSING"!==t.code?t:new D(t.code,t.message,{...t.details??{},hint:"string"==typeof t.details?.hint?t.details.hint:"Run `agent-device web setup` to install the managed web backend."})}export{ay as acquireProcessLock,eT as appendScriptSeriesFlags,aw as createAgentDevice,e8 as decodePngAsync,aS as doctorManagedAgentBrowser,e6 as encodePngAsync,ns as evaluateIsPredicate,eF as findMistargetedTypeRefToken,eq as formatPortableActionLine,eE as formatScriptActionSummary,eP as formatScriptArg,eN as formatScriptStringLiteral,eS as isClickLikeCommand,eY as isKeyboardAction,ni as isSupportedPredicate,eI as isTouchTargetCommand,ab as localCommandPolicy,aD as mapManagedAgentBrowserError,eB as parseReplayOpenFlags,eL as parseReplayRuntimeFlags,eU as parseReplaySeriesFlags,e3 as prewarmPngWorker,aA as resolveAgentBrowserTool,aM as setupManagedAgentBrowser,e5 as terminatePngWorker,eG as timingSafeStringEqual};
package/dist/src/2948.js CHANGED
@@ -1 +1 @@
1
- import{AppError as e}from"./733.js";import{recordingCommandMetadata as t,recordingCommandDefinitions as r,perfCommandDefinitions as o,METRO_PREPARE_FLAGS as a,defineExecutableCommand as i,systemCommandDefinitions as s,replayCommandMetadataList as n,requiredField as l,captureCommandDefinitions as d,observabilityCommandDefinitions as m,perfCommandMetadataList as p,captureCommandMetadata as u,batchCommandMetadata as c,integerField as b,booleanField as f,managementCommandMetadata as h,stringSchema as g,METRO_RELOAD_FLAGS as y,observabilityCommandMetadata as M,replayCommandDefinitions as P,reactNativeCommandDefinition as I,enumField as S,interactionCommandMetadata as U,commonInputFromFlags as v,defineFieldCommandMetadata as w,systemCommandMetadata as x,managementCommandDefinitions as H,jsonSchemaField as R,stringField as T,reactNativeCommandMetadata as _}from"./9873.js";import{listMcpExposedCommandNames as A}from"./2133.js";let N="debug",C=w(N,"Symbolicate crash artifacts with matching debug symbols.",{action:l(S(["symbols"])),artifact:l(T("Apple crash artifact path (.ips, .crash, or .log).")),dsym:T("Path to a matching .dSYM bundle."),searchPath:T("Directory to scan for matching .dSYM bundles."),out:T("Output path for the symbolicated artifact.")}),k=i(C,(e,t)=>e.debug.symbols(t)),D={[N]:{usageOverride:"debug symbols --artifact <crash.ips|crash.log> (--dsym <App.dSYM> | --search-path <dir>) [--out <symbolicated>]",listUsageOverride:"debug symbols --artifact <path> --dsym <App.dSYM>",helpDescription:"Symbolicate Apple crash artifacts with matching dSYM UUIDs. This debug namespace is intentionally narrow: use logs for app logs, network for HTTP evidence, perf for performance samples, record/trace for media and traces, and react-devtools for React Native profiles.",summary:"Symbolicate Apple crash artifacts",positionalArgs:["symbols"],allowedFlags:["artifact","dsym","searchPath","out"]}},B={debug:(t,r)=>({...v(r),action:function(t){if("symbols"===t)return t;throw new e("INVALID_ARGS","debug supports only symbols; use logs, network, perf, record, trace, or react-devtools for other diagnostics")}(t[0]),artifact:r.artifact,dsym:r.dsym,searchPath:r.searchPath,out:r.out})},E="metro",j=w(E,"Prepare Metro runtime or reload React Native apps.",{action:l(S(["prepare","reload"])),projectRoot:T(),kind:R(g()),publicBaseUrl:T(),proxyBaseUrl:T(),bearerToken:T(),bridgeScope:R({type:"object",additionalProperties:!0}),launchUrl:T(),port:b(),listenHost:T(),statusHost:T(),startupTimeoutMs:b(),probeTimeoutMs:b(),reuseExisting:f(),installDependenciesIfNeeded:f(),runtimeFilePath:T(),logPath:T(),metroHost:T(),metroPort:b(),bundleUrl:T(),timeoutMs:b()}),F=i(j,async(e,t)=>{var r,o,a;return"prepare"===t.action?await e.metro.prepare({projectRoot:(r=t).projectRoot,kind:r.kind,publicBaseUrl:r.publicBaseUrl,proxyBaseUrl:r.proxyBaseUrl,bearerToken:r.bearerToken,bridgeScope:r.bridgeScope??((o=r).tenant&&o.runId&&o.leaseId?{tenantId:o.tenant,runId:o.runId,leaseId:o.leaseId}:void 0),port:r.port,listenHost:r.listenHost,statusHost:r.statusHost,startupTimeoutMs:r.startupTimeoutMs,probeTimeoutMs:r.probeTimeoutMs,reuseExisting:r.reuseExisting,installDependenciesIfNeeded:r.installDependenciesIfNeeded,runtimeFilePath:r.runtimeFilePath}):await e.metro.reload({metroHost:(a=t).metroHost,metroPort:a.metroPort,bundleUrl:a.bundleUrl,timeoutMs:a.timeoutMs})}),K={[E]:{usageOverride:"metro prepare (--public-base-url <url> | --proxy-base-url <url>) [--project-root <path>] [--port <port>] [--kind auto|react-native|expo]\n agent-device metro reload [--metro-host <host>] [--metro-port <port>] [--bundle-url <url>]",listUsageOverride:"metro prepare --public-base-url <url> | --proxy-base-url <url>; metro reload",helpDescription:"Prepare a local Metro runtime or ask Metro to reload connected React Native apps",summary:"Prepare Metro or reload apps",positionalArgs:["prepare|reload"],allowedFlags:[...y,...a]}},L={metro:(t,r)=>{let o=(t[0]??"").toLowerCase();if("prepare"!==o&&"reload"!==o)throw new e("INVALID_ARGS","metro requires a subcommand: prepare or reload");if("reload"===o)return{action:o,metroHost:r.metroHost,metroPort:r.metroPort,bundleUrl:r.bundleUrl,timeoutMs:r.metroProbeTimeoutMs};if(!r.metroPublicBaseUrl&&!r.metroProxyBaseUrl)throw new e("INVALID_ARGS","metro prepare requires --public-base-url <url> or --proxy-base-url <url>.");return{action:o,projectRoot:r.metroProjectRoot,kind:function(t){if(void 0!==t){if("auto"===t||"react-native"===t||"expo"===t)return t;throw new e("INVALID_ARGS","metro prepare --kind must be auto, react-native, or expo")}}(r.kind??r.metroKind),port:r.metroPreparePort,listenHost:r.metroListenHost,statusHost:r.metroStatusHost,publicBaseUrl:r.metroPublicBaseUrl,proxyBaseUrl:r.metroProxyBaseUrl,bearerToken:r.metroBearerToken,bridgeScope:r.tenant&&r.runId&&r.leaseId?{tenantId:r.tenant,runId:r.runId,leaseId:r.leaseId}:void 0,startupTimeoutMs:r.metroStartupTimeoutMs,probeTimeoutMs:r.metroProbeTimeoutMs,reuseExisting:!r.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!r.metroNoInstallDeps&&void 0,runtimeFilePath:r.metroRuntimeFile}}},O=[{metadata:h,definitions:H},{metadata:u,definitions:d},{metadata:x,definitions:s},{metadata:[_],definitions:[I]},{metadata:n,definitions:P},{metadata:M,definitions:m},{metadata:p,definitions:o},{metadata:[C],definitions:[k]},{metadata:t,definitions:r},{metadata:[j],definitions:[F]}],Y=O.flatMap(e=>[...e.metadata]),G=O.flatMap(e=>[...e.definitions]),V=[...U,...Y,c],q=new Map(V.map(e=>[e.name,e]));function $(){return[...V]}function z(){return A().map(e=>{var t;if(!J(e))throw Error(`Missing command metadata for MCP-exposed command: ${e}`);return t=e,q.get(t)})}function J(e){return q.has(e)}export{G as clientCommandDefinitions,B as debuggingCliReaders,D as debuggingCliSchemas,J as isCommandName,$ as listCommandMetadata,z as listMcpCommandMetadata,L as metroCliReaders,K as metroCliSchemas};
1
+ import{AppError as e}from"./733.js";import{recordingCommandMetadata as t,recordingCommandDefinitions as r,perfCommandDefinitions as o,METRO_PREPARE_FLAGS as a,defineExecutableCommand as i,systemCommandDefinitions as s,replayCommandMetadataList as n,requiredField as d,captureCommandDefinitions as l,observabilityCommandDefinitions as m,perfCommandMetadataList as p,captureCommandMetadata as u,batchCommandMetadata as c,integerField as b,booleanField as f,managementCommandMetadata as h,stringSchema as g,METRO_RELOAD_FLAGS as M,observabilityCommandMetadata as y,replayCommandDefinitions as P,reactNativeCommandDefinition as I,enumField as S,interactionCommandMetadata as U,commonInputFromFlags as v,defineFieldCommandMetadata as w,systemCommandMetadata as R,managementCommandDefinitions as x,jsonSchemaField as H,stringField as T,reactNativeCommandMetadata as _}from"./9873.js";import{listMcpExposedCommandNames as N}from"./2133.js";let A="debug",k=w(A,"Symbolicate crash artifacts with matching debug symbols.",{action:d(S(["symbols"])),artifact:d(T("Apple crash artifact path (.ips, .crash, or .log).")),dsym:T("Path to a matching .dSYM bundle."),searchPath:T("Directory to scan for matching .dSYM bundles."),out:T("Output path for the symbolicated artifact.")}),C=i(k,(e,t)=>e.debug.symbols(t)),D={[A]:{usageOverride:"debug symbols --artifact <crash.ips|crash.log> (--dsym <App.dSYM> | --search-path <dir>) [--out <symbolicated>]",listUsageOverride:"debug",helpDescription:"Symbolicate Apple crash artifacts with matching dSYM UUIDs. This debug namespace is intentionally narrow: use logs for app logs, network for HTTP evidence, perf for performance samples, record/trace for media and traces, and react-devtools for React Native profiles.",summary:"Symbolicate Apple crash artifacts with dSYMs; use logs/network/perf for other diagnostics",positionalArgs:["symbols"],allowedFlags:["artifact","dsym","searchPath","out"]}},B={debug:(t,r)=>({...v(r),action:function(t){if("symbols"===t)return t;throw new e("INVALID_ARGS","debug supports only symbols; use logs, network, perf, record, trace, or react-devtools for other diagnostics")}(t[0]),artifact:r.artifact,dsym:r.dsym,searchPath:r.searchPath,out:r.out})},E="metro",j=w(E,"Prepare Metro runtime or reload React Native apps.",{action:d(S(["prepare","reload"])),projectRoot:T(),kind:H(g()),publicBaseUrl:T(),proxyBaseUrl:T(),bearerToken:T(),bridgeScope:H({type:"object",additionalProperties:!0}),launchUrl:T(),port:b(),listenHost:T(),statusHost:T(),startupTimeoutMs:b(),probeTimeoutMs:b(),reuseExisting:f(),installDependenciesIfNeeded:f(),runtimeFilePath:T(),logPath:T(),metroHost:T(),metroPort:b(),bundleUrl:T(),timeoutMs:b()}),F=i(j,async(e,t)=>{var r,o,a;return"prepare"===t.action?await e.metro.prepare({projectRoot:(r=t).projectRoot,kind:r.kind,publicBaseUrl:r.publicBaseUrl,proxyBaseUrl:r.proxyBaseUrl,bearerToken:r.bearerToken,bridgeScope:r.bridgeScope??((o=r).tenant&&o.runId&&o.leaseId?{tenantId:o.tenant,runId:o.runId,leaseId:o.leaseId}:void 0),port:r.port,listenHost:r.listenHost,statusHost:r.statusHost,startupTimeoutMs:r.startupTimeoutMs,probeTimeoutMs:r.probeTimeoutMs,reuseExisting:r.reuseExisting,installDependenciesIfNeeded:r.installDependenciesIfNeeded,runtimeFilePath:r.runtimeFilePath}):await e.metro.reload({metroHost:(a=t).metroHost,metroPort:a.metroPort,bundleUrl:a.bundleUrl,timeoutMs:a.timeoutMs})}),K={[E]:{usageOverride:"metro prepare (--public-base-url <url> | --proxy-base-url <url>) [--project-root <path>] [--port <port>] [--kind auto|react-native|expo]\n agent-device metro reload [--metro-host <host>] [--metro-port <port>] [--bundle-url <url>]",listUsageOverride:"metro",helpDescription:"Prepare a local Metro runtime or ask Metro to reload connected React Native apps",summary:"Prepare Metro reachability for React Native/Expo apps or trigger app reloads",positionalArgs:["prepare|reload"],allowedFlags:[...M,...a]}},L={metro:(t,r)=>{let o=(t[0]??"").toLowerCase();if("prepare"!==o&&"reload"!==o)throw new e("INVALID_ARGS","metro requires a subcommand: prepare or reload");if("reload"===o)return{action:o,metroHost:r.metroHost,metroPort:r.metroPort,bundleUrl:r.bundleUrl,timeoutMs:r.metroProbeTimeoutMs};if(!r.metroPublicBaseUrl&&!r.metroProxyBaseUrl)throw new e("INVALID_ARGS","metro prepare requires --public-base-url <url> or --proxy-base-url <url>.");return{action:o,projectRoot:r.metroProjectRoot,kind:function(t){if(void 0!==t){if("auto"===t||"react-native"===t||"expo"===t)return t;throw new e("INVALID_ARGS","metro prepare --kind must be auto, react-native, or expo")}}(r.kind??r.metroKind),port:r.metroPreparePort,listenHost:r.metroListenHost,statusHost:r.metroStatusHost,publicBaseUrl:r.metroPublicBaseUrl,proxyBaseUrl:r.metroProxyBaseUrl,bearerToken:r.metroBearerToken,bridgeScope:r.tenant&&r.runId&&r.leaseId?{tenantId:r.tenant,runId:r.runId,leaseId:r.leaseId}:void 0,startupTimeoutMs:r.metroStartupTimeoutMs,probeTimeoutMs:r.metroProbeTimeoutMs,reuseExisting:!r.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!r.metroNoInstallDeps&&void 0,runtimeFilePath:r.metroRuntimeFile}}},O=[{metadata:h,definitions:x},{metadata:u,definitions:l},{metadata:R,definitions:s},{metadata:[_],definitions:[I]},{metadata:n,definitions:P},{metadata:y,definitions:m},{metadata:p,definitions:o},{metadata:[k],definitions:[C]},{metadata:t,definitions:r},{metadata:[j],definitions:[F]}],Y=O.flatMap(e=>[...e.metadata]),G=O.flatMap(e=>[...e.definitions]),V=[...U,...Y,c],q=new Map(V.map(e=>[e.name,e]));function $(){return[...V]}function z(){return N().map(e=>{var t;if(!J(e))throw Error(`Missing command metadata for MCP-exposed command: ${e}`);return t=e,q.get(t)})}function J(e){return q.has(e)}export{G as clientCommandDefinitions,B as debuggingCliReaders,D as debuggingCliSchemas,J as isCommandName,$ as listCommandMetadata,z as listMcpCommandMetadata,L as metroCliReaders,K as metroCliSchemas};
package/dist/src/4291.js CHANGED
@@ -1,2 +1 @@
1
- import{AppError as e}from"./733.js";function t(e){return e.map((e,t)=>({...e,ref:`e${t+1}`}))}function r(e){let t=e.trim();return t.startsWith("@")?t.slice(1)||null:t.startsWith("e")?t:null}function a(e,t){return e.find(e=>e.ref===t)??null}function n(e){return JSON.stringify({interactiveOnly:e?.interactiveOnly===!0,depth:"number"==typeof e?.depth?e.depth:null,scope:e?.scope?.trim()||null,raw:e?.raw===!0})}function i(e){if(e)return{depth:e.snapshotDepth,interactiveOnly:e.snapshotInteractiveOnly,raw:e.snapshotRaw,scope:e.snapshotScope}}function o(e){return{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}let l=["ios","macos","android","linux","apple"],s=["mobile","tv","desktop"];function d(e){return e}function c(e){return"apple"===e||"ios"===e||"macos"===e}function u(e,t){return!t||("apple"===t?c(e):e===t)}function m(e){return"macos"===e||"desktop"===e?"macOS":"tv"===e?"tvOS":"iOS"}function f(e){let{simulatorSetPath:t,platform:r,target:a}=e;if(t&&"macos"!==r&&"desktop"!==a)return t}async function p(t,r,a={}){let n=t,i=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(r.platform&&(n=n.filter(e=>u(e.platform,r.platform))),r.target&&(n=n.filter(e=>(e.target??"mobile")===r.target)),r.udid){let t=n.find(e=>e.id===r.udid&&c(e.platform));if(!t)throw new e("DEVICE_NOT_FOUND",`No Apple device with UDID ${r.udid}`);return t}if(r.serial){let t=n.find(e=>e.id===r.serial&&"android"===e.platform);if(!t)throw new e("DEVICE_NOT_FOUND",`No Android device with serial ${r.serial}`);return t}if(r.deviceName){let t=i(r.deviceName),a=n.find(e=>i(e.name)===t);if(!a)throw new e("DEVICE_NOT_FOUND",`No device named ${r.deviceName}`);return a}let o=n[0];if(void 0!==o&&1===n.length)return o;if(0===n.length){var l;let t=a.simulatorSetPath;if(t&&(!(l=r.platform)||"apple"===l||"ios"===l))throw new e("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:t,hint:`The simulator set at "${t}" appears to be empty. Create a simulator first:
2
- xcrun simctl --set "${t}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:r});throw new e("DEVICE_NOT_FOUND","No devices found",{selector:r})}let s=n.filter(e=>"device"!==e.kind);s.length>0&&(n=s);let d=n.filter(e=>e.booted),m=d[0];if(void 0!==m&&1===d.length)return m;let f=d[0]??n[0];if(void 0===f)throw new e("DEVICE_NOT_FOUND","No devices found",{selector:r});return f}let h=["reject","strip"],$=["ios-simulator","ios-instance","android-instance"],E=["socket","http","dual"],I=["auto","socket","http"],v=["none","tenant"],S=["summary","headers","body","all"];function N(e){return{parse:t=>e(t,"$")}}function O(e,t){throw Error(`${e}: ${t}`)}function _(e,t){return(!e||"object"!=typeof e||Array.isArray(e))&&O(t,"Expected an object"),e}function g(e,t){return"string"!=typeof e&&O(t,"Expected a string"),e}function y(e,t){let r=g(e,t).trim();return r||O(t,"Expected a non-empty string"),r}function P(e,t){return Number.isInteger(e)||O(t,"Expected an integer"),e}function b(e,t,r){let a=e[t];return void 0===a?void 0:g(a,`${r}.${t}`)}function w(e,t,r){let a=e[t];if(void 0!==a)return"boolean"!=typeof a&&O(`${r}.${t}`,"Expected a boolean"),a}function A(e,t,r){let a=e[t];return void 0===a?void 0:P(a,`${r}.${t}`)}function D(e,t,r){let a=e[t];return void 0===a?void 0:_(a,`${r}.${t}`)}function M(e,t,r,a){let n=e[t];if(void 0!==n)return"string"==typeof n&&r.includes(n)||O(`${a}.${t}`,`Expected one of: ${r.join(", ")}`),n}function R(e,t){let r=_(e,t),a={};for(let[e,n]of Object.entries(r))a[e]=g(n,`${t}.${e}`);return a}let k=N((e,t)=>{let r=_(e,t);return{platform:M(r,"platform",["ios","android"],t),metroHost:b(r,"metroHost",t),metroPort:A(r,"metroPort",t),bundleUrl:b(r,"bundleUrl",t),launchUrl:b(r,"launchUrl",t)}}),x=N((e,t)=>{var r,a;let n=_(e,t),i=(r=n.positionals,a=`${t}.positionals`,Array.isArray(r)||O(a,"Expected an array"),r),o=D(n,"meta",t);return{token:b(n,"token",t),session:b(n,"session",t),command:g(n.command,`${t}.command`),positionals:i.map((e,r)=>g(e,`${t}.positionals[${String(r)}]`)),flags:D(n,"flags",t),runtime:void 0===n.runtime?void 0:k.parse(n.runtime),meta:void 0===o?void 0:{requestId:b(o,"requestId",`${t}.meta`),debug:w(o,"debug",`${t}.meta`),cwd:b(o,"cwd",`${t}.meta`),sessionExplicit:w(o,"sessionExplicit",`${t}.meta`),tenantId:b(o,"tenantId",`${t}.meta`),runId:b(o,"runId",`${t}.meta`),leaseId:b(o,"leaseId",`${t}.meta`),leaseTtlMs:A(o,"leaseTtlMs",`${t}.meta`),leaseBackend:M(o,"leaseBackend",$,`${t}.meta`),sessionIsolation:M(o,"sessionIsolation",v,`${t}.meta`),uploadedArtifactId:b(o,"uploadedArtifactId",`${t}.meta`),clientArtifactPaths:void 0===o.clientArtifactPaths?void 0:R(o.clientArtifactPaths,`${t}.meta.clientArtifactPaths`),installSource:void 0===o.installSource?void 0:function(e,t){let r=_(e,t),a=g(r.kind,`${t}.kind`);if("url"===a){let e=g(r.url,`${t}.url`),n=void 0===r.headers?void 0:R(r.headers,`${t}.headers`);return n?{kind:a,url:e,headers:n}:{kind:a,url:e}}if("path"===a)return{kind:a,path:g(r.path,`${t}.path`)};if("github-actions-artifact"===a){let e,a,n,i,o;return e=y(r.owner,`${t}.owner`),a=y(r.repo,`${t}.repo`),n=void 0!==r.artifactId,i=void 0!==r.runId,o=void 0!==r.artifactName,(n&&(i||o)&&O(`${t}`,"Expected either artifactId or artifactName, not both"),n||!i||o||O(`${t}`,"Expected artifactName when runId is specified"),n||o||O(`${t}`,"Expected artifactId or artifactName"),n)?{kind:"github-actions-artifact",owner:e,repo:a,artifactId:P(r.artifactId,`${t}.artifactId`)}:{kind:"github-actions-artifact",owner:e,repo:a,...i?{runId:P(r.runId,`${t}.runId`)}:{},artifactName:y(r.artifactName,`${t}.artifactName`)}}O(`${t}.kind`,'Expected "url", "path", or "github-actions-artifact"')}(o.installSource,`${t}.meta.installSource`),retainMaterializedPaths:w(o,"retainMaterializedPaths",`${t}.meta`),materializedPathRetentionMs:A(o,"materializedPathRetentionMs",`${t}.meta`),materializationId:b(o,"materializationId",`${t}.meta`),lockPolicy:M(o,"lockPolicy",h,`${t}.meta`),lockPlatform:M(o,"lockPlatform",l,`${t}.meta`)}}});function C(e,t){return{token:b(e,"token",t),session:b(e,"session",t),tenantId:b(e,"tenantId",t),tenant:b(e,"tenant",t),runId:b(e,"runId",t)}}let T=N((e,t)=>{let r=_(e,t);return{...C(r,t),ttlMs:A(r,"ttlMs",t),backend:M(r,"backend",$,t)}}),U=N((e,t)=>{let r,a={record:r=_(e,t),leaseId:b(r,"leaseId",t),ttlMs:A(r,"ttlMs",t)};return{...C(a.record,t),leaseId:a.leaseId,ttlMs:a.ttlMs}}),F=N((e,t)=>{let r=_(e,t);return void 0!==r.ttlMs&&O(`${t}.ttlMs`,"Unexpected field"),{...C(r,t),leaseId:b(r,"leaseId",t)}}),j=N((e,t)=>{let r,a=_(e,t);return{jsonrpc:b(a,"jsonrpc",t),id:(null==(r=a.id)||"string"!=typeof r&&"number"!=typeof r&&O(`${t}.id`,"Expected a string, number, or null"),r),method:b(a,"method",t),params:a.params}});export{h as DAEMON_LOCK_POLICIES,E as DAEMON_SERVER_MODES,I as DAEMON_TRANSPORT_PREFERENCES,s as DEVICE_TARGETS,$ as LEASE_BACKENDS,S as NETWORK_INCLUDE_MODES,l as PLATFORM_SELECTORS,v as SESSION_ISOLATION_MODES,t as attachRefs,n as buildSnapshotPresentationKey,o as centerOfRect,x as daemonCommandRequestSchema,k as daemonRuntimeSchema,a as findNodeByRef,c as isApplePlatform,j as jsonRpcRequestSchema,T as leaseAllocateSchema,U as leaseHeartbeatSchema,F as leaseReleaseSchema,u as matchesPlatformSelector,d as normalizePlatformSelector,r as normalizeRef,m as resolveApplePlatformName,f as resolveAppleSimulatorSetPathForSelector,p as resolveDevice,i as snapshotPresentationOptionsFromFlags};
1
+ import"./733.js";import{PLATFORM_SELECTORS as t}from"./5910.js";function e(t){return"xctest"===t||"android"===t||"macos-helper"===t||"linux-atspi"===t||"web"===t}function n(t){return void 0===t||"xctest"===t||"android"===t}function a(t){return t.map((t,e)=>({...t,ref:`e${e+1}`}))}function r(t){let e=t.trim();return e.startsWith("@")?e.slice(1)||null:e.startsWith("e")?e:null}function i(t,e){return t.find(t=>t.ref===e)??null}function o(t){return JSON.stringify({interactiveOnly:t?.interactiveOnly===!0,depth:"number"==typeof t?.depth?t.depth:null,scope:t?.scope?.trim()||null,raw:t?.raw===!0})}function s(t){if(t)return{depth:t.snapshotDepth,interactiveOnly:t.snapshotInteractiveOnly,raw:t.snapshotRaw,scope:t.snapshotScope}}function d(t){return{x:Math.round(t.x+t.width/2),y:Math.round(t.y+t.height/2)}}let l=["reject","strip"],c=["ios-simulator","ios-instance","android-instance"],u=["socket","http","dual"],m=["auto","socket","http"],f=["none","tenant"],p=["summary","headers","body","all"];function h(t){return{parse:e=>t(e,"$")}}function $(t,e){throw Error(`${t}: ${e}`)}function I(t,e){return(!t||"object"!=typeof t||Array.isArray(t))&&$(e,"Expected an object"),t}function E(t,e){return"string"!=typeof t&&$(e,"Expected a string"),t}function S(t,e){let n=E(t,e).trim();return n||$(e,"Expected a non-empty string"),n}function v(t,e){return Number.isInteger(t)||$(e,"Expected an integer"),t}function y(t,e,n){let a=t[e];return void 0===a?void 0:E(a,`${n}.${e}`)}function b(t,e,n){let a=t[e];if(void 0!==a)return"boolean"!=typeof a&&$(`${n}.${e}`,"Expected a boolean"),a}function M(t,e,n){let a=t[e];return void 0===a?void 0:v(a,`${n}.${e}`)}function N(t,e,n){let a=t[e];return void 0===a?void 0:I(a,`${n}.${e}`)}function P(t,e,n,a){let r=t[e];if(void 0!==r)return"string"==typeof r&&n.includes(r)||$(`${a}.${e}`,`Expected one of: ${n.join(", ")}`),r}function x(t,e){let n=I(t,e),a={};for(let[t,r]of Object.entries(n))a[t]=E(r,`${e}.${t}`);return a}let O=h((t,e)=>{let n=I(t,e);return{platform:P(n,"platform",["ios","android"],e),metroHost:y(n,"metroHost",e),metroPort:M(n,"metroPort",e),bundleUrl:y(n,"bundleUrl",e),launchUrl:y(n,"launchUrl",e)}}),R=h((e,n)=>{var a,r;let i=I(e,n),o=(a=i.positionals,r=`${n}.positionals`,Array.isArray(a)||$(r,"Expected an array"),a),s=N(i,"meta",n);return{token:y(i,"token",n),session:y(i,"session",n),command:E(i.command,`${n}.command`),positionals:o.map((t,e)=>E(t,`${n}.positionals[${String(e)}]`)),flags:N(i,"flags",n),runtime:void 0===i.runtime?void 0:O.parse(i.runtime),meta:void 0===s?void 0:{requestId:y(s,"requestId",`${n}.meta`),debug:b(s,"debug",`${n}.meta`),cwd:y(s,"cwd",`${n}.meta`),sessionExplicit:b(s,"sessionExplicit",`${n}.meta`),tenantId:y(s,"tenantId",`${n}.meta`),runId:y(s,"runId",`${n}.meta`),leaseId:y(s,"leaseId",`${n}.meta`),leaseTtlMs:M(s,"leaseTtlMs",`${n}.meta`),leaseBackend:P(s,"leaseBackend",c,`${n}.meta`),sessionIsolation:P(s,"sessionIsolation",f,`${n}.meta`),uploadedArtifactId:y(s,"uploadedArtifactId",`${n}.meta`),clientArtifactPaths:void 0===s.clientArtifactPaths?void 0:x(s.clientArtifactPaths,`${n}.meta.clientArtifactPaths`),installSource:void 0===s.installSource?void 0:function(t,e){let n=I(t,e),a=E(n.kind,`${e}.kind`);if("url"===a){let t=E(n.url,`${e}.url`),r=void 0===n.headers?void 0:x(n.headers,`${e}.headers`);return r?{kind:a,url:t,headers:r}:{kind:a,url:t}}if("path"===a)return{kind:a,path:E(n.path,`${e}.path`)};if("github-actions-artifact"===a){let t,a,r,i,o;return t=S(n.owner,`${e}.owner`),a=S(n.repo,`${e}.repo`),r=void 0!==n.artifactId,i=void 0!==n.runId,o=void 0!==n.artifactName,(r&&(i||o)&&$(`${e}`,"Expected either artifactId or artifactName, not both"),r||!i||o||$(`${e}`,"Expected artifactName when runId is specified"),r||o||$(`${e}`,"Expected artifactId or artifactName"),r)?{kind:"github-actions-artifact",owner:t,repo:a,artifactId:v(n.artifactId,`${e}.artifactId`)}:{kind:"github-actions-artifact",owner:t,repo:a,...i?{runId:v(n.runId,`${e}.runId`)}:{},artifactName:S(n.artifactName,`${e}.artifactName`)}}$(`${e}.kind`,'Expected "url", "path", or "github-actions-artifact"')}(s.installSource,`${n}.meta.installSource`),retainMaterializedPaths:b(s,"retainMaterializedPaths",`${n}.meta`),materializedPathRetentionMs:M(s,"materializedPathRetentionMs",`${n}.meta`),materializationId:y(s,"materializationId",`${n}.meta`),lockPolicy:P(s,"lockPolicy",l,`${n}.meta`),lockPlatform:P(s,"lockPlatform",t,`${n}.meta`)}}});function _(t,e){return{token:y(t,"token",e),session:y(t,"session",e),tenantId:y(t,"tenantId",e),tenant:y(t,"tenant",e),runId:y(t,"runId",e)}}let g=h((t,e)=>{let n=I(t,e);return{..._(n,e),ttlMs:M(n,"ttlMs",e),backend:P(n,"backend",c,e)}}),k=h((t,e)=>{let n,a={record:n=I(t,e),leaseId:y(n,"leaseId",e),ttlMs:M(n,"ttlMs",e)};return{..._(a.record,e),leaseId:a.leaseId,ttlMs:a.ttlMs}}),A=h((t,e)=>{let n=I(t,e);return void 0!==n.ttlMs&&$(`${e}.ttlMs`,"Unexpected field"),{..._(n,e),leaseId:y(n,"leaseId",e)}}),w=h((t,e)=>{let n,a=I(t,e);return{jsonrpc:y(a,"jsonrpc",e),id:(null==(n=a.id)||"string"!=typeof n&&"number"!=typeof n&&$(`${e}.id`,"Expected a string, number, or null"),n),method:y(a,"method",e),params:a.params}});export{l as DAEMON_LOCK_POLICIES,u as DAEMON_SERVER_MODES,m as DAEMON_TRANSPORT_PREFERENCES,c as LEASE_BACKENDS,p as NETWORK_INCLUDE_MODES,f as SESSION_ISOLATION_MODES,a as attachRefs,o as buildSnapshotPresentationKey,d as centerOfRect,R as daemonCommandRequestSchema,O as daemonRuntimeSchema,i as findNodeByRef,e as isSnapshotBackend,w as jsonRpcRequestSchema,g as leaseAllocateSchema,k as leaseHeartbeatSchema,A as leaseReleaseSchema,r as normalizeRef,s as snapshotPresentationOptionsFromFlags,n as usesMobileSnapshotPresentation};
package/dist/src/4428.js CHANGED
@@ -1,3 +1,3 @@
1
- import e from"node:fs";import{parseAllDocuments as t,stringify as n}from"yaml";import{AppError as r}from"./733.js";import{MAESTRO_NEW_ISSUE_URL as i,MAESTRO_COMPAT_TRACKER_URL as o,readScreenshotScriptFlag as s}from"./9873.js";import{formatScriptStringLiteral as l,parseReplayOpenFlags as a,formatPortableActionLine as u,parseReplaySeriesFlags as f,parseReplayRuntimeFlags as p,isClickLikeCommand as c}from"./5299.js";let h=/^[A-Z_][A-Z0-9_]*$/,d=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,m="AD_VAR_";function g(e){return e.startsWith("AD_")}function A(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(g(e))throw A(e);t[e]=r}return{values:t}}function v(e,t){Object.assign(e.values,t)}function w(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(m))continue;let e=n.slice(m.length);0!==e.length&&h.test(e)&&(g(e)||(t[e]=r))}return t}function b(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!h.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(g(i))throw A(i);t[i]=n.slice(e+1)}return t}function I(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function $(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function S(e,t,n){return e.replace(d,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function _(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>S(e,t,n)),flags:N(e.flags,t,n)??{},runtime:N(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:S(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function N(e,t,n){return e?function e(t,n,r){return"string"==typeof t?S(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let R=new Set(["ios","android","macos","linux"]),D=new Set(["mobile","tv","desktop"]);function M(e){let t=[],n=[],i=e.split(/\r?\n/),o=!1;for(let[e,l]of i.entries()){let i=l.trim();if(0===i.length||i.startsWith("#"))continue;if(x(i)){if(o)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let u=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...i]=function(e){let t=[],n=0;for(;n<e.length&&!((n=function(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}(e,n))>=e.length);){let i='"'===e[n]?function(e,t){let n=!1,i=t+1;for(;i<e.length;i+=1){let t=e.charAt(i);if('"'===t&&!n)break;if(n){n=!1;continue}n="\\"===t}if(i>=e.length)throw new r("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,i+1)),nextCursor:i+1}}(e,n):function(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}(e,n);t.push(i.value),n=i.nextCursor}return t}(t);if(void 0===n||"context"===n)return null;let o={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){o.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){o.flags.snapshotInteractiveOnly=!0;continue}if("-c"!==t){if("--raw"===t){o.flags.snapshotRaw=!0;continue}if("--force-full"===t){o.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(o.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){o.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}}return o}if("open"===n){let e=a(i);return o.positionals=e.positionals,Object.assign(o.flags,e.flags),o.runtime=e.runtime,o}if("runtime"===n){let e=p(i);return o.positionals=e.positionals,Object.assign(o.flags,e.flags),o}if(c(n)){let e=f(n,i);Object.assign(o.flags,e.flags);let t=e.positionals[0];if(void 0===t)return o;if(t.startsWith("@"))return o.positionals=[t],e.positionals[1]&&(o.result={refLabel:e.positionals[1]}),o;let r=e.positionals[0],s=e.positionals[1];return j(r)&&j(s)&&e.positionals.length>=2?o.positionals=[r,s]:o.positionals=[e.positionals.join(" ")],o}if("fill"===n){let e=f(n,i);if(Object.assign(o.flags,e.flags),!(e.positionals.length>=2))return o.positionals=e.positionals,o;let[t,r,...s]=e.positionals;return t.startsWith("@")?(s.length>0?(o.positionals=[t,s.join(" ")],o.result={refLabel:r}):o.positionals=[t,r],o):(o.positionals=[t,[r,...s].join(" ")],o)}if("get"===n){let e=i[0],t=i[1];return void 0===e||void 0===t?o.positionals=i:t.startsWith("@")?(o.positionals=[e,t],i[2]&&(o.result={refLabel:i[2]})):o.positionals=[e,i.slice(1).join(" ")],o}if("swipe"===n||"type"===n){let e=f(n,i);return Object.assign(o.flags,e.flags),o.positionals=e.positionals,o}if("record"===n){let e=[];for(let t=0;t<i.length;t+=1){let n=i[t];if("--hide-touches"===n){o.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(o.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(o.flags.quality=Math.floor(e)),t+=1;continue}e.push(n)}return o.positionals=e,o}if("screenshot"===n){let e=[];for(let t=0;t<i.length;t+=1){let n=i[t],r=s({args:i,index:t,flags:o.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return o.positionals=e,o}return o.positionals=i,o}(l);u&&(t.push(u),n.push(e+1),o=!0)}return{actions:t,actionLines:n}}function O(e){let t=e.split(/\r?\n/),n={};for(let[e,i]of t.entries()){let t=i.trim();if(0===t.length||t.startsWith("#"))continue;if(x(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!h.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,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 r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&R.has(e)&&L(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&D.has(e)&&L(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&L(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&L(n,"retries",Math.floor(e))}}return n}function x(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function L(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function j(e){return!!e&&!Number.isNaN(Number(e))}function V(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${l(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(u(e,{runtimeIncludeAllPositionals:!0}));let o=`${i.join("\n")}
2
- `,s=`${t}.tmp-${process.pid}-${Date.now()}`;e.writeFileSync(s,o),e.renameSync(s,t)}function k(e){let n=t(e);for(let e of n)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new r("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return n.map(e=>e.toJSON()).filter(e=>null!==e)}function E(e){return`${e.map(e=>n(e).trimEnd()).join("\n---\n")}
3
- `}function G(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function C(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw H(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function P(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function W(e){return e.map((e,t)=>{if("string"==typeof e||P(e))return e;throw new r("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function F(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}function K(e,t){if(null==e)return{};if(!P(e))throw new r("INVALID_ARGS",`${t} expects a map.`);let n={};for(let[t,r]of Object.entries(e))("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=String(r));return n}function U(e,t){return P(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function q(e,t){if(e.appId)return e.appId;throw new r("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function z(e,t){if("string"==typeof t)return t;throw new r("INVALID_ARGS",`${e} expects a string value.`)}function Y(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function Z(e){throw H(`Maestro command "${e}" is not supported yet.`)}function H(e){throw new r("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${o}. If this syntax matters for your flows, comment there or open a focused issue at ${i}.`)}function J(e,t){return`${e},${t}`}function T(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw H('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function B(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 n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:"percent",x:Number(n[1]),y:Number(n[2])};throw H('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}export{C as assertOnlyKeys,y as buildReplayVarScope,w as collectReplayShellEnv,J as formatMaestroPoint,P as isPlainRecord,v as mergeReplayVarScopeValues,W as normalizeCommandList,F as normalizePlatform,T as parseAbsolutePoint,B as parseMaestroPoint,k as parseMaestroYamlDocuments,b as parseReplayCliEnvEntries,M as parseReplayScriptDetailed,K as readEnvMap,I as readReplayCliEnvEntries,O as readReplayScriptMetadata,$ as readReplayShellEnvSource,U as readTimeoutMs,q as requireAppId,z as requireStringValue,Y as resolveMaestroString,_ as resolveReplayAction,E as stringifyMaestroYamlDocuments,G as support_action,Z as unsupportedCommand,H as unsupportedMaestroSyntax,V as writeReplayScript};
1
+ import e from"node:fs";import{parseAllDocuments as t,stringify as n}from"yaml";import{AppError as r}from"./733.js";import{recordingQualityInputToExportQuality as i,readScreenshotScriptFlag as o,MAESTRO_COMPAT_TRACKER_URL as s,MAESTRO_NEW_ISSUE_URL as l}from"./9873.js";import{formatScriptStringLiteral as a,parseReplayOpenFlags as u,formatPortableActionLine as f,parseReplaySeriesFlags as c,parseReplayRuntimeFlags as p,isClickLikeCommand as h}from"./2577.js";let d=/^[A-Z_][A-Z0-9_]*$/,m=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,g="AD_VAR_";function A(e){return e.startsWith("AD_")}function v(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(A(e))throw v(e);t[e]=r}return{values:t}}function w(e,t){Object.assign(e.values,t)}function b(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(g))continue;let e=n.slice(g.length);0!==e.length&&d.test(e)&&(A(e)||(t[e]=r))}return t}function I(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!d.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(A(i))throw v(i);t[i]=n.slice(e+1)}return t}function $(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function S(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function _(e,t,n){return e.replace(m,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function N(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>_(e,t,n)),flags:R(e.flags,t,n)??{},runtime:R(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:_(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function R(e,t,n){return e?function e(t,n,r){return"string"==typeof t?_(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let D=new Set(["ios","android","macos","linux"]),M=new Set(["mobile","tv","desktop"]);function x(e){let t=[],n=[],s=e.split(/\r?\n/),l=!1;for(let[e,a]of s.entries()){let s=a.trim();if(0===s.length||s.startsWith("#"))continue;if(L(s)){if(l)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let f=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...s]=function(e){let t=[],n=0;for(;n<e.length&&!((n=function(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}(e,n))>=e.length);){let i='"'===e[n]?function(e,t){let n=!1,i=t+1;for(;i<e.length;i+=1){let t=e.charAt(i);if('"'===t&&!n)break;if(n){n=!1;continue}n="\\"===t}if(i>=e.length)throw new r("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,i+1)),nextCursor:i+1}}(e,n):function(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}(e,n);t.push(i.value),n=i.nextCursor}return t}(t);if(void 0===n||"context"===n)return null;let l={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){l.positionals=[];for(let e=0;e<s.length;e+=1){let t=s[e];if("-i"===t){l.flags.snapshotInteractiveOnly=!0;continue}if("-c"!==t){if("--raw"===t){l.flags.snapshotRaw=!0;continue}if("--force-full"===t){l.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<s.length){let t=Number(s[e+1]);Number.isFinite(t)&&t>=0&&(l.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<s.length){l.flags.snapshotScope=s[e+1],e+=1;continue}if("--backend"===t&&e+1<s.length){e+=1;continue}}}return l}if("open"===n){let e=u(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l.runtime=e.runtime,l}if("runtime"===n){let e=p(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l}if(h(n)){let e=c(n,s);Object.assign(l.flags,e.flags);let t=e.positionals[0];if(void 0===t)return l;if(t.startsWith("@"))return l.positionals=[t],e.positionals[1]&&(l.result={refLabel:e.positionals[1]}),l;let r=e.positionals[0],i=e.positionals[1];return V(r)&&V(i)&&e.positionals.length>=2?l.positionals=[r,i]:l.positionals=[e.positionals.join(" ")],l}if("fill"===n){let e=c(n,s);if(Object.assign(l.flags,e.flags),!(e.positionals.length>=2))return l.positionals=e.positionals,l;let[t,r,...i]=e.positionals;return t.startsWith("@")?(i.length>0?(l.positionals=[t,i.join(" ")],l.result={refLabel:r}):l.positionals=[t,r],l):(l.positionals=[t,[r,...i].join(" ")],l)}if("get"===n){let e=s[0],t=s[1];return void 0===e||void 0===t?l.positionals=s:t.startsWith("@")?(l.positionals=[e,t],s[2]&&(l.result={refLabel:s[2]})):l.positionals=[e,s.slice(1).join(" ")],l}if("swipe"===n||"type"===n){let e=c(n,s);return Object.assign(l.flags,e.flags),l.positionals=e.positionals,l}if("record"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t];if("--hide-touches"===n){l.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<s.length){let e=i(s[t+1]);void 0!==e&&(l.flags.quality=e),t+=1;continue}if("--max-size"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.screenshotMaxSize=Math.floor(e)),t+=1;continue}e.push(n)}return l.positionals=e,l}if("screenshot"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t],r=o({args:s,index:t,flags:l.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return l.positionals=e,l}return l.positionals=s,l}(a);f&&(t.push(f),n.push(e+1),l=!0)}return{actions:t,actionLines:n}}function O(e){let t=e.split(/\r?\n/),n={};for(let[e,i]of t.entries()){let t=i.trim();if(0===t.length||t.startsWith("#"))continue;if(L(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!d.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,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 r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&D.has(e)&&j(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&M.has(e)&&j(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&j(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&j(n,"retries",Math.floor(e))}}return n}function L(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function j(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function V(e){return!!e&&!Number.isNaN(Number(e))}function k(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${a(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(f(e,{runtimeIncludeAllPositionals:!0}));let o=`${i.join("\n")}
2
+ `,s=`${t}.tmp-${process.pid}-${Date.now()}`;e.writeFileSync(s,o),e.renameSync(s,t)}function E(e){let n=t(e);for(let e of n)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new r("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return n.map(e=>e.toJSON()).filter(e=>null!==e)}function G(e){return`${e.map(e=>n(e).trimEnd()).join("\n---\n")}
3
+ `}function C(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function P(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw J(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function W(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function F(e){return e.map((e,t)=>{if("string"==typeof e||W(e))return e;throw new r("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function K(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}function z(e,t){if(null==e)return{};if(!W(e))throw new r("INVALID_ARGS",`${t} expects a map.`);let n={};for(let[t,r]of Object.entries(e))("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=String(r));return n}function U(e,t){return W(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function q(e,t){if(e.appId)return e.appId;throw new r("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function Y(e,t){if("string"==typeof t)return t;throw new r("INVALID_ARGS",`${e} expects a string value.`)}function Z(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function H(e){throw J(`Maestro command "${e}" is not supported yet.`)}function J(e){throw new r("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${s}. If this syntax matters for your flows, comment there or open a focused issue at ${l}.`)}function T(e,t){return`${e},${t}`}function B(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw J('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function Q(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 n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:"percent",x:Number(n[1]),y:Number(n[2])};throw J('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}export{P as assertOnlyKeys,y as buildReplayVarScope,b as collectReplayShellEnv,T as formatMaestroPoint,W as isPlainRecord,w as mergeReplayVarScopeValues,F as normalizeCommandList,K as normalizePlatform,B as parseAbsolutePoint,Q as parseMaestroPoint,E as parseMaestroYamlDocuments,I as parseReplayCliEnvEntries,x as parseReplayScriptDetailed,z as readEnvMap,$ as readReplayCliEnvEntries,O as readReplayScriptMetadata,S as readReplayShellEnvSource,U as readTimeoutMs,q as requireAppId,Y as requireStringValue,Z as resolveMaestroString,N as resolveReplayAction,G as stringifyMaestroYamlDocuments,C as support_action,H as unsupportedCommand,J as unsupportedMaestroSyntax,k as writeReplayScript};
package/dist/src/4723.js CHANGED
@@ -1 +1 @@
1
- import e from"node:fs";import t from"node:path";import{AppError as n}from"./733.js";import{resolveUserPath as r}from"./9612.js";let o=new Set(["1","true","yes","on"]),i=new Set(["0","false","no","off"]);function a(e){return`AGENT_DEVICE_${e.replace(/([A-Z])/g,"_$1").replace(/[^A-Za-z0-9_]/g,"_").toUpperCase()}`}function s(e,t,r,o){if(e.multiple)return(Array.isArray(t)?t:[t]).map(t=>s({...e,multiple:!1},t,r,o));if("boolean"===e.type){var i=t,a=r,u=o;if("boolean"==typeof i)return i;if("string"==typeof i){let e=l(i);if(void 0!==e)return e}throw new n("INVALID_ARGS",`Invalid value for "${u}" in ${a}. Expected boolean.`)}if("booleanOrString"===e.type){if("boolean"==typeof t)return t;if("string"==typeof t&&void 0!==l(t))return l(t);if("string"==typeof t&&t.trim().length>0)return t;throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected boolean or non-empty string.`)}if("string"===e.type){if("string"==typeof t&&t.trim().length>0)return t;throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected non-empty string.`)}if("enum"===e.type){if(void 0!==e.setValue){var f=e,y=t,p=r,m=o;let i=f.setValue;if(y===i)return i;if("string"==typeof y){let e=y.trim();if(""===e||"true"===e||"1"===e)return i;if("false"===e||"0"===e)return}if(!0===y)return i;if(!1!==y)throw new n("INVALID_ARGS",`Invalid value for "${m}" in ${p}. Expected boolean-like value for enum flag.`);return}if("string"!=typeof t||!e.enumValues?.includes(t))throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected one of: ${e.enumValues?.join(", ")}.`);return t}let c="number"==typeof t?t:"string"==typeof t?Number(t):NaN;if(!Number.isFinite(c)||!Number.isInteger(c))throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected integer.`);if("number"==typeof e.min&&c<e.min)throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Must be >= ${e.min}.`);if("number"==typeof e.max&&c>e.max)throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Must be <= ${e.max}.`);return c}function l(e){let t=e.trim().toLowerCase();return!!o.has(t)||!i.has(t)&&void 0}let u=[{key:"stateDir",type:"string",path:!0},{key:"daemonBaseUrl",type:"string"},{key:"daemonAuthToken",type:"string"},{key:"daemonTransport",type:"enum",enumValues:["auto","socket","http"]},{key:"daemonServerMode",type:"enum",enumValues:["socket","http","dual"]},{key:"tenant",type:"string"},{key:"sessionIsolation",type:"enum",enumValues:["none","tenant"]},{key:"runId",type:"string"},{key:"leaseId",type:"string"},{key:"leaseBackend",type:"enum",enumValues:["ios-simulator","ios-instance","android-instance"]},{key:"platform",type:"enum",enumValues:["ios","macos","android","linux","apple"]},{key:"target",type:"enum",enumValues:["mobile","tv","desktop"]},{key:"device",type:"string"},{key:"udid",type:"string"},{key:"serial",type:"string"},{key:"iosSimulatorDeviceSet",type:"string",path:!0,env:!1},{key:"androidDeviceAllowlist",type:"string"},{key:"session",type:"string"},{key:"metroProjectRoot",type:"string",path:!0},{key:"metroKind",type:"enum",enumValues:["auto","react-native","expo"]},{key:"metroPublicBaseUrl",type:"string"},{key:"metroProxyBaseUrl",type:"string"},{key:"metroBearerToken",type:"string"},{key:"metroPreparePort",type:"int",min:1,max:65535},{key:"metroListenHost",type:"string"},{key:"metroStatusHost",type:"string"},{key:"metroStartupTimeoutMs",type:"int",min:1},{key:"metroProbeTimeoutMs",type:"int",min:1},{key:"metroRuntimeFile",type:"string",path:!0},{key:"metroNoReuseExisting",type:"boolean"},{key:"metroNoInstallDeps",type:"boolean"}],f=new Map(u.map(e=>[e.key,e]));function y(e){let t=e.env??process.env;return r(e.configPath,{cwd:e.cwd,env:t})}function p(o){let i=function(o){let i,a,l=o.env??process.env,u=y(o);if(!e.existsSync(u))throw new n("INVALID_ARGS",`Remote config file not found: ${u}`);try{i=e.readFileSync(u,"utf8")}catch(e){throw new n("INVALID_ARGS",`Failed to read remote config file: ${u}`,{cause:e instanceof Error?e.message:String(e)})}try{a=JSON.parse(i)}catch(e){throw new n("INVALID_ARGS",`Invalid JSON in remote config file: ${u}`,{cause:e instanceof Error?e.message:String(e)})}if(!a||"object"!=typeof a||Array.isArray(a))throw new n("INVALID_ARGS",`Remote config file must contain a JSON object: ${u}`);let p={},m=a,c=t.dirname(u);for(let[e,t]of Object.entries(m)){let o=f.get(e);if(!o)throw new n("INVALID_ARGS",`Unsupported remote config key "${e}" in remote config file ${u}.`);let i=s(o,t,`remote config file ${u}`,e);p[o.key]="string"==typeof i&&"path"in o&&o.path?r(i,{cwd:c,env:l}):i}return{resolvedPath:u,profile:p}}(o);return{resolvedPath:i.resolvedPath,profile:function(...e){let t={};for(let n of e)if(n)for(let e of u){let r=n[e.key];void 0!==r&&(t[e.key]=r)}return t}(function(e=process.env){let t={};for(let n of u){let r=(function(e){let t=f.get(e);return t?.env===!1?[]:[a(e)]})(n.key).map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);r&&(t[n.key]=s(n,r.value,`environment variable ${r.name}`,r.name))}return t}(o.env),i.profile)}}export{u as REMOTE_CONFIG_FIELD_SPECS,a as buildPrimaryEnvVarName,s as parseSourceValue,y as resolveRemoteConfigPath,p as resolveRemoteConfigProfile};
1
+ import e from"node:fs";import t from"node:path";import{AppError as n}from"./733.js";import{PLATFORM_SELECTORS as r}from"./5910.js";import{resolveUserPath as o}from"./9612.js";let i=new Set(["1","true","yes","on"]),a=new Set(["0","false","no","off"]);function s(e){return`AGENT_DEVICE_${e.replace(/([A-Z])/g,"_$1").replace(/[^A-Za-z0-9_]/g,"_").toUpperCase()}`}function l(e,t,r,o){if(e.multiple)return(Array.isArray(t)?t:[t]).map(t=>l({...e,multiple:!1},t,r,o));if("boolean"===e.type){var i=t,a=r,s=o;if("boolean"==typeof i)return i;if("string"==typeof i){let e=u(i);if(void 0!==e)return e}throw new n("INVALID_ARGS",`Invalid value for "${s}" in ${a}. Expected boolean.`)}if("booleanOrString"===e.type){if("boolean"==typeof t)return t;if("string"==typeof t&&void 0!==u(t))return u(t);if("string"==typeof t&&t.trim().length>0)return t;throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected boolean or non-empty string.`)}if("string"===e.type){if("string"==typeof t&&t.trim().length>0)return t;throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected non-empty string.`)}if("enum"===e.type){if(void 0!==e.setValue){var f=e,y=t,p=r,m=o;let i=f.setValue;if(y===i)return i;if("string"==typeof y){let e=y.trim();if(""===e||"true"===e||"1"===e)return i;if("false"===e||"0"===e)return}if(!0===y)return i;if(!1!==y)throw new n("INVALID_ARGS",`Invalid value for "${m}" in ${p}. Expected boolean-like value for enum flag.`);return}if("string"!=typeof t||!e.enumValues?.includes(t))throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected one of: ${e.enumValues?.join(", ")}.`);return t}let c="number"==typeof t?t:"string"==typeof t?Number(t):NaN;if(!Number.isFinite(c)||!Number.isInteger(c))throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Expected integer.`);if("number"==typeof e.min&&c<e.min)throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Must be >= ${e.min}.`);if("number"==typeof e.max&&c>e.max)throw new n("INVALID_ARGS",`Invalid value for "${o}" in ${r}. Must be <= ${e.max}.`);return c}function u(e){let t=e.trim().toLowerCase();return!!i.has(t)||!a.has(t)&&void 0}let f=[{key:"stateDir",type:"string",path:!0},{key:"daemonBaseUrl",type:"string"},{key:"daemonAuthToken",type:"string"},{key:"daemonTransport",type:"enum",enumValues:["auto","socket","http"]},{key:"daemonServerMode",type:"enum",enumValues:["socket","http","dual"]},{key:"tenant",type:"string"},{key:"sessionIsolation",type:"enum",enumValues:["none","tenant"]},{key:"runId",type:"string"},{key:"leaseId",type:"string"},{key:"leaseBackend",type:"enum",enumValues:["ios-simulator","ios-instance","android-instance"]},{key:"platform",type:"enum",enumValues:r},{key:"target",type:"enum",enumValues:["mobile","tv","desktop"]},{key:"device",type:"string"},{key:"udid",type:"string"},{key:"serial",type:"string"},{key:"iosSimulatorDeviceSet",type:"string",path:!0,env:!1},{key:"androidDeviceAllowlist",type:"string"},{key:"session",type:"string"},{key:"metroProjectRoot",type:"string",path:!0},{key:"metroKind",type:"enum",enumValues:["auto","react-native","expo"]},{key:"metroPublicBaseUrl",type:"string"},{key:"metroProxyBaseUrl",type:"string"},{key:"metroBearerToken",type:"string"},{key:"metroPreparePort",type:"int",min:1,max:65535},{key:"metroListenHost",type:"string"},{key:"metroStatusHost",type:"string"},{key:"metroStartupTimeoutMs",type:"int",min:1},{key:"metroProbeTimeoutMs",type:"int",min:1},{key:"metroRuntimeFile",type:"string",path:!0},{key:"metroNoReuseExisting",type:"boolean"},{key:"metroNoInstallDeps",type:"boolean"}],y=new Map(f.map(e=>[e.key,e]));function p(e){let t=e.env??process.env;return o(e.configPath,{cwd:e.cwd,env:t})}function m(r){let i=function(r){let i,a,s=r.env??process.env,u=p(r);if(!e.existsSync(u))throw new n("INVALID_ARGS",`Remote config file not found: ${u}`);try{i=e.readFileSync(u,"utf8")}catch(e){throw new n("INVALID_ARGS",`Failed to read remote config file: ${u}`,{cause:e instanceof Error?e.message:String(e)})}try{a=JSON.parse(i)}catch(e){throw new n("INVALID_ARGS",`Invalid JSON in remote config file: ${u}`,{cause:e instanceof Error?e.message:String(e)})}if(!a||"object"!=typeof a||Array.isArray(a))throw new n("INVALID_ARGS",`Remote config file must contain a JSON object: ${u}`);let f={},m=a,c=t.dirname(u);for(let[e,t]of Object.entries(m)){let r=y.get(e);if(!r)throw new n("INVALID_ARGS",`Unsupported remote config key "${e}" in remote config file ${u}.`);let i=l(r,t,`remote config file ${u}`,e);f[r.key]="string"==typeof i&&"path"in r&&r.path?o(i,{cwd:c,env:s}):i}return{resolvedPath:u,profile:f}}(r);return{resolvedPath:i.resolvedPath,profile:function(...e){let t={};for(let n of e)if(n)for(let e of f){let r=n[e.key];void 0!==r&&(t[e.key]=r)}return t}(function(e=process.env){let t={};for(let n of f){let r=(function(e){let t=y.get(e);return t?.env===!1?[]:[s(e)]})(n.key).map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);r&&(t[n.key]=l(n,r.value,`environment variable ${r.name}`,r.name))}return t}(r.env),i.profile)}}export{f as REMOTE_CONFIG_FIELD_SPECS,s as buildPrimaryEnvVarName,l as parseSourceValue,p as resolveRemoteConfigPath,m as resolveRemoteConfigProfile};
@@ -0,0 +1,2 @@
1
+ import{AppError as e}from"./733.js";let t=["ios","macos","android","linux","web","apple"],i=["mobile","tv","desktop"];function r(e){return e}function o(e){return"apple"===e||"ios"===e||"macos"===e}function l(e,t){return!t||("apple"===t?o(e):e===t)}function a(e){return"macos"===e||"desktop"===e?"macOS":"tv"===e?"tvOS":"iOS"}function n(e){let{simulatorSetPath:t,platform:i,target:r}=e;if(t&&"macos"!==i&&"desktop"!==r)return t}async function m(t,i,r={}){let a=t,n=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(i.platform&&(a=a.filter(e=>l(e.platform,i.platform))),i.target&&(a=a.filter(e=>(e.target??"mobile")===i.target)),i.udid){let t=a.find(e=>e.id===i.udid&&o(e.platform));if(!t)throw new e("DEVICE_NOT_FOUND",`No Apple device with UDID ${i.udid}`);return t}if(i.serial){let t=a.find(e=>e.id===i.serial&&"android"===e.platform);if(!t)throw new e("DEVICE_NOT_FOUND",`No Android device with serial ${i.serial}`);return t}if(i.deviceName){let t=n(i.deviceName),r=a.find(e=>n(e.name)===t);if(!r)throw new e("DEVICE_NOT_FOUND",`No device named ${i.deviceName}`);return r}let d=a[0];if(void 0!==d&&1===a.length)return d;if(0===a.length){var f;let t=r.simulatorSetPath;if(t&&(!(f=i.platform)||"apple"===f||"ios"===f))throw new e("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:t,hint:`The simulator set at "${t}" appears to be empty. Create a simulator first:
2
+ xcrun simctl --set "${t}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:i});throw new e("DEVICE_NOT_FOUND","No devices found",{selector:i})}let p=a.filter(e=>"device"!==e.kind);p.length>0&&(a=p);let c=a.filter(e=>e.booted),s=c[0];if(void 0!==s&&1===c.length)return s;let u=c[0]??a[0];if(void 0===u)throw new e("DEVICE_NOT_FOUND","No devices found",{selector:i});return u}export{i as DEVICE_TARGETS,t as PLATFORM_SELECTORS,o as isApplePlatform,l as matchesPlatformSelector,r as normalizePlatformSelector,a as resolveApplePlatformName,n as resolveAppleSimulatorSetPathForSelector,m as resolveDevice};