agent-device 0.17.2 → 0.17.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.2.apk → agent-device-android-multitouch-helper-0.17.4.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.4.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.2.manifest.json → agent-device-android-multitouch-helper-0.17.4.manifest.json} +4 -4
- package/android-snapshot-helper/README.md +3 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.2.apk → agent-device-android-snapshot-helper-0.17.4.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.4.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.2.manifest.json → agent-device-android-snapshot-helper-0.17.4.manifest.json} +6 -6
- package/dist/src/123.js +1 -1
- package/dist/src/1231.js +1 -1
- package/dist/src/1352.js +1 -1
- package/dist/src/221.js +2 -2
- package/dist/src/2403.js +3 -3
- package/dist/src/2415.js +37 -29
- package/dist/src/4012.js +4 -0
- package/dist/src/5611.js +1 -0
- package/dist/src/5827.js +1 -0
- package/dist/src/6088.js +1 -0
- package/dist/src/6133.js +1 -0
- package/dist/src/7847.js +1 -1
- package/dist/src/9471.js +1 -1
- package/dist/src/9542.js +6 -3
- package/dist/src/9616.js +2 -1
- package/dist/src/9818.js +1 -1
- package/dist/src/android-snapshot-helper.d.ts +0 -1
- package/dist/src/android.js +5 -5
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +10 -10
- package/dist/src/args.js +53 -14
- package/dist/src/batch.js +1 -1
- package/dist/src/cli-output.js +30 -0
- package/dist/src/cli.js +15 -16
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +52 -0
- package/dist/src/contracts.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/generic.js +5 -5
- package/dist/src/index.d.ts +127 -8
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +3 -3
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +14 -0
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session.js +8 -10
- package/dist/src/snapshot.js +2 -2
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +14 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +297 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +327 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +122 -173
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +153 -5
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +171 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -10
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +64 -18
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +200 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +450 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +82 -178
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +425 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +77 -6
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +10 -1
- package/ios-runner/README.md +5 -5
- package/ios-runner/RUNNER_PROTOCOL.md +0 -1
- package/package.json +3 -3
- package/server.json +2 -2
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.2.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.2.apk.sha256 +0 -1
- package/dist/src/1534.js +0 -1
- package/dist/src/1620.js +0 -1
- package/dist/src/1644.js +0 -2
- package/dist/src/2284.js +0 -1
- package/dist/src/2474.js +0 -1
- package/dist/src/2672.js +0 -1
- package/dist/src/3393.js +0 -1
- package/dist/src/5898.js +0 -1
- package/dist/src/695.js +0 -1
- package/dist/src/7455.js +0 -1
- package/dist/src/8173.js +0 -27
- package/dist/src/8407.js +0 -1
- package/dist/src/8699.js +0 -1
- package/dist/src/9238.js +0 -4
- package/dist/src/9673.js +0 -1
- package/dist/src/9974.js +0 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ It works with native iOS and Android apps, plus apps built with Expo, Flutter, a
|
|
|
27
27
|
|
|
28
28
|
## Capabilities
|
|
29
29
|
|
|
30
|
-
- **Inspect** real app UI through
|
|
30
|
+
- **Inspect** real app UI through structured accessibility snapshots, interactive refs like `@e3`, selectors, and React Native component trees.
|
|
31
31
|
- **Interact** by opening apps, tapping, typing, scrolling, performing gestures, waiting, asserting state, handling alerts, and closing sessions.
|
|
32
32
|
- **Capture evidence** with screenshots, videos, logs, traces, network traffic, performance samples, crash context, and React profiles.
|
|
33
33
|
- **Replay workflows** by recording `.ad` scripts for local runs, CI, repeatable e2e checks, and strict Maestro YAML export when a flow needs to run in Maestro.
|
|
@@ -118,7 +118,7 @@ Appium, Detox, and Maestro are traditional mobile automation frameworks. `agent-
|
|
|
118
118
|
|
|
119
119
|
## Used By
|
|
120
120
|
|
|
121
|
-
Used by teams and developers at Callstack, Expensify, Shopify, Kindred, Total Wine & More, LegendList, HerLyfe, App & Flow, and more.
|
|
121
|
+
Used by teams and developers at Callstack, JPMorgan Chase, Expensify, Shopify, Kindred, Total Wine & More, LegendList, HerLyfe, App & Flow, and more.
|
|
122
122
|
|
|
123
123
|
## Documentation
|
|
124
124
|
|
|
Binary file
|
package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.4.apk.sha256
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
acbcf7812e197c1c9a9185396de63a54a42f05000ea354f4ab338d1e3b233c87 agent-device-android-multitouch-helper-0.17.4.apk
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-multitouch-helper",
|
|
3
|
-
"version": "0.17.
|
|
4
|
-
"assetName": "agent-device-android-multitouch-helper-0.17.
|
|
5
|
-
"sha256": "
|
|
3
|
+
"version": "0.17.4",
|
|
4
|
+
"assetName": "agent-device-android-multitouch-helper-0.17.4.apk",
|
|
5
|
+
"sha256": "acbcf7812e197c1c9a9185396de63a54a42f05000ea354f4ab338d1e3b233c87",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.multitouchhelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 17004,
|
|
8
8
|
"instrumentationRunner": "com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation",
|
|
9
9
|
"statusProtocol": "android-multitouch-helper-v1"
|
|
10
10
|
}
|
|
@@ -43,6 +43,9 @@ The `-t` install flag is required because the helper is a test-only instrumentat
|
|
|
43
43
|
Devices or providers that block test-package installs must allow this package before helper capture
|
|
44
44
|
can run.
|
|
45
45
|
|
|
46
|
+
`waitForIdleTimeoutMs` defaults to `500`, which is a maximum wait, not a fixed sleep. Direct helper
|
|
47
|
+
invocations can pass `0` when immediate capture during ongoing animation is preferred.
|
|
48
|
+
|
|
46
49
|
## Output Contract
|
|
47
50
|
|
|
48
51
|
The APK emits instrumentation status records using
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b93505dc2bc839c7cf77ec598bcc08cc89e33ac6e758680a3d5bc39d6d56c42c agent-device-android-snapshot-helper-0.17.4.apk
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-snapshot-helper",
|
|
3
|
-
"version": "0.17.
|
|
4
|
-
"releaseTag": "v0.17.
|
|
5
|
-
"assetName": "agent-device-android-snapshot-helper-0.17.
|
|
3
|
+
"version": "0.17.4",
|
|
4
|
+
"releaseTag": "v0.17.4",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.17.4.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.17.
|
|
7
|
+
"sha256": "b93505dc2bc839c7cf77ec598bcc08cc89e33ac6e758680a3d5bc39d6d56c42c",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.17.4.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 17004,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
package/dist/src/123.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e,{promises as t}from"node:fs";import{Worker as n}from"node:worker_threads";import a from"node:path";import{fileURLToPath as r}from"node:url";import{appendScreenshotScriptFlags as i}from"./695.js";import{normalizeRef as s,centerOfRect as o,buildSnapshotPresentationKey as l,findNodeByRef as d}from"./1644.js";import{emitDiagnostic as u}from"./7599.js";import{asAppError as c,toAppErrorCode as p,AppError as h}from"./9152.js";import{computeScreenshotDiffPixels as f,PNG as m,toBuffer as w,decodePng as g}from"./9010.js";import{successText as b}from"./1534.js";import{expandRect as y,intersectArea as k,unionRects as v,rectCenter as x,clamp as A,normalizedRect as M,squaredDistance as R}from"./4778.js";import{whichCmd as N,runCmd as I}from"./9818.js";import{buildMobileSnapshotPresentation as P,now as S,sleep as _,formatRole as O,isNodeVisibleInEffectiveViewport as D,formatSnapshotLine as E,shouldScopeFind as C,scrollCommand as T,longPressCommand as U,focusCommand as $,toBackendResult as L,displayLabel as B,swipeCommand as G,resolveInteractionTarget as X,toBackendContext as Y,requireIntInRange as K,pinchCommand as q,buildSnapshotDisplayLines as F}from"./1620.js";import{findSelectorChainMatch as V,extractNodeText as j,findSnapshotAncestor as H,buildSelectorChainForNode as z,resolveSelectorChain as W,findNodeByLabel as J,resolveRefLabel as Z,isNodeVisible as Q,extractReadableText as ee,buildSnapshotNodeByIndex as et,formatSelectorFailure as en,normalizeType as ea,isNodeEditable as er,isFillableType as ei}from"./7847.js";import{findBestMatchesByLocator as es}from"./7556.js";import"./9673.js";import{parseSelectorChain as eo}from"./8407.js";import{resolveAppsFilter as el,assertResolvedAppsFilter as ed}from"./3675.js";let eu=/^-?\d+(\.\d+)?$/,ec=/^[^\s"\\]+$/,ep=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),eh=new Map([["--count","count"],["--pause-ms","pauseMs"]]),ef=new Map([["--delay-ms","delayMs"]]);function em(e){return"click"===e||"press"===e}function ew(e){return em(e)||"longpress"===e}function eg(e){return"type"===e||"fill"===e}function eb(e){return ek(e,ev)}function ey(e){return JSON.stringify(e)}function ek(e,t){return t(e)?e:ey(e)}function ev(e){return ex(e)&&e.startsWith("@")||eu.test(e)}function ex(e){return ec.test(e)}function eA(e){let t=(e.positionals??[]).map(e=>eb(e));return[e.command,...t].join(" ")}function eM(e,t){let n=t.flags??{};if(em(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}eg(t.command)&&"number"==typeof n.delayMs&&e.push("--delay-ms",String(n.delayMs))}function eR(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",ek(t.metroHost,ex)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",ek(t.bundleUrl,ex)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",ek(t.launchUrl,ex)))}function eN(e,t){let n=[],a={},r=em(e)?ep:"swipe"===e?eh:eg(e)?ef:void 0;for(let i=0;i<t.length;i+=1){let s=t[i];if(em(e)&&"--double-tap"===s){a.doubleTap=!0;continue}let o=t[i+1];if(em(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=eP(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 eI(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=eP(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 eP(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function eS(e){var t;let n=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}n.push(t)}let r=eI(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 e_(e,t={}){let n=[e.command];if("snapshot"===e.command)e.flags?.snapshotInteractiveOnly&&n.push("-i"),e.flags?.snapshotCompact&&n.push("-c"),"number"==typeof e.flags?.snapshotDepth&&n.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&n.push("-s",eb(e.flags.snapshotScope)),e.flags?.snapshotRaw&&n.push("--raw");else if("open"===e.command){for(let t of e.positionals??[])n.push(eb(t));e.flags?.relaunch&&n.push("--relaunch"),eR(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(ek(t,ex));eR(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(ek(n,ex)),a))e.push(eb(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}(n,e);else if("screenshot"===e.command){for(let t of e.positionals??[])n.push(eb(t));i(n,e.flags)}else{for(let t of e.positionals??[])n.push(eb(t));eM(n,e)}return n.join(" ")}let eO=["status","get","dismiss","enter","return"];function eD(e){return eO.includes(e)}function eE(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}let eC=/\b(logbox|redbox|reload js|copy stack|component stack|call stack|runtime error|open debugger to view warnings)\b/,eT=/\b(redbox|runtime error|reload js|copy stack|component stack|call stack)\b/,eU=[/\b[\w.$<>/-]+\.(?:tsx?|jsx?):\d+(?::\d+)?\b/,/\b[\w.$<>/-]+\.(?:tsx?|jsx?)\s+\(\d+:\d+\)/],e$=[/^!,\s+/,/^(warn|warning|error):\s+/,/\b(?:possible\s+)?unhandled (?:promise )?rejection\b/],eL=["open debugger to view warnings","getsnapshot should be cached to avoid an infinite loop",'unique "key" prop',"unique 'key' prop","virtualizedlists should never be nested","failed prop type"],eB=new Set(["x","\xd7","✕","✖","⨯"]);function eG(e){return eX(e)}function eX(e){var t,n,a,r,i,s,l,d,u,c;let p,h,f,m,w,g,b,y,k=(p=(t=e).map(eF).join("\n").toLowerCase(),h=e1(t,ez),f=e1(t,eJ),m=e1(t,ej,eZ),w=e1(t,eH),g=(n=p,eU.some(e=>e.test(n))),b=eV(p),y=(a=p,r=h,i=f,r.length>0||i.length>0||/\b(reload js|copy stack)\b/.test(a)),{dismissNodes:h,minimizeNodes:f,collapsedNodes:m,redBox:(s=p,l=g,d=y,eT.test(s)||eV(s)||l&&d),detected:(u={text:p,hasReactNativeStackFrame:g,hasOverlayControl:y,hasControllessRedBoxText:b,collapsedNodes:m,openDebuggerWarningNodes:w}).collapsedNodes.length>0||u.openDebuggerWarningNodes.length>0||u.hasControllessRedBoxText||u.hasOverlayControl&&(c=u.text,eC.test(c)||u.hasReactNativeStackFrame)}),v=k.detected?function(e){let t=e4(e.dismissNodes,e2);if(t){let e;var n,a=t,r=(n=t,(e=e5(n)?.trim().toLowerCase())&&eW(e)?"dismiss":"close");if(!a.rect)throw Error("React Native overlay target node must have rect");return{action:r,point:o(a.rect),rect:a.rect,ref:a.ref,label:e5(a)}}let i=e4(e.collapsedNodes.filter(eQ),e3);return i?.rect?{action:"close-collapsed-banner",point:function(e){var t,n;if(!e.rect)throw Error("Collapsed React Native warning node must have rect");let a=Math.min(e.rect.height,52),r=Math.min(36,Math.max(18,.45*a));return{x:Math.round((t=e.rect.x+e.rect.width-r,n=e.rect.x+1,Math.min(e.rect.x+e.rect.width-1,Math.max(n,t)))),y:Math.round(e.rect.y+a/2)}}(i),rect:i.rect,ref:i.ref,label:e5(i)}:null}(k):null;return{detected:k.detected,redBox:k.redBox,dismissNodes:k.dismissNodes,minimizeNodes:k.minimizeNodes,collapsedNodes:k.collapsedNodes,primaryAction:v}}function eY(e){return[...e.dismissNodes,...e.minimizeNodes,...e.collapsedNodes]}function eK(e){var t;return ej(e.label?.trim())&&!!(t=e.rect)&&t.x<=1&&t.y<=1&&t.width>=300&&t.height>=600}function eq(e,t){let n=e.label?.trim();return!!n&&!!eK(e)&&t.some(e=>e.label?.trim()===n&&e0(e))}function eF(e){return[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(" ")}function eV(e){return/\buncaught\b/.test(e)&&/unable to download asset/.test(e)}function ej(e){let t=e?.trim().toLowerCase();return!!t&&(eL.some(e=>t.includes(e))||e$.some(e=>e.test(t)))}function eH(e){return e.includes("open debugger to view warnings")||/^!,\s+open debugger\b/.test(e)}function ez(e){var t,n;return eW(e)||(t=e,/^close(?:\s*\([^)]*\))?$/i.test(t))||(n=e,eB.has(n))}function eW(e){return/^dismiss(?:\s*\([^)]*\))?$/i.test(e)}function eJ(e){return/^minimi[sz]e(?:\b|\s|\()/i.test(e)}function eZ(e){return!e.rect||e.rect.height<=180}function eQ(e){let t=e5(e)?.trim().toLowerCase()??"";return(eH(t)||/^!,\s+/.test(t))&&e0(e)}function e0(e){return!!e.rect&&e.rect.width>=120&&e.rect.height>=36&&e.rect.height<=180}function e1(e,t,n=()=>!0){let a=[];for(let r of e)r.ref&&n(r)&&[r.label,r.value,r.identifier].map(e=>e?.trim().toLowerCase()).filter(e=>!!e).some(e=>t(e))&&a.push(r);return a}function e2(e){var t;let n;return[+(!0===(n=[e.type,e.role,e.subrole].join(" ").toLowerCase(),/\b(button|menuitem|link)\b/.test(n))),+(!0===e.hittable),-((t=e.rect)?t.width*t.height:1/0)]}function e4(e,t){let n=e.filter(e=>e.rect);return 0===n.length?null:n.sort((e,n)=>(function(e,t){for(let n=0;n<e.length;n+=1){let a=e[n]-t[n];if(0!==a)return a}return 0})(t(n),t(e)))[0]??null}function e3(e){return[+(!0===e.hittable),e.rect?.width??0,e.rect?.y??0]}function e5(e){return e.label??e.value??e.identifier}class e8 extends Error{}let e6=null,e9=!1,e7=!1,te=0,tt=new Map;function tn(e){e9=!0,e7||(e7=!0,u({level:"warn",phase:"png_worker_unavailable",data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function ta(e){let t=tt.get(e.id);t&&(tt.delete(e.id),ts(),e.ok?t.resolve(e.result):t.reject(new h(p(e.error.code),e.error.message,e.error.details)))}function tr(e,t){e6===e&&(tn(t.message),e6=null,e.terminate().catch(()=>{}),ti(new e8(`PNG worker failed: ${t.message}`)))}function ti(e){let t=[...tt.values()];for(let n of(tt.clear(),t))n.reject(e)}function ts(){e6&&(tt.size>0?e6.ref():e6.unref())}function to(){if(e9)return null;if(e6)return e6;let t=function(t,n){try{let i=r(t),s=a.extname(i)||".js";return[a.join(a.dirname(i),`${n}${s}`),a.join(a.dirname(i),"internal",`${n}${s}`)].find(t=>e.existsSync(t))??null}catch{return null}}(import.meta.url,"png-worker");if(!t)return tn("worker entry module not found next to the current module"),null;try{let e=new n(t,{execArgv:t.endsWith(".ts")?["--experimental-strip-types"]:[]});return e.on("message",ta),e.on("error",t=>{tr(e,t)}),e.on("exit",t=>{tr(e,Error(`PNG worker exited with code ${t}`))}),e.unref(),e6=e,e}catch(e){return tn(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}async function tl(e,t){try{return await function(e){let t=to();if(!t)return Promise.reject(new e8("PNG worker is unavailable"));let n=te+=1;return new Promise((a,r)=>{tt.set(n,{resolve:a,reject:r}),ts();try{t.postMessage({...e,id:n})}catch(e){tt.delete(n),ts(),r(new e8(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}(e)}catch(e){if(e instanceof e8)return t();throw e}}function td(){to()}async function tu(){let e=e6;e6=null,ti(new e8("PNG worker terminated")),e&&await e.terminate()}async function tc(e,t){let n=await tl({kind:"decode",png:e,label:t},()=>{let n=g(e,t);return{kind:"decode",width:n.width,height:n.height,data:n.data}});return new m({width:n.width,height:n.height,data:w(n.data)})}async function tp(e){return w((await tl({kind:"encode",width:e.width,height:e.height,data:e.data},()=>({kind:"encode",png:m.sync.write(e)}))).png)}async function th(e){let{kind:t,...n}=await tl({kind:"diff-pixels",...e},()=>({kind:"diff-pixels",...f(e)}));return{...n,diffData:w(n.diffData)}}async function tf(e,n){if(!Number.isInteger(n)||n<1)throw new h("INVALID_ARGS","Screenshot max size must be a positive integer");let a=await tc(await t.readFile(e),"screenshot"),r=Math.max(a.width,a.height);if(r<=n)return;let i=n/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 m({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 t.writeFile(e,await tp(l))}async function tm(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new h("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw c(e)}}async function tw(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new h("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 c(e)}}async function tg(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw c(e)}}let tb=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new h("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await tw(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 tf(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...b(`Saved screenshot: ${a.path}`)}},ty=[0,187,255,255];function tk(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 tv(e,t,n){return Math.min(Math.max(e,t),n)}let tx=[{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(!tM(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 tx){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;tM(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 tM(e,t,n){return 1===e[n]&&1!==t[n]}let tR={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},tN={leading:20,trailing:20,separator:10,unknown:0,background:-30};function tI(e){return"background"!==e.likelyKind}function tP(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function tS(e,t){let n,a=0;for(let r of t){let t=tC(e,r.rect);t<=a||(a=t,n=r)}return n}function t_(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,tC(t,a=n.rect)>0||Math.abs(x(t).y-x(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=v([e.rect,n.rect])}return t}function tO(e,t){let n,a=x(e);for(let e of t){let t=Math.sqrt(R(a,x(e.rect)));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tD(e){let t=tE(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function tE(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tC(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}async function tT(e){if(await N("tesseract"))try{let[t,n]=await Promise.all([t$(e.baselinePath),t$(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tU(t.stdout,e.width,e.height),r=tU(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tK(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(tK(o.text)!==t)continue;let l=x(e.normalizedRect),d=R(l,x(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=tV(t.rect.width/e.rect.width),r=tV(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)=>tL(t)-tL(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-tq(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(tB).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tG(t)-tG(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 tU(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=tY(t,i,"level"),a=tX(t,i,"text").trim(),r=tY(t,i,"conf");if(5!==n||(o=a,!/[\p{L}\p{N}]/u.test(o))||r<0)continue;let l=tY(t,i,"left"),d=tY(t,i,"top"),u=tY(t,i,"width"),c=tY(t,i,"height");u<=0||c<=0||s.push({key:[tX(t,i,"page_num"),tX(t,i,"block_num"),tX(t,i,"par_num"),tX(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=v(a.map(e=>e.rect)),i=Math.round(100*tq(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:M({x:tF(r.x/t),y:tF(r.y/n),width:tF(r.width/t),height:tF(r.height/n)})}})(e,t,n)).filter(e=>null!==e)}function t$(e){return I("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tL(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 tB(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 tG(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tX(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tY(e,t,n){let a=Number(tX(e,t,n));return Number.isFinite(a)?a:0}function tK(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tq(e){return e.reduce((e,t)=>e+t,0)/e.length}function tF(e){return Math.round(100*e*100)/100}function tV(e){return Math.round(1e3*e)/1e3}function tj(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tH(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tz(e){return`#${tW(e.r)}${tW(e.g)}${tW(e.b)}`}function tW(e){return e.toString(16).padStart(2,"0")}function tJ(e){return Math.round(100*e*100)/100}let tZ=255*Math.sqrt(3);async function tQ(e,n,r={}){var i,s,o,l,d;let u,c,p,h;await t0(e,"Baseline image not found"),await t0(n,"Current screenshot not found");let f=r.outputPath,[w,g]=await Promise.all([t.readFile(e),t.readFile(n)]),[b,v]=await Promise.all([tc(w,"baseline screenshot"),tc(g,"current screenshot")]);t1(b.width,b.height,"baseline screenshot",r.maxPixels),t1(v.width,v.height,"current screenshot",r.maxPixels);let x=r.threshold??.1;if(b.width!==v.width||b.height!==v.height){let e=b.width*b.height;return await t2(r.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:b.width,height:b.height},actual:{width:v.width,height:v.height}}}}let R=b.width*b.height,{diffData:N,diffMask:I,differentPixels:P}=await th({width:b.width,height:b.height,baselineData:b.data,currentData:v.data,maxColorDistance:x*tZ}),S=P>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:I,baseline:b,current:v,totalPixels:R,differentPixels:P,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,R,N,I,P,S,_,O;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=tj(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),x=tj(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),A=y.width*y.height,R=tJ(n.differentPixels/A),N=Math.round(tH(v)),I=Math.round(tH(x)),P=(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"),S=(f=A/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",_=(d=v,u=x,m=tH(d),Math.abs(w=tH(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"),O=(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:M({x:tJ(y.x/r.width),y:tJ(y.y/r.height),width:tJ(y.width/r.width),height:tJ(y.height/r.height)}),differentPixels:n.differentPixels,shareOfDiffPercentage:tJ(n.differentPixels/r.differentPixels),densityPercentage:R,shape:P,size:S,location:O,averageBaselineColorHex:tz(v),averageCurrentColorHex:tz(x),baselineLuminance:N,currentLuminance:I,dominantChange:_}}):[];if(P>0&&f){let e=new m({width:b.width,height:b.height,data:N});for(let t of S)t.rect.width<4||t.rect.height<4||function(e,t){let n=tv(t.x,0,e.width-1),a=tv(t.y,0,e.height-1),r=tv(t.x+t.width-1,0,e.width-1),i=tv(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)tk(e,s,a+t,ty),tk(e,s,i-t,ty);for(let s=a;s<=i;s+=1)tk(e,n+t,s,ty),tk(e,r-t,s,ty)}}(e,t.rect);await t.mkdir(a.dirname(f),{recursive:!0}),await t.writeFile(f,await tp(e))}else await t2(r.outputPath);let _=P>0?await tT({baselinePath:e,currentPath:n,width:b.width,height:b.height}):void 0,O=_&&(_.matches.length>0||(_.movementClusters?.length??0)>0)?{provider:_.provider,baselineBlocks:_.baselineBlocks,currentBlocks:_.currentBlocks,matches:_.matches,..._.movementClusters?{movementClusters:_.movementClusters}:{}}:void 0,D=P>0&&_?(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=A(Math.floor(a.x),0,t-1),i=A(Math.floor(a.y),0,n-1),s=A(Math.ceil(a.x+a.width),0,t),o=A(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,y(e.rect,8));return r}((o={diffMask:I,width:b.width,height:b.height,regions:S,ocr:_}).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=t_(o.ocr?.currentBlocksRaw??[]),h=t_(o.ocr?.baselineBlocksRaw??[]),c.filter(tD).map(e=>{var t,n,a,r,i,s,l,d,u,c,f;let m,w,g,b,y,v,x,A,M,R;return t=e,n=o,a=p,r=h,b=function(e,t){let n,a=0;for(let r of t){let t=k(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(g=tE(t),n.regions),y=function(e,t,n){let a=tS(e,t);if(a)return tO(e,a.blocks);let r=tS(e,n);return r?tO(e,r.blocks):void 0}(g,a,r),v=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),x=(i=g,s=v,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":tP(i,d)?"background":"visual"),A={...b?{regionIndex:b}:{},slot:v,likelyKind:x,rect:g},{...b?{regionIndex:b}:{},slot:v,likelyKind:x,rect:g,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(u=A,c=t.differentPixels,f=n,M=tP(u.rect,f)?-35:0,R=20*!!u.regionIndex,tR[u.likelyKind]+tN[u.slot]+R+M+Math.min(20,c/200))}}).filter(e=>e.rect.y>=.08*o.height).filter(tI).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}:{}}})):[],E=R>0?Math.round(P/R*1e4)/100:0;return{...P>0&&f?{diffPath:f}:{},...S.length>0?{regions:S}:{},...O?{ocr:O}:{},...D.length>0?{nonTextDeltas:D}:{},totalPixels:R,differentPixels:P,mismatchPercentage:E,match:0===P}}async function t0(e,n){try{await t.access(e)}catch{throw new h("INVALID_ARGS",`${n}: ${e}`)}}function t1(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new h("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function t2(e){if(e)try{await t.unlink(e)}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function t4(e){return e.width*e.height}function t3(e){return Math.round(100*e*100)/100}async function t5(e,t){let n=await tg(e,{prefix:"agent-device-diff-current",ext:".png"});try{await t6(e,t,n.path,t9(t))}catch(e){throw await n.cleanup(),e}return n}async function t8(e,t,n,a,r){var i,s,o,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await ne(n),a;let d=(i=t,s=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:t7(s??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:t7(i.out.clientPath)}:{},...i.out.fileName?{fileName:t7(i.out.fileName)}:{}}:void 0),u=await tw(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await t6(e,t,u.path,{overlayRefs:!0,...t9(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=t4(t.rect),n.map(e=>{let n=e.overlayRect,r=k(t.rect,n);return r<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:n,overlayCoveragePercentage:t3(r/t4(n)),regionCoveragePercentage:t3(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 t6(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new h("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 t9(e){return e.surface?{surface:e.surface}:{}}function t7(e){let t=a.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function ne(e){try{await t.unlink(t7(e))}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function nt(e){return"live"===e.kind}function nn(e,t){let n=O(e.type??"Element"),a=B(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 na(e,t){return t.flatten?e.map(e=>({text:E(e,0,!1),comparable:nn(e,0)})):F(e).map(e=>({text:e.text,comparable:nn(e.node,e.depth)}))}function nr(e,t){return e.get(t)??0}function ni(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}))}async function ns(e,t){var n,a,r,i,s,o;let d,u,c,p;if(!e.backend.captureSnapshot)throw new h("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let f=t.session??"default",m=await e.sessions.get(f),w=await e.backend.captureSnapshot({session:f,requestId:t.requestId,appId:m?.appId,appBundleId:m?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),g=(a=w,r=e,n=a.snapshot?a.snapshot:{nodes:a.nodes??[],truncated:a.truncated,backend:a.backend,createdAt:S(r)},n.presentationKey?n:{...n,presentationKey:l(t)}),b=S(e);return{snapshot:g,result:w,session:m,warnings:((d=[...(i={result:w,snapshot:g,options:t,session:m,capturedAt:g.createdAt??b,runtimeNow:b}).result.warnings??[]]).push(...function(e){let t=e.result.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)),d.push(...function(e){if("xctest"!==e.snapshot.backend||!0!==e.options.interactiveOnly||!0!==e.options.compact||1!==e.snapshot.nodes.length)return[];let t=e.snapshot.nodes[0];return t?.type!=="Application"?[]:["iOS compact interactive snapshot exposed only the application root. XCTest typed 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=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.result.androidSnapshot))&&d.push(u),(c=function(e){if(eX(e).detected)return"Hint: React Native warning/error overlay detected. It overlays part of the app and should be handled before interacting.\nRun: agent-device react-native dismiss-overlay\nThe command verifies the overlay is gone. Run agent-device snapshot -i -c afterward only when you need fresh refs for the next action."}(i.snapshot.nodes))&&d.push(c),(p=function(e){var t,n,a,r,i,s;let o=e.session?.snapshot;if(!e.result.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 nl}(i))&&d.push(p),d.push(...(s=i.result.freshness,o=i.snapshot.backend,s?.staleAfterRetries&&"android"===o?"stuck-route"===s.reason?[`Recent ${s.action} was followed by a nearly identical snapshot after ${s.retryCount} automatic retr${1===s.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"===s.reason?[nl]:[]:[])),Array.from(new Set(d)))}}function no(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 nl="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.";function nd(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function nu(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,s=j(n),o=er(n,i),l=!0===n.selected,d="text"===t?Q(n):function(e,t,n){var a,r,i;let s;if("android"===n&&!1===e.visibleToUser)return!1;if(nc(e.rect))return function(e,t){return D(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=et(r),H(r,a,s,e=>!function(e,t){if("android"===t&&!1===e.visibleToUser)return!1;let n=ea(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&&nc(e.rect):!0===e.hittable||nc(e.rect))}(e,i)?null:e));return!!o&&(nc(o.rect)?function(e,t){return D(e,t)}(o,t):"android"!==n&&!0===o.hittable)}(n,a,i),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=o;break;case"selected":u=l;break;case"text":u=s===(r??"")}let c="text"===t?`expected="${r??""}" actual="${s}"`:`actual=${JSON.stringify({visible:d,editable:o,selected:l})}`;return{pass:u,actualText:s,details:c}}function nc(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 np(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new h("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new h("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function nh(e,t,n={updateSession:!0}){let a=e.backend.captureSnapshot;if(!a)throw new h("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",i=await e.sessions.get(r),s=await a(Y(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,createdAt:S(e)};return n.updateSession&&i&&await e.sessions.set({...i,snapshot:o}),{sessionName:r,session:i,snapshot:o}}async function nf(e,t,n){if(e.backend.readText){let a=await e.backend.readText(Y(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return ee(n)}let nm=async(e,t)=>{if("ref"===t.target.kind){let n=await np(e,t.session),a=function(e,t,n){let a=s(t);if(!a)throw new h("INVALID_ARGS",n.invalidRefMessage);let r=d(e,a)??(n.fallbackLabel.length>0?J(e,n.fallbackLabel):null);if(!r)throw new h("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=z(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 nf(e,n,a.node),node:a.node,selectorChain:r}}let n=await nP(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=z(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 nf(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},nw=async(e,t)=>{let n=await nm(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new h("COMMAND_FAILED","getText returned non-text result");return n},ng=async(e,t)=>{let n=await nm(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new h("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nb=async(e,t)=>{if(!nd(t.predicate))throw new h("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new h("INVALID_ARGS","is text requires expected text value");let n=await nh(e,t,{updateSession:!0}),a=eo(t.selector);if("exists"===t.predicate){let r=V(n.snapshot.nodes,a,{platform:e.backend.platform});if(!r)throw new h("COMMAND_FAILED",en(a,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:r.selector.raw,matches:r.matches,selectorChain:a.selectors.map(e=>e.raw)}}let r=W(n.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!r)throw new h("COMMAND_FAILED",en(a,[],{unique:!0}),{command:"is",reason:"selector_not_found",predicate:t.predicate,selector:a.raw});let i=nu({predicate:t.predicate,node:r.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!i.pass)throw new h("COMMAND_FAILED",`is ${t.predicate} failed for selector ${r.selector.raw}: ${i.details}`,{command:"is",reason:"predicate_failed",predicate:t.predicate,selector:r.selector.raw,predicateDetails:i.details});return{predicate:t.predicate,pass:!0,selector:r.selector.raw,..."text"===t.predicate?{text:i.actualText}:{},selectorChain:a.selectors.map(e=>e.raw)}},ny=async(e,t)=>await nb(e,{...t,predicate:"visible",selector:t.target.selector}),nk=async(e,t)=>await nb(e,{...t,predicate:"hidden",selector:t.target.selector}),nv=async(e,t)=>{if("sleep"===t.target.kind)return await _(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await np(e,t.session),a=s(t.target.ref);if(!a)throw new h("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=d(n.snapshot.nodes,a),i=r?Z(r,n.snapshot.nodes):void 0;if(!i)throw new h("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await nN(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nR(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new h("INVALID_ARGS","wait requires text");return await nN(e,t,t.target.text,t.target.timeoutMs)},nx=async(e,t)=>{let n=await nv(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new h("COMMAND_FAILED","waitForText returned non-text result");return n};async function nA(e,t,n){let a=t.timeoutMs??1e4,r=S(e);for(;S(e)-r<a;){let{match:a}=await nM(e,t,n);if(a)return{kind:"found",found:!0,waitedMs:S(e)-r};await _(e,300)}throw new h("COMMAND_FAILED","find wait timed out")}async function nM(e,t,n){let a=await nh(e,t,{updateSession:!0,scope:C(n)?t.query:void 0}),r=es(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];return{capture:a,match:r}}async function nR(e,t,n,a){let r=a??1e4,i=S(e),s=eo(n);for(;S(e)-i<r;){let n=V((await nh(e,t,{updateSession:!0})).snapshot.nodes,s,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:S(e)-i};await _(e,300)}throw new h("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nN(e,t,n,a){let r=a??1e4,i=S(e);for(;S(e)-i<r;){if(e.backend.findText?(await e.backend.findText(Y(e,t),n)).found:await nI(e,t,n))return{kind:"text",text:n,waitedMs:S(e)-i};await _(e,300)}throw new h("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nI(e,t,n){return!!J((await nh(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nP(e,t,n,a){let r=await nh(e,{...t,session:n},{updateSession:!0}),i=eo(a.selector),s=W(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!s)throw new h("COMMAND_FAILED",en(i,[],{unique:!0}));return{capture:r,node:s.node,selector:s.selector.raw,ref:`@${s.node.ref}`}}async function nS(e,t,n){let a=await X(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new h("UNSUPPORTED_OPERATION","tap is not supported by this backend");let r=L(await e.backend.tap(Y(e,t),a.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...a,...r?{backendResult:r}:{}}}function n_(e,t){if(void 0!==e)return nO(e,t)}function nO(e,t){let n=e?.trim();if(!n)throw new h("INVALID_ARGS",`${t} must be a non-empty string`);return n}let nD=/^[A-Za-z0-9_.:-]{1,64}$/;async function nE(e,t){if(!t||"object"!=typeof t)throw new h("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nC(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await tm(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nC(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new h("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 h("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new h("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new h("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nT(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}async function nU(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new h("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?nO(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new h("INVALID_ARGS",`admin.${n} requires app`);let s=Y(e,t),o=await n$(e,s,t.source);try{var l,d,u,c,p;let t,a,h,f,m,w,g,y,k=await r.call(e.backend,s,{...i?{app:i}:{},source:o.source});return l=n,d=i,u=o.source,c=k,t=L(c),a=nX(c,"appName"),h=nX(c,"appId"),f=nX(c,"bundleId"),m=nX(c,"packageName"),w=nX(c,"launchTarget"),g=nX(c,"installablePath"),y=nX(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}:{},...w?{launchTarget:w}:{},...g?{installablePath:g}:{},...y?{archivePath:y}:{},...t?{backendResult:t}:{},...b(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??w??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await o.cleanup?.()}}async function n$(e,t,n){let a=nB(n),r=await nL(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nB(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function nL(e,t){if("url"===t.kind)return{source:t};let n=await tm(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nB(e){if(!e||"object"!=typeof e)throw new h("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nO(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nO(e.id,"source.id")};if("url"===e.kind){let t=nO(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new h("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new h("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new h("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function nG(e){if(!e)return;let t=n_(e.id,"target.id"),n=n_(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 nX(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function nY(e,t){if("start"===e||"stop"===e)return e;throw new h("INVALID_ARGS",`${t} action must be start or stop`)}function nK(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...b("start"===e?a.startMessage:a.stopMessage)}}let nq=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,nF=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function nV(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(nF,()=>(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=nj(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function nj(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))nq.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 nH=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function nz(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(nH.test(a))n[a]="[REDACTED]",t=!0;else{let e=nQ(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function nW(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=nZ(t,nV);return n0(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??nQ(e,2048)}function nJ(e){return nZ(e,e=>nQ(e,2048))}function nZ(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=nZ(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(nH.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=nZ(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function nQ(e,t){if(void 0===e)return{redacted:!1};let n=nV(e);return n0(n.value,t,n.redacted)}function n0(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}}async function n1(e,t){let n=Y(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 n2(e,t,n,a){return{...n4(e),...void 0!==e.cursor?{cursor:nO(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:K(e.limit,a,1,n)}}function n4(e){return{...void 0!==e.since?{since:nO(e.since,"since")}:{},...void 0!==e.until?{until:nO(e.until,"until")}:{}}}function n3(e,t,n=50){if(!Array.isArray(e))throw new h("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new h("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>nO(e,`${t}[${n}]`))}let n5=tb,n8=async(e,t)=>{let n,a,r;if(!t.baseline)throw new h("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 h("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),s=t.current??{kind:"live"};if(t.overlayRefs&&!nt(s))throw new h("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let o=await tm(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=nt(s)?(a=await t5(e,t)).path:(n=await tm(e,s,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await tw(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tQ(o.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});nt(s)&&(u=await t8(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?.()}},n6=async(e,t)=>{var n;let a,r,i=await ns(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(ni(r.nodes))!==JSON.stringify(ni(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(no(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:a,snapshotRaw:r}=e;if(r||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let i=P(n),s=new Set;return i.hiddenCount>0&&s.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&s.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&s.add("scroll-hidden-below"),{partial:s.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...s]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.result.androidSnapshot?{androidSnapshot:i.result.androidSnapshot}:{},...i.warnings.length>0?{warnings:i.warnings}:{},...s?{unchanged:s}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},n9=async(e,t)=>{let n=await ns(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=no(t.session,n);if(!r){let t=function(e,t={}){return na(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&&nr(i,r-1)<nr(i,r+1)?nr(i,r+1):nr(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&&nr(r,l-1)<nr(r,l+1)?l+1:l-1,u=nr(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[]}(na(e,n),na(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}:{}}},n7=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new h("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nA(e,t,n);let{capture:a,match:r}=await nM(e,t,n);if(!r)throw new h("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 nf(e,a,r),node:r}},ae=nm,at=nw,an=ng,aa=nb,ar=ny,ai=nk,as=nv,ao=nx,al=async(e,t)=>await nS(e,t,"click"),ad=async(e,t)=>await nS(e,t,"press"),au=async(e,t)=>{var n;if(!t.text)throw new h("INVALID_ARGS","fill requires text");let a=await X(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new h("UNSUPPORTED_OPERATION","fill is not supported by this backend");let r=L(await e.backend.fill(Y(e,t),a.point,t.text,{delayMs:t.delayMs})),i="node"in a?a.node.type??"":"",s=i&&!ei(i,e.backend.platform)?`fill target ${n=a,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${i}", attempting fill anyway.`:void 0;return{...a,text:t.text,...s?{warning:s}:{},...r?{backendResult:r}:{}}},ac=async(e,t)=>{let n=t.text;if(!n)throw new h("INVALID_ARGS","type requires text");let a=eE(n);if(a)throw new h("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 h("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=K(t.delayMs??0,"delay-ms",0,1e4),i=L(await e.backend.typeText(Y(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...b(`Typed ${Array.from(n).length} chars`)}},ap=$,ah=U,af=G,am=T,aw=q,ag=async(e,t={})=>{if(!e.backend.pressBack)throw new h("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new h("INVALID_ARGS","system.back mode must be in-app or system");let a=L(await e.backend.pressBack(Y(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...b("Back")}},ab=async(e,t={})=>{if(!e.backend.pressHome)throw new h("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=L(await e.backend.pressHome(Y(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...b("Home")}},ay=async(e,t)=>{if(!e.backend.rotate)throw new h("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 h("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=L(await e.backend.rotate(Y(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...b(`Rotated to ${n}`)}},ak=async(e,t={})=>{var n,a,r,i,s,o,l;if(!e.backend.setKeyboard)throw new h("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let d=t.action??"status";if(!eD(d))throw new h("INVALID_ARGS","system.keyboard action must be status, get, dismiss, enter, or return");let u=await e.backend.setKeyboard(Y(e,t),{action:d}),c=L(u),p=(n=u)&&"object"==typeof n?u:{};return"enter"===d||"return"===d?{kind:"keyboardEnterPressed",action:"enter",state:p,...(a=c)?{backendResult:a}:{},...b("Keyboard enter pressed")}:"dismiss"===d?(r=d,{kind:"keyboardDismissed",action:r,state:i=p,...(s=c)?{backendResult:s}:{},...b(!1===i.dismissed?"Keyboard already hidden":"Keyboard dismissed")}):(o=d,{kind:"keyboardState",action:o,state:p,...(l=c)?{backendResult:l}:{}})},av=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new h("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(Y(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new h("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new h("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new h("INVALID_ARGS","system.clipboard write requires text");let n=L(await e.backend.setClipboard(Y(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...b("Clipboard updated")}},ax=async(e,t={})=>{if(!e.backend.openSettings)throw new h("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=n_(t.target,"target"),a=L(await e.backend.openSettings(Y(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...b(n?`Opened settings: ${n}`:"Opened settings")}},aA=async(e,t={})=>{var n,a;if(!e.backend.handleAlert)throw new h("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 h("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let i=void 0===t.timeoutMs?void 0:K(t.timeoutMs,"timeoutMs",0,12e4),s=await e.backend.handleAlert(Y(e,t),r,{timeoutMs:i});return n=r,a=s,"get"===n?function(e){if("alertStatus"!==e.kind)throw new h("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 h("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}:{},...b(e.alert?"Alert visible":"Alert wait timed out")}}(a):function(e,t){if("alertHandled"!==t.kind)throw new h("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}:{},...b(t.handled?`Alert ${e}ed`:"No alert handled")}}(n,a)},aM=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new h("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=L(await e.backend.openAppSwitcher(Y(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...b("Opened app switcher")}},aR=async(e,t)=>{var n;if(!e.backend.openApp)throw new h("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=n_(e.app,"app"),a=n_(e.appId,"appId"),r=n_(e.bundleId,"bundleId"),i=n_(e.packageName,"packageName"),s=n_(e.url,"url"),o=n_(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 h("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=L(await e.backend.openApp(nT(e,t),a,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...b(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},aN=async(e,t={})=>{if(!e.backend.closeApp)throw new h("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=n_(t.app,"app"),a=L(await e.backend.closeApp(nT(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...b(n?`Closed: ${n}`:"Closed app")}},aI=async(e,t={})=>{if(!e.backend.listApps)throw new h("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nT(e,t),ed(t.filter))}},aP=async(e,t)=>{if(!e.backend.getAppState)throw new h("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nO(t.app,"app"),a=await e.backend.getAppState(nT(e,t),n);return{kind:"appState",app:n,state:a}},aS=async(e,t)=>{if(!e.backend.pushFile)throw new h("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nO(t.app,"app"),a=await nE(e,t.input);try{let r=await e.backend.pushFile(nT(e,t),a.backendInput,n),i=L(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...b(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},a_=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new h("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nO(e,"name");if(!nD.test(t))throw new h("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&&nC(n,a,8192);let i=L(await e.backend.triggerAppEvent(nT(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...b(`Triggered app event: ${r}`)}},aO=async(e,t={})=>{if(!e.backend.listDevices)throw new h("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(Y(e,t),t.filter)}},aD=async(e,t={})=>{if(!e.backend.bootDevice)throw new h("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=nG(t.target),a=L(await e.backend.bootDevice(Y(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...b("Booted device")}},aE=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new h("UNSUPPORTED_OPERATION","admin.shutdown is not supported by this backend");let n=nG(t.target),a=L(await e.backend.shutdownDevice(Y(e,t),n));return{kind:"deviceShutdown",...n?{target:n}:{},...a?{backendResult:a}:{},...b("Shutdown device")}},aC=async(e,t)=>await nU(e,t,"install"),aT=async(e,t)=>await nU(e,t,"reinstall"),aU=async(e,t)=>await nU(e,t,"installFromSource"),a$=async(e,t)=>{let n=nY(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new h("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await tw(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,s,o,l,d;let u,c,p=(i=t,s=r?.path,u=void 0===i.fps?void 0:K(i.fps,"fps",1,60),c=void 0===i.quality?void 0:K(i.quality,"quality",5,10),{...s?{outPath:s}:{},...void 0!==u?{fps:u}:{},...void 0!==c?{quality:c}:{},...void 0!==i.hideTouches?{showTouches:!0!==i.hideTouches}:{}}),h=await a.call(e.backend,Y(e,t),p),f=await r?.publish();return o=n,l=h,d=f,{..."string"==typeof l.path?{path:l.path}:{},..."string"==typeof l.telemetryPath?{telemetryPath:l.telemetryPath}:{},..."string"==typeof l.warning?{warning:l.warning}:{},...nK(o,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},aL=async(e,t)=>{let n=nY(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new h("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await tw(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,Y(e,t),l),u=await r?.publish();return i=n,s=d,o=u,{..."string"==typeof s.outPath?{outPath:s.outPath}:{},...nK(i,s,o,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}},aB=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new h("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await n1(e,t),{...n2(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:n3(a.levels,"levels")}:{},...void 0!==a.search?{search:nO(a.search,"search")}:{},...void 0!==a.source?{source:nO(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=nQ(e.message,4096),n=nJ(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}:{}}},aG=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new h("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let s={...n2(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 h("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await n1(e,t),s),a=s.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?nj(t=e.url)??nQ(t,2048):void 0,r="headers"===a||"all"===a?nz(e.requestHeaders):void 0,s="headers"===a||"all"===a?nz(e.responseHeaders):void 0,o="body"===a||"all"===a?nW(e.requestBody):void 0,l="body"===a||"all"===a?nW(e.responseBody):void 0,d=nJ(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}:{}}},aX=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new h("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await n1(e,t),{...n4(a=t),...void 0!==a.sampleMs?{sampleMs:K(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:n3(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=nQ(e.message,4096),n=nJ(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}:{}}};function aY(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,aK(e)]));return{get:e=>aK(t.get(e)),set:e=>{t.set(e.name,aK(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>aK(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=>n5(t,e),diffScreenshot:e=>n8(t,e),snapshot:e=>n6(t,e),diffSnapshot:e=>n9(t,e)},selectors:{find:e=>n7(t,e),get:e=>ae(t,e),getText:(e,n={})=>at(t,{...n,target:e}),getAttrs:(e,n={})=>an(t,{...n,target:e}),is:e=>aa(t,e),isVisible:(e,n={})=>ar(t,{...n,target:e}),isHidden:(e,n={})=>ai(t,{...n,target:e}),wait:e=>as(t,e),waitForText:(e,n={})=>ao(t,{...n,text:e})},interactions:{click:(e,n={})=>al(t,{...n,target:e}),press:(e,n={})=>ad(t,{...n,target:e}),fill:(e,n,a={})=>au(t,{...a,target:e,text:n}),typeText:(e,n={})=>ac(t,{...n,text:e}),focus:(e,n={})=>ap(t,{...n,target:e}),longPress:(e,n={})=>ah(t,{...n,target:e}),swipe:e=>af(t,e),scroll:e=>am(t,e),pinch:e=>aw(t,e)},system:{back:e=>ag(t,e),home:e=>ab(t,e),rotate:e=>ay(t,e),keyboard:e=>ak(t,e),clipboard:e=>av(t,e),settings:e=>ax(t,e),alert:e=>aA(t,e),appSwitcher:e=>aM(t,e)},apps:{open:e=>aR(t,e),close:e=>aN(t,e),list:(e={})=>aI(t,{...e,filter:el(e.filter)}),state:e=>aP(t,e),push:e=>aS(t,e),triggerEvent:e=>a_(t,e)},admin:{devices:e=>aO(t,e),boot:e=>aD(t,e),shutdown:e=>aE(t,e),install:e=>aC(t,e),reinstall:e=>aT(t,e),installFromSource:e=>aU(t,e)},recording:{record:e=>a$(t,e),trace:e=>aL(t,e)},observability:{logs:e=>aB(t,e),network:e=>aG(t,e),perf:e=>aX(t,e)}}}function aK(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 aq(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}export{eX as analyzeReactNativeOverlay,eM as appendScriptSeriesFlags,aY as createAgentDevice,tc as decodePngAsync,eG as detectReactNativeOverlay,tp as encodePngAsync,nu as evaluateIsPredicate,eE as findMistargetedTypeRefToken,e_ as formatPortableActionLine,eA as formatScriptActionSummary,eb as formatScriptArg,ey as formatScriptStringLiteral,em as isClickLikeCommand,eD as isKeyboardAction,eK as isReactNativeCollapsedWarningWrapperCandidate,eq as isReactNativeCollapsedWarningWrapperWithVisibleBanner,nd as isSupportedPredicate,ew as isTouchTargetCommand,aq as localCommandPolicy,eS as parseReplayOpenFlags,eI as parseReplayRuntimeFlags,eN as parseReplaySeriesFlags,td as prewarmPngWorker,eY as readReactNativeOverlayActionNodes,tu as terminatePngWorker};
|
|
1
|
+
import e,{promises as t}from"node:fs";import n from"node:path";import{Worker as a}from"node:worker_threads";import{fileURLToPath as r}from"node:url";import{buildMobileSnapshotPresentation as i,isSparseSnapshotQualityVerdict as s,now as o,isNodeVisibleInEffectiveViewport as l,sleep as d,publicSnapshotCaptureAnnotations as u,scrollCommand as c,longPressCommand as p,appendScreenshotScriptFlags as h,successText as f,focusCommand as m,toBackendResult as w,swipeCommand as g,resolveInteractionTarget as b,toBackendContext as y,snapshotCaptureAnnotationsFrom as k,requireIntInRange as x,formatReactNativeOverlayWarning as v,pinchCommand as A,renderSnapshotQualityWarnings as M}from"./6133.js";import{emitDiagnostic as I}from"./7599.js";import{asAppError as P,toAppErrorCode as R,AppError as N}from"./9152.js";import{computeScreenshotDiffPixels as S,PNG as _,toBuffer as O,decodePng as D}from"./9010.js";import{expandRect as E,intersectArea as T,unionRects as C,rectCenter as U,clamp as $,normalizedRect as L,squaredDistance as B}from"./4778.js";import{whichCmd as G,runCmd as X}from"./9818.js";import{formatSnapshotLine as q,formatRole as Y,displayLabel as K,buildSnapshotDisplayLines as F}from"./5827.js";import{buildSnapshotPresentationKey as V,normalizeRef as j,findNodeByRef as H}from"./9616.js";import{extractNodeText as z,findSnapshotAncestor as W,parseSelectorChain as J,isNodeVisible as Z,buildSnapshotNodeByIndex as Q,isNodeEditable as ee,findSelectorChainMatch as et,buildSelectorChainForNode as en,resolveSelectorChain as ea,findNodeByLabel as er,resolveRefLabel as ei,extractReadableText as es,formatSelectorFailure as eo,normalizeType as el,isFillableType as ed}from"./7847.js";import{findBestMatchesByLocator as eu}from"./7556.js";import{resolveAppsFilter as ec,assertResolvedAppsFilter as ep}from"./3675.js";let eh=/^-?\d+(\.\d+)?$/,ef=/^[^\s"\\]+$/,em=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),ew=new Map([["--count","count"],["--pause-ms","pauseMs"]]),eg=new Map([["--delay-ms","delayMs"]]);function eb(e){return"click"===e||"press"===e}function ey(e){return eb(e)||"longpress"===e}function ek(e){return"type"===e||"fill"===e}function ex(e){return eA(e,eM)}function ev(e){return JSON.stringify(e)}function eA(e,t){return t(e)?e:ev(e)}function eM(e){return eI(e)&&e.startsWith("@")||eh.test(e)}function eI(e){return ef.test(e)}function eP(e){let t=(e.positionals??[]).map(e=>ex(e));return[e.command,...t].join(" ")}function eR(e,t){let n=t.flags??{};if(eb(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}ek(t.command)&&"number"==typeof n.delayMs&&e.push("--delay-ms",String(n.delayMs))}function eN(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",eA(t.metroHost,eI)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",eA(t.bundleUrl,eI)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",eA(t.launchUrl,eI)))}function eS(e,t){let n=[],a={},r=eb(e)?em:"swipe"===e?ew:ek(e)?eg:void 0;for(let i=0;i<t.length;i+=1){let s=t[i];if(eb(e)&&"--double-tap"===s){a.doubleTap=!0;continue}let o=t[i+1];if(eb(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=eO(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 e_(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=eO(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 eO(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function eD(e){var t;let n=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}n.push(t)}let r=e_(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 eE(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",ex(e.flags.snapshotScope)),e.flags?.snapshotRaw&&n.push("--raw");else if("open"===e.command){for(let t of e.positionals??[])n.push(ex(t));e.flags?.relaunch&&n.push("--relaunch"),eN(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(eA(t,eI));eN(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(eA(n,eI)),a))e.push(ex(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.quality&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}(n,e);else if("screenshot"===e.command){for(let t of e.positionals??[])n.push(ex(t));h(n,e.flags)}else{for(let t of e.positionals??[])n.push(ex(t));eR(n,e)}return n.join(" ")}let eT=["status","get","dismiss","enter","return"];function eC(e){return eT.includes(e)}function eU(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 e$ extends Error{}let eL=null,eB=!1,eG=!1,eX=0,eq=new Map;function eY(e){eB=!0,eG||(eG=!0,I({level:"warn",phase:"png_worker_unavailable",data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function eK(e){let t=eq.get(e.id);t&&(eq.delete(e.id),ej(),e.ok?t.resolve(e.result):t.reject(new N(R(e.error.code),e.error.message,e.error.details)))}function eF(e,t){eL===e&&(eY(t.message),eL=null,e.terminate().catch(()=>{}),eV(new e$(`PNG worker failed: ${t.message}`)))}function eV(e){let t=[...eq.values()];for(let n of(eq.clear(),t))n.reject(e)}function ej(){eL&&(eq.size>0?eL.ref():eL.unref())}function eH(){if(eB)return null;if(eL)return eL;let t=function(t,a){try{let i=r(t),s=n.extname(i)||".js";return[n.join(n.dirname(i),`${a}${s}`),n.join(n.dirname(i),"internal",`${a}${s}`)].find(t=>e.existsSync(t))??null}catch{return null}}(import.meta.url,"png-worker");if(!t)return eY("worker entry module not found next to the current module"),null;try{let e=new a(t,{execArgv:t.endsWith(".ts")?["--experimental-strip-types"]:[]});return e.on("message",eK),e.on("error",t=>{eF(e,t)}),e.on("exit",t=>{eF(e,Error(`PNG worker exited with code ${t}`))}),e.unref(),eL=e,e}catch(e){return eY(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}async function ez(e,t){try{return await function(e){let t=eH();if(!t)return Promise.reject(new e$("PNG worker is unavailable"));let n=eX+=1;return new Promise((a,r)=>{eq.set(n,{resolve:a,reject:r}),ej();try{t.postMessage({...e,id:n})}catch(e){eq.delete(n),ej(),r(new e$(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}(e)}catch(e){if(e instanceof e$)return t();throw e}}function eW(){eH()}async function eJ(){let e=eL;eL=null,eV(new e$("PNG worker terminated")),e&&await e.terminate()}async function eZ(e,t){let n=await ez({kind:"decode",png:e,label:t},()=>{let n=D(e,t);return{kind:"decode",width:n.width,height:n.height,data:n.data}});return new _({width:n.width,height:n.height,data:O(n.data)})}async function eQ(e){return O((await ez({kind:"encode",width:e.width,height:e.height,data:e.data},()=>({kind:"encode",png:_.sync.write(e)}))).png)}async function e0(e){let{kind:t,...n}=await ez({kind:"diff-pixels",...e},()=>({kind:"diff-pixels",...S(e)}));return{...n,diffData:O(n.diffData)}}let e1=[0,187,255,255];function e2(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 e4(e,t,n){return Math.min(Math.max(e,t),n)}let e3=[{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 e5(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(!e8(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 e3){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;e8(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 e8(e,t,n){return 1===e[n]&&1!==t[n]}let e6={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},e9={leading:20,trailing:20,separator:10,unknown:0,background:-30};function e7(e){return"background"!==e.likelyKind}function te(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function tt(e,t){let n,a=0;for(let r of t){let t=ts(e,r.rect);t<=a||(a=t,n=r)}return n}function tn(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,ts(t,a=n.rect)>0||Math.abs(U(t).y-U(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=C([e.rect,n.rect])}return t}function ta(e,t){let n,a=U(e);for(let e of t){let t=Math.sqrt(B(a,U(e.rect)));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tr(e){let t=ti(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function ti(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function ts(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}async function to(e){if(await G("tesseract"))try{let[t,n]=await Promise.all([td(e.baselinePath),td(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tl(t.stdout,e.width,e.height),r=tl(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tm(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(tm(o.text)!==t)continue;let l=U(e.normalizedRect),d=B(l,U(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=tb(t.rect.width/e.rect.width),r=tb(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)=>tu(t)-tu(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-tw(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(tc).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tp(t)-tp(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 tl(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=tf(t,i,"level"),a=th(t,i,"text").trim(),r=tf(t,i,"conf");if(5!==n||(o=a,!/[\p{L}\p{N}]/u.test(o))||r<0)continue;let l=tf(t,i,"left"),d=tf(t,i,"top"),u=tf(t,i,"width"),c=tf(t,i,"height");u<=0||c<=0||s.push({key:[th(t,i,"page_num"),th(t,i,"block_num"),th(t,i,"par_num"),th(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=C(a.map(e=>e.rect)),i=Math.round(100*tw(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:L({x:tg(r.x/t),y:tg(r.y/n),width:tg(r.width/t),height:tg(r.height/n)})}})(e,t,n)).filter(e=>null!==e)}function td(e){return X("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tu(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 tc(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 tp(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function th(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tf(e,t,n){let a=Number(th(e,t,n));return Number.isFinite(a)?a:0}function tm(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tw(e){return e.reduce((e,t)=>e+t,0)/e.length}function tg(e){return Math.round(100*e*100)/100}function tb(e){return Math.round(1e3*e)/1e3}function ty(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tk(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tx(e){return`#${tv(e.r)}${tv(e.g)}${tv(e.b)}`}function tv(e){return e.toString(16).padStart(2,"0")}function tA(e){return Math.round(100*e*100)/100}let tM=255*Math.sqrt(3);async function tI(e,a,r={}){var i,s,o,l,d;let u,c,p,h;await tP(e,"Baseline image not found"),await tP(a,"Current screenshot not found");let f=r.outputPath,[m,w]=await Promise.all([t.readFile(e),t.readFile(a)]),[g,b]=await Promise.all([eZ(m,"baseline screenshot"),eZ(w,"current screenshot")]);tR(g.width,g.height,"baseline screenshot",r.maxPixels),tR(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 tN(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:x,diffMask:v,differentPixels:A}=await e0({width:g.width,height:g.height,baselineData:g.data,currentData:b.data,maxColorDistance:y*tM}),M=A>0?(s=(u=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n;return e5({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:v,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,x,v,A,M,I,P,R,N,S,_;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)},x=ty(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),v=ty(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),A=y.width*y.height,M=tA(n.differentPixels/A),I=Math.round(tk(x)),P=Math.round(tk(v)),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"),N=(f=A/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",S=(d=x,u=v,m=tk(d),Math.abs(w=tk(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:L({x:tA(y.x/r.width),y:tA(y.y/r.height),width:tA(y.width/r.width),height:tA(y.height/r.height)}),differentPixels:n.differentPixels,shareOfDiffPercentage:tA(n.differentPixels/r.differentPixels),densityPercentage:M,shape:R,size:N,location:_,averageBaselineColorHex:tx(x),averageCurrentColorHex:tx(v),baselineLuminance:I,currentLuminance:P,dominantChange:S}}):[];if(A>0&&f){let e=new _({width:g.width,height:g.height,data:x});for(let t of M)t.rect.width<4||t.rect.height<4||function(e,t){let n=e4(t.x,0,e.width-1),a=e4(t.y,0,e.height-1),r=e4(t.x+t.width-1,0,e.width-1),i=e4(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)e2(e,s,a+t,e1),e2(e,s,i-t,e1);for(let s=a;s<=i;s+=1)e2(e,n+t,s,e1),e2(e,r-t,s,e1)}}(e,t.rect);await t.mkdir(n.dirname(f),{recursive:!0}),await t.writeFile(f,await eQ(e))}else await tN(r.outputPath);let I=A>0?await to({baselinePath:e,currentPath:a,width:g.width,height:g.height}):void 0,P=I&&(I.matches.length>0||(I.movementClusters?.length??0)>0)?{provider:I.provider,baselineBlocks:I.baselineBlocks,currentBlocks:I.currentBlocks,matches:I.matches,...I.movementClusters?{movementClusters:I.movementClusters}:{}}:void 0,R=A>0&&I?(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=$(Math.floor(a.x),0,t-1),i=$(Math.floor(a.y),0,n-1),s=$(Math.ceil(a.x+a.width),0,t),o=$(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,E(e.rect,8));return r}((o={diffMask:v,width:g.width,height:g.height,regions:M,ocr:I}).diffMask,o.width,o.height,o.ocr),d=o.width,e5({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=tn(o.ocr?.currentBlocksRaw??[]),h=tn(o.ocr?.baselineBlocksRaw??[]),c.filter(tr).map(e=>{var t,n,a,r,i,s,l,d,u,c,f;let m,w,g,b,y,k,x,v,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=T(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(g=ti(t),n.regions),y=function(e,t,n){let a=tt(e,t);if(a)return ta(e,a.blocks);let r=tt(e,n);return r?ta(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),x=(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":te(i,d)?"background":"visual"),v={...b?{regionIndex:b}:{},slot:k,likelyKind:x,rect:g},{...b?{regionIndex:b}:{},slot:k,likelyKind:x,rect:g,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(u=v,c=t.differentPixels,f=n,A=te(u.rect,f)?-35:0,M=20*!!u.regionIndex,e6[u.likelyKind]+e9[u.slot]+M+A+Math.min(20,c/200))}}).filter(e=>e.rect.y>=.08*o.height).filter(e7).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}:{}}})):[],N=k>0?Math.round(A/k*1e4)/100:0;return{...A>0&&f?{diffPath:f}:{},...M.length>0?{regions:M}:{},...P?{ocr:P}:{},...R.length>0?{nonTextDeltas:R}:{},totalPixels:k,differentPixels:A,mismatchPercentage:N,match:0===A}}async function tP(e,n){try{await t.access(e)}catch{throw new N("INVALID_ARGS",`${n}: ${e}`)}}function tR(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new N("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function tN(e){if(e)try{await t.unlink(e)}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function tS(e){return e.width*e.height}function t_(e){return Math.round(100*e*100)/100}async function tO(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new N("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw P(e)}}async function tD(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new N("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 P(e)}}async function tE(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw P(e)}}let tT=async(e,t)=>{let n,a,r;if(!t.baseline)throw new N("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 N("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),s=t.current??{kind:"live"};if(t.overlayRefs&&!tX(s))throw new N("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let o=await tO(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=tX(s)?(a=await tC(e,t)).path:(n=await tO(e,s,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await tD(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tI(o.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});tX(s)&&(u=await tU(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 tC(e,t){let n=await tE(e,{prefix:"agent-device-diff-current",ext:".png"});try{await t$(e,t,n.path,tL(t))}catch(e){throw await n.cleanup(),e}return n}async function tU(e,t,n,a,r){var i,s,o,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await tG(n),a;let d=(i=t,s=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:tB(s??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:tB(i.out.clientPath)}:{},...i.out.fileName?{fileName:tB(i.out.fileName)}:{}}:void 0),u=await tD(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await t$(e,t,u.path,{overlayRefs:!0,...tL(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=tS(t.rect),n.map(e=>{let n=e.overlayRect,r=T(t.rect,n);return r<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:n,overlayCoveragePercentage:t_(r/tS(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 t$(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new N("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 tL(e){return e.surface?{surface:e.surface}:{}}function tB(e){let t=n.extname(e),a=t?e.slice(0,-t.length):e;return`${a}.current-overlay${t||".png"}`}async function tG(e){try{await t.unlink(tB(e))}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function tX(e){return"live"===e.kind}async function tq(e,n){if(!Number.isInteger(n)||n<1)throw new N("INVALID_ARGS","Screenshot max size must be a positive integer");let a=await eZ(await t.readFile(e),"screenshot"),r=Math.max(a.width,a.height);if(r<=n)return;let i=n/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 _({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 t.writeFile(e,await eQ(l))}let tY=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new N("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await tD(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 tq(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...f(`Saved screenshot: ${a.path}`)}};function tK(e,t){let n=Y(e.type??"Element"),a=K(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 tF(e,t){return t.flatten?e.map(e=>({text:q(e,0,!1),comparable:tK(e,0)})):F(e).map(e=>({text:e.text,comparable:tK(e.node,e.depth)}))}function tV(e,t){return e.get(t)??0}function tj(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 tH=async(e,t)=>{var n;let a,r,s=await tW(e,t),o=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(tj(r.nodes))!==JSON.stringify(tj(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:s.session?.snapshot,current:s.snapshot,options:t,identity:{previousAppBundleId:s.session?.appBundleId,currentAppBundleId:s.result.appBundleId??s.session?.appBundleId}});return await e.sessions.set(tJ(t.session,s)),{nodes:s.snapshot.nodes,truncated:s.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:a,snapshotRaw:r}=e;if(r||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let s=i(n),o=new Set;return s.hiddenCount>0&&o.add("offscreen-nodes"),s.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),s.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:s.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:s.snapshot.nodes,backend:s.snapshot.backend,snapshotRaw:t.raw}),...u({...s.annotations,warnings:s.warnings}),...o?{unchanged:o}:{},...s.result.snapshotDiagnostics?{snapshotDiagnostics:s.result.snapshotDiagnostics}:{},...(a=(n=s).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},tz=async(e,t)=>{let n=await tW(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=tJ(t.session,n);if(!r){let t=function(e,t={}){return tF(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&&tV(i,r-1)<tV(i,r+1)?tV(i,r+1):tV(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&&tV(r,l-1)<tV(r,l+1)?l+1:l-1,u=tV(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[]}(tF(e,n),tF(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 tW(e,t){var n,a,r,i,s,l,d;let u,c,p,h,f;if(!e.backend.captureSnapshot)throw new N("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:o(r)},n.presentationKey?n:{...n,presentationKey:V(t)}),y=k(g),x=o(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??x,runtimeNow:x}).annotations.warnings??[]],i.annotations.quality&&u.push(...M(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=v(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 tZ}(i))&&u.push(f),u.push(...(l=i.annotations.freshness,d=i.snapshot.backend,l?.staleAfterRetries&&"android"===d?"stuck-route"===l.reason?[`Recent ${l.action} was followed by a nearly identical snapshot after ${l.retryCount} automatic retr${1===l.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"===l.reason?[tZ]:[]:[])),Array.from(new Set(u)))}}function tJ(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 tZ="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.",tQ=async(e,t)=>await t4(e,t,"press"),t0=async(e,t)=>await t4(e,t,"click"),t1=async(e,t)=>{var n;if(!t.text)throw new N("INVALID_ARGS","fill requires text");let a=await b(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new N("UNSUPPORTED_OPERATION","fill is not supported by this backend");let r=w(await e.backend.fill(y(e,t),a.point,t.text,{delayMs:t.delayMs})),i="node"in a?a.node.type??"":"",s=i&&!ed(i,e.backend.platform)?`fill target ${n=a,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${i}", attempting fill anyway.`:void 0;return{...a,text:t.text,...s?{warning:s}:{},...r?{backendResult:r}:{}}},t2=async(e,t)=>{let n=t.text;if(!n)throw new N("INVALID_ARGS","type requires text");let a=eU(n);if(a)throw new N("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 N("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=x(t.delayMs??0,"delay-ms",0,1e4),i=w(await e.backend.typeText(y(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...f(`Typed ${Array.from(n).length} chars`)}};async function t4(e,t,n){let a=await b(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new N("UNSUPPORTED_OPERATION","tap is not supported by this backend");let r=w(await e.backend.tap(y(e,t),a.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...a,...r?{backendResult:r}:{}}}function t3(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function t5(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,s=z(n),o=ee(n,i),d=!0===n.selected,u="text"===t?Z(n):function(e,t,n){var a,r,i;let s;if("android"===n&&!1===e.visibleToUser)return!1;if(t8(e.rect))return function(e,t){return l(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=Q(r),W(r,a,s,e=>!function(e,t){if("android"===t&&!1===e.visibleToUser)return!1;let n=el(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&&t8(e.rect):!0===e.hittable||t8(e.rect))}(e,i)?null:e));return!!o&&(t8(o.rect)?function(e,t){return l(e,t)}(o,t):"android"!==n&&!0===o.hittable)}(n,a,i),c=!1;switch(t){case"visible":c=u;break;case"hidden":c=!u;break;case"editable":c=o;break;case"selected":c=d;break;case"text":c=s===(r??"")}let p="text"===t?`expected="${r??""}" actual="${s}"`:`actual=${JSON.stringify({visible:u,editable:o,selected:d})}`;return{pass:c,actualText:s,details:p}}function t8(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 t6(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new N("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new N("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function t9(e,t,n={updateSession:!0}){let a=e.backend.captureSnapshot;if(!a)throw new N("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",i=await e.sessions.get(r),l=await a(y(e,t),{interactiveOnly:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),d=l.snapshot??{nodes:l.nodes??[],truncated:l.truncated,backend:l.backend,...l.quality?{snapshotQuality:l.quality}:{},createdAt:o(e)};return n.updateSession&&i&&!s(d.snapshotQuality)&&await e.sessions.set({...i,snapshot:d}),{sessionName:r,session:i,snapshot:d}}async function t7(e,t,n){if(e.backend.readText){let a=await e.backend.readText(y(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return es(n)}let ne=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new N("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nd(e,t,n);let{capture:a,match:r}=await nu(e,t,n);if(!r)throw new N("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 t7(e,a,r),node:r}},nt=async(e,t)=>{if("ref"===t.target.kind){let n=await t6(e,t.session),a=function(e,t,n){let a=j(t);if(!a)throw new N("INVALID_ARGS",n.invalidRefMessage);let r=H(e,a)??(n.fallbackLabel.length>0?er(e,n.fallbackLabel):null);if(!r)throw new N("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=en(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 t7(e,n,a.node),node:a.node,selectorChain:r}}let n=await nf(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=en(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 t7(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},nn=async(e,t)=>{let n=await nt(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new N("COMMAND_FAILED","getText returned non-text result");return n},na=async(e,t)=>{let n=await nt(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new N("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nr=async(e,t)=>{if(!t3(t.predicate))throw new N("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new N("INVALID_ARGS","is text requires expected text value");let n=await t9(e,t,{updateSession:!0}),a=J(t.selector);if("exists"===t.predicate){let r=et(n.snapshot.nodes,a,{platform:e.backend.platform});if(!r)throw new N("COMMAND_FAILED",eo(a,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:r.selector.raw,matches:r.matches,selectorChain:a.selectors.map(e=>e.raw)}}let r=ea(n.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!r)throw new N("COMMAND_FAILED",eo(a,[],{unique:!0}),{command:"is",reason:"selector_not_found",predicate:t.predicate,selector:a.raw});let i=t5({predicate:t.predicate,node:r.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!i.pass)throw new N("COMMAND_FAILED",`is ${t.predicate} failed for selector ${r.selector.raw}: ${i.details}`,{command:"is",reason:"predicate_failed",predicate:t.predicate,selector:r.selector.raw,predicateDetails:i.details});return{predicate:t.predicate,pass:!0,selector:r.selector.raw,..."text"===t.predicate?{text:i.actualText}:{},selectorChain:a.selectors.map(e=>e.raw)}},ni=async(e,t)=>await nr(e,{...t,predicate:"visible",selector:t.target.selector}),ns=async(e,t)=>await nr(e,{...t,predicate:"hidden",selector:t.target.selector}),no=async(e,t)=>{if("sleep"===t.target.kind)return await d(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await t6(e,t.session),a=j(t.target.ref);if(!a)throw new N("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=H(n.snapshot.nodes,a),i=r?ei(r,n.snapshot.nodes):void 0;if(!i)throw new N("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await np(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nc(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new N("INVALID_ARGS","wait requires text");return await np(e,t,t.target.text,t.target.timeoutMs)},nl=async(e,t)=>{let n=await no(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new N("COMMAND_FAILED","waitForText returned non-text result");return n};async function nd(e,t,n){let a=t.timeoutMs??1e4,r=o(e);for(;o(e)-r<a;){let{match:a}=await nu(e,t,n);if(a)return{kind:"found",found:!0,waitedMs:o(e)-r};await d(e,300)}throw new N("COMMAND_FAILED","find wait timed out")}async function nu(e,t,n){let a=await t9(e,t,{updateSession:!0,scope:"text"===n||"label"===n||"any"===n?t.query:void 0});if(s(a.snapshot.snapshotQuality))throw new N("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=eu(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];return{capture:a,match:r}}async function nc(e,t,n,a){let r=a??1e4,i=o(e),s=J(n);for(;o(e)-i<r;){let n=et((await t9(e,t,{updateSession:!0})).snapshot.nodes,s,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:o(e)-i};await d(e,300)}throw new N("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function np(e,t,n,a){let r=a??1e4,i=o(e);for(;o(e)-i<r;){if(e.backend.findText?(await e.backend.findText(y(e,t),n)).found:await nh(e,t,n))return{kind:"text",text:n,waitedMs:o(e)-i};await d(e,300)}throw new N("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nh(e,t,n){return!!er((await t9(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nf(e,t,n,a){let r=await t9(e,{...t,session:n},{updateSession:!0}),i=J(a.selector),s=ea(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!s)throw new N("COMMAND_FAILED",eo(i,[],{unique:!0}));return{capture:r,node:s.node,selector:s.selector.raw,ref:`@${s.node.ref}`}}function nm(e,t){if(void 0!==e)return nw(e,t)}function nw(e,t){let n=e?.trim();if(!n)throw new N("INVALID_ARGS",`${t} must be a non-empty string`);return n}let ng=async(e,t={})=>{if(!e.backend.listDevices)throw new N("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(y(e,t),t.filter)}},nb=async(e,t={})=>{if(!e.backend.bootDevice)throw new N("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=nR(t.target),a=w(await e.backend.bootDevice(y(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...f("Booted device")}},ny=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new N("UNSUPPORTED_OPERATION","admin.shutdown is not supported by this backend");let n=nR(t.target),a=w(await e.backend.shutdownDevice(y(e,t),n));return{kind:"deviceShutdown",...n?{target:n}:{},...a?{backendResult:a}:{},...f("Shutdown device")}},nk=async(e,t)=>await nA(e,t,"install"),nx=async(e,t)=>await nA(e,t,"reinstall"),nv=async(e,t)=>await nA(e,t,"installFromSource");async function nA(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new N("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?nw(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new N("INVALID_ARGS",`admin.${n} requires app`);let s=y(e,t),o=await nM(e,s,t.source);try{var l,d,u,c,p;let t,a,h,m,g,b,y,k,x=await r.call(e.backend,s,{...i?{app:i}:{},source:o.source});return l=n,d=i,u=o.source,c=x,t=w(c),a=nN(c,"appName"),h=nN(c,"appId"),m=nN(c,"bundleId"),g=nN(c,"packageName"),b=nN(c,"launchTarget"),y=nN(c,"installablePath"),k=nN(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...h?{appId:h}:{},...a?{appName:a}:{},...m?{bundleId:m}:{},...g?{packageName:g}:{},...b?{launchTarget:b}:{},...y?{installablePath:y}:{},...k?{archivePath:k}:{},...t?{backendResult:t}:{},...f(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??b??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await o.cleanup?.()}}async function nM(e,t,n){let a=nP(n),r=await nI(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nP(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function nI(e,t){if("url"===t.kind)return{source:t};let n=await tO(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nP(e){if(!e||"object"!=typeof e)throw new N("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nw(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nw(e.id,"source.id")};if("url"===e.kind){let t=nw(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new N("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new N("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new N("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function nR(e){if(!e)return;let t=nm(e.id,"target.id"),n=nm(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 nN(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}let nS=/^[A-Za-z0-9_.:-]{1,64}$/,n_=async(e,t)=>{var n;if(!e.backend.openApp)throw new N("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=nm(e.app,"app"),a=nm(e.appId,"appId"),r=nm(e.bundleId,"bundleId"),i=nm(e.packageName,"packageName"),s=nm(e.url,"url"),o=nm(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 N("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=w(await e.backend.openApp(nL(e,t),a,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...f(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},nO=async(e,t={})=>{if(!e.backend.closeApp)throw new N("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nm(t.app,"app"),a=w(await e.backend.closeApp(nL(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...f(n?`Closed: ${n}`:"Closed app")}},nD=async(e,t={})=>{if(!e.backend.listApps)throw new N("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nL(e,t),ep(t.filter))}},nE=async(e,t)=>{if(!e.backend.getAppState)throw new N("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nw(t.app,"app"),a=await e.backend.getAppState(nL(e,t),n);return{kind:"appState",app:n,state:a}},nT=async(e,t)=>{if(!e.backend.pushFile)throw new N("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nw(t.app,"app"),a=await nU(e,t.input);try{let r=await e.backend.pushFile(nL(e,t),a.backendInput,n),i=w(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...f(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},nC=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new N("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nw(e,"name");if(!nS.test(t))throw new N("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&&n$(n,a,8192);let i=w(await e.backend.triggerAppEvent(nL(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...f(`Triggered app event: ${r}`)}};async function nU(e,t){if(!t||"object"!=typeof t)throw new N("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return n$(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await tO(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function n$(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new N("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 N("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new N("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new N("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nL(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}let nB=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,nG=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function nX(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(nG,()=>(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()))nB.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 nY=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function nK(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(nY.test(a))n[a]="[REDACTED]",t=!0;else{let e=nH(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function nF(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=nj(t,nX);return nz(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??nH(e,2048)}function nV(e){return nj(e,e=>nH(e,2048))}function nj(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=nj(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(nY.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=nj(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function nH(e,t){if(void 0===e)return{redacted:!1};let n=nX(e);return nz(n.value,t,n.redacted)}function nz(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 nW=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new N("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await nQ(e,t),{...n0(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:n2(a.levels,"levels")}:{},...void 0!==a.search?{search:nw(a.search,"search")}:{},...void 0!==a.source?{source:nw(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=nH(e.message,4096),n=nV(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}:{}}},nJ=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new N("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let s={...n0(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 N("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await nQ(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)??nH(t,2048):void 0,r="headers"===a||"all"===a?nK(e.requestHeaders):void 0,s="headers"===a||"all"===a?nK(e.responseHeaders):void 0,o="body"===a||"all"===a?nF(e.requestBody):void 0,l="body"===a||"all"===a?nF(e.responseBody):void 0,d=nV(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}:{}}},nZ=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new N("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await nQ(e,t),{...n1(a=t),...void 0!==a.sampleMs?{sampleMs:x(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:n2(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=nH(e.message,4096),n=nV(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 nQ(e,t){let n=y(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 n0(e,t,n,a){return{...n1(e),...void 0!==e.cursor?{cursor:nw(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:x(e.limit,a,1,n)}}function n1(e){return{...void 0!==e.since?{since:nw(e.since,"since")}:{},...void 0!==e.until?{until:nw(e.until,"until")}:{}}}function n2(e,t,n=50){if(!Array.isArray(e))throw new N("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new N("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>nw(e,`${t}[${n}]`))}let n4=async(e,t)=>{let n=n5(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new N("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await tD(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,s,o,l,d;let u,c,p=(i=t,s=r?.path,u=void 0===i.fps?void 0:x(i.fps,"fps",1,60),c=void 0===i.quality?void 0:x(i.quality,"quality",5,10),{...s?{outPath:s}:{},...void 0!==u?{fps:u}:{},...void 0!==c?{quality:c}:{},...void 0!==i.hideTouches?{showTouches:!0!==i.hideTouches}:{}}),h=await a.call(e.backend,y(e,t),p),f=await r?.publish();return o=n,l=h,d=f,{..."string"==typeof l.path?{path:l.path}:{},..."string"==typeof l.telemetryPath?{telemetryPath:l.telemetryPath}:{},..."string"==typeof l.warning?{warning:l.warning}:{},...n8(o,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},n3=async(e,t)=>{let n=n5(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new N("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await tD(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,y(e,t),l),u=await r?.publish();return i=n,s=d,o=u,{..."string"==typeof s.outPath?{outPath:s.outPath}:{},...n8(i,s,o,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}};function n5(e,t){if("start"===e||"stop"===e)return e;throw new N("INVALID_ARGS",`${t} action must be start or stop`)}function n8(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...f("start"===e?a.startMessage:a.stopMessage)}}let n6=async(e,t={})=>{if(!e.backend.pressBack)throw new N("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new N("INVALID_ARGS","system.back mode must be in-app or system");let a=w(await e.backend.pressBack(y(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...f("Back")}},n9=async(e,t={})=>{if(!e.backend.pressHome)throw new N("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=w(await e.backend.pressHome(y(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...f("Home")}},n7=async(e,t)=>{if(!e.backend.rotate)throw new N("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 N("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=w(await e.backend.rotate(y(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...f(`Rotated to ${n}`)}},ae=async(e,t={})=>{var n,a,r,i,s,o,l;if(!e.backend.setKeyboard)throw new N("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let d=t.action??"status";if(!eC(d))throw new N("INVALID_ARGS","system.keyboard action must be status, get, dismiss, enter, or return");let u=await e.backend.setKeyboard(y(e,t),{action:d}),c=w(u),p=(n=u)&&"object"==typeof n?u:{};return"enter"===d||"return"===d?{kind:"keyboardEnterPressed",action:"enter",state:p,...(a=c)?{backendResult:a}:{},...f("Keyboard enter pressed")}:"dismiss"===d?(r=d,{kind:"keyboardDismissed",action:r,state:i=p,...(s=c)?{backendResult:s}:{},...f(!1===i.dismissed?"Keyboard already hidden":"Keyboard dismissed")}):(o=d,{kind:"keyboardState",action:o,state:p,...(l=c)?{backendResult:l}:{}})},at=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new N("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(y(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new N("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new N("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new N("INVALID_ARGS","system.clipboard write requires text");let n=w(await e.backend.setClipboard(y(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...f("Clipboard updated")}},an=async(e,t={})=>{if(!e.backend.openSettings)throw new N("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=nm(t.target,"target"),a=w(await e.backend.openSettings(y(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...f(n?`Opened settings: ${n}`:"Opened settings")}},aa=async(e,t={})=>{var n,a;if(!e.backend.handleAlert)throw new N("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 N("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let i=void 0===t.timeoutMs?void 0:x(t.timeoutMs,"timeoutMs",0,12e4),s=await e.backend.handleAlert(y(e,t),r,{timeoutMs:i});return n=r,a=s,"get"===n?function(e){if("alertStatus"!==e.kind)throw new N("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 N("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}:{},...f(e.alert?"Alert visible":"Alert wait timed out")}}(a):function(e,t){if("alertHandled"!==t.kind)throw new N("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}:{},...f(t.handled?`Alert ${e}ed`:"No alert handled")}}(n,a)},ar=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new N("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=w(await e.backend.openAppSwitcher(y(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...f("Opened app switcher")}};function ai(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,as(e)]));return{get:e=>as(t.get(e)),set:e=>{t.set(e.name,as(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>as(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=>tY(t,e),diffScreenshot:e=>tT(t,e),snapshot:e=>tH(t,e),diffSnapshot:e=>tz(t,e)},selectors:{find:e=>ne(t,e),get:e=>nt(t,e),getText:(e,n={})=>nn(t,{...n,target:e}),getAttrs:(e,n={})=>na(t,{...n,target:e}),is:e=>nr(t,e),isVisible:(e,n={})=>ni(t,{...n,target:e}),isHidden:(e,n={})=>ns(t,{...n,target:e}),wait:e=>no(t,e),waitForText:(e,n={})=>nl(t,{...n,text:e})},interactions:{click:(e,n={})=>t0(t,{...n,target:e}),press:(e,n={})=>tQ(t,{...n,target:e}),fill:(e,n,a={})=>t1(t,{...a,target:e,text:n}),typeText:(e,n={})=>t2(t,{...n,text:e}),focus:(e,n={})=>m(t,{...n,target:e}),longPress:(e,n={})=>p(t,{...n,target:e}),swipe:e=>g(t,e),scroll:e=>c(t,e),pinch:e=>A(t,e)},system:{back:e=>n6(t,e),home:e=>n9(t,e),rotate:e=>n7(t,e),keyboard:e=>ae(t,e),clipboard:e=>at(t,e),settings:e=>an(t,e),alert:e=>aa(t,e),appSwitcher:e=>ar(t,e)},apps:{open:e=>n_(t,e),close:e=>nO(t,e),list:(e={})=>nD(t,{...e,filter:ec(e.filter)}),state:e=>nE(t,e),push:e=>nT(t,e),triggerEvent:e=>nC(t,e)},admin:{devices:e=>ng(t,e),boot:e=>nb(t,e),shutdown:e=>ny(t,e),install:e=>nk(t,e),reinstall:e=>nx(t,e),installFromSource:e=>nv(t,e)},recording:{record:e=>n4(t,e),trace:e=>n3(t,e)},observability:{logs:e=>nW(t,e),network:e=>nJ(t,e),perf:e=>nZ(t,e)}}}function as(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 ao(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}export{eR as appendScriptSeriesFlags,ai as createAgentDevice,eZ as decodePngAsync,eQ as encodePngAsync,t5 as evaluateIsPredicate,eU as findMistargetedTypeRefToken,eE as formatPortableActionLine,eP as formatScriptActionSummary,ex as formatScriptArg,ev as formatScriptStringLiteral,eb as isClickLikeCommand,eC as isKeyboardAction,t3 as isSupportedPredicate,ey as isTouchTargetCommand,ao as localCommandPolicy,eD as parseReplayOpenFlags,e_ as parseReplayRuntimeFlags,eS as parseReplaySeriesFlags,eW as prewarmPngWorker,eJ as terminatePngWorker};
|
package/dist/src/1231.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{asAppError as t,AppError as e}from"./9152.js";
|
|
1
|
+
import{asAppError as t,AppError as e}from"./9152.js";import{normalizeBatchCommandName as r,INHERITED_PARENT_FLAG_KEYS as o,assertBatchRuntimeCommandAllowed as a,BATCH_DAEMON_STEP_KEYS as n}from"./6088.js";let s=new Set(n);async function i(e,r,o){let a=e.flags,n=a?.batchOnError??"stop";if("stop"!==n)return p("INVALID_ARGS",`Unsupported batch on-error mode: ${n}.`);let s=a?.batchMaxSteps??100;if(!Number.isInteger(s)||s<1||s>1e3)return p("INVALID_ARGS",`Invalid batch max-steps: ${String(a?.batchMaxSteps)}`);try{let t=l(a?.batchSteps,s),n=Date.now(),i=[];for(let[a,n]of t.entries()){let s=await h(e,r,n,o,a+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:a,total:t.length,partialResults:i}}};i.push(s.result)}return{ok:!0,data:{total:t.length,executed:t.length,totalDurationMs:Date.now()-n,results:i}}}catch(r){let e=t(r);return p(e.code,e.message,e.details)}}function l(t,o){if(!Array.isArray(t)||0===t.length)throw new e("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(t.length>o)throw new e("INVALID_ARGS",`batch has ${t.length} steps; max allowed is ${o}.`);let n=[];for(let o=0;o<t.length;o+=1){let i=t[o];if(!i||"object"!=typeof i)throw new e("INVALID_ARGS",`Invalid batch step at index ${o}.`);let l=Object.keys(i).filter(t=>!s.has(t));if(l.length>0){let t=l.map(t=>`"${t}"`).join(", ");throw new e("INVALID_ARGS",`Batch step ${o+1} has unknown field(s): ${t}. Allowed fields: command, positionals, flags, runtime.`)}let c=r(i.command);if(!c)throw new e("INVALID_ARGS",`Batch step ${o+1} requires command.`);if(a(c,o+1),void 0!==i.positionals&&!Array.isArray(i.positionals))throw new e("INVALID_ARGS",`Batch step ${o+1} positionals must be an array.`);let m=i.positionals??[];if(m.some(t=>"string"!=typeof t))throw new e("INVALID_ARGS",`Batch step ${o+1} positionals must contain only strings.`);if(void 0!==i.flags&&("object"!=typeof i.flags||Array.isArray(i.flags)||!i.flags))throw new e("INVALID_ARGS",`Batch step ${o+1} flags must be an object.`);if(void 0!==i.runtime&&("object"!=typeof i.runtime||Array.isArray(i.runtime)||!i.runtime))throw new e("INVALID_ARGS",`Batch step ${o+1} runtime must be an object.`);n.push({command:c,positionals:m,flags:i.flags??{},runtime:i.runtime})}return n}function c(t,e){let{batchSteps:r,batchOnError:o,batchMaxSteps:a,...n}=e??{};return m(t,n)}function m(t,e){let r=t??{};for(let t of o)void 0===e[t]&&void 0!==r[t]&&(e[t]=r[t]);return e}async function h(t,e,r,o,a){let n=Date.now(),s=c(t.flags,r.flags);void 0===s.session&&(s.session=e);let i=await o({token:t.token,session:e,command:r.command,positionals:r.positionals,flags:s,runtime:void 0===r.runtime?t.runtime:r.runtime,meta:t.meta}),l=Date.now()-n;return i.ok?{ok:!0,step:a,result:{step:a,command:r.command,ok:!0,data:i.data??{},durationMs:l}}:{ok:!1,step:a,error:i.error}}function p(t,e,r){return{ok:!1,error:{code:t,message:e,...r?{details:r}:{}}}}export{c as buildBatchStepFlags,m as mergeParentFlags,i as runBatch,l as validateAndNormalizeBatchSteps};
|