agent-device 0.17.7 → 0.17.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.7.apk → agent-device-android-multitouch-helper-0.17.8.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.8.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.7.manifest.json → agent-device-android-multitouch-helper-0.17.8.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.7.apk → agent-device-android-snapshot-helper-0.17.8.apk} +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.8.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.7.manifest.json → agent-device-android-snapshot-helper-0.17.8.manifest.json} +6 -6
  7. package/dist/src/2133.js +1 -1
  8. package/dist/src/2577.js +1 -0
  9. package/dist/src/4428.js +1 -1
  10. package/dist/src/8184.js +1 -1
  11. package/dist/src/8358.js +4 -0
  12. package/dist/src/9581.js +13 -2
  13. package/dist/src/9722.js +36 -36
  14. package/dist/src/9873.js +1 -1
  15. package/dist/src/9919.js +5 -5
  16. package/dist/src/cli-help.js +18 -7
  17. package/dist/src/cli.js +28 -18
  18. package/dist/src/interaction.js +1 -1
  19. package/dist/src/internal/bin.js +1 -1
  20. package/dist/src/record-trace-recording.js +1 -1
  21. package/dist/src/selector-runtime.js +1 -1
  22. package/dist/src/session.js +1 -1
  23. package/dist/src/snapshot.js +1 -1
  24. package/package.json +1 -1
  25. package/server.json +2 -2
  26. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.7.apk.sha256 +0 -1
  27. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.7.apk.sha256 +0 -1
  28. package/dist/src/2892.js +0 -4
  29. package/dist/src/368.js +0 -1
@@ -0,0 +1 @@
1
+ 7babb1a8cfdc9ea488cb6d419067a5345cf287581532de6a388b3c0f6bb9f72f agent-device-android-multitouch-helper-0.17.8.apk
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "android-multitouch-helper",
3
- "version": "0.17.7",
4
- "assetName": "agent-device-android-multitouch-helper-0.17.7.apk",
5
- "sha256": "cc41db9a5e5f7df8bdf302c3d4e6130ed7b35f1012bd37d2db583b70a0104ee8",
3
+ "version": "0.17.8",
4
+ "assetName": "agent-device-android-multitouch-helper-0.17.8.apk",
5
+ "sha256": "7babb1a8cfdc9ea488cb6d419067a5345cf287581532de6a388b3c0f6bb9f72f",
6
6
  "packageName": "com.callstack.agentdevice.multitouchhelper",
7
- "versionCode": 17007,
7
+ "versionCode": 17008,
8
8
  "instrumentationRunner": "com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation",
9
9
  "statusProtocol": "android-multitouch-helper-v1"
10
10
  }
@@ -0,0 +1 @@
1
+ 95eff5dda23179abb7da5bcf1650fb4e9ebcf40ae08871936683233aee152914 agent-device-android-snapshot-helper-0.17.8.apk
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "android-snapshot-helper",
3
- "version": "0.17.7",
4
- "releaseTag": "v0.17.7",
5
- "assetName": "agent-device-android-snapshot-helper-0.17.7.apk",
3
+ "version": "0.17.8",
4
+ "releaseTag": "v0.17.8",
5
+ "assetName": "agent-device-android-snapshot-helper-0.17.8.apk",
6
6
  "apkUrl": null,
7
- "sha256": "a8d1788b652e75d6542891763afee0213d38d02825f453a1b5d0edfca6ad8cd4",
8
- "checksumName": "agent-device-android-snapshot-helper-0.17.7.apk.sha256",
7
+ "sha256": "95eff5dda23179abb7da5bcf1650fb4e9ebcf40ae08871936683233aee152914",
8
+ "checksumName": "agent-device-android-snapshot-helper-0.17.8.apk.sha256",
9
9
  "packageName": "com.callstack.agentdevice.snapshothelper",
10
- "versionCode": 17007,
10
+ "versionCode": 17008,
11
11
  "instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
12
12
  "minSdk": 23,
13
13
  "targetSdk": 36,
package/dist/src/2133.js CHANGED
@@ -1 +1 @@
1
- import{AppError as e}from"./733.js";let t={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",close:"close",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",gesture:"gesture",get:"get",home:"home",install:"install",installFromSource:"install-from-source",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",open:"open",perf:"perf",prepare:"prepare",press:"press",push:"push",record:"record",reactNative:"react-native",reinstall:"reinstall",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",shutdown:"shutdown",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"},s={installSource:"install_source",leaseAllocate:"lease_allocate",leaseHeartbeat:"lease_heartbeat",leaseRelease:"lease_release",releaseMaterializedPaths:"release_materialized_paths",runtime:"runtime",sessionList:"session_list"},a={auth:"auth",connect:"connect",connection:"connection",debug:"debug",disconnect:"disconnect",mcp:"mcp",metro:"metro",reactDevtools:"react-devtools",session:"session",web:"web"},r=["pan","fling","swipe","pinch","rotate","transform"],o=`gesture requires one of: ${r.join(", ")}`,n=c(a.auth,a.connect,a.connection,a.disconnect,a.mcp,a.reactDevtools,a.web,t.prepare);function c(...e){return new Set(e)}function i(){return[...Object.values(t),...Object.values(a)].sort()}function l(e){return Object.values(t).includes(e)||e===a.debug||e===a.metro||e===a.session}function p(){return i().filter(e=>!n.has(e))}c(a.auth,a.connect,a.connection,a.debug,a.disconnect,a.mcp,a.metro,a.reactDevtools,a.session,a.web,t.appState,t.prepare,t.batch,t.devices,t.gesture,t.replay,t.test,t.trace);let u=[t.devices,t.boot,t.shutdown,t.apps,t.open,t.close,t.install,t.reinstall,t.installFromSource,t.push,t.triggerAppEvent,t.snapshot,t.screenshot,t.diff,t.wait,t.alert,t.settings,t.click,t.press,t.longPress,t.swipe,t.focus,t.type,t.fill,t.scroll,t.get,t.gesture,t.is,t.find,t.perf,t.logs,t.network,t.record,t.trace,t.test,t.appState,t.back,t.home,t.rotate,t.appSwitcher,t.keyboard,t.clipboard,t.reactNative],d=new Set(["batch","replay"]),m=["command","positionals","flags","runtime"],h=["platform","target","device","udid","serial","verbose","out"],f=new Set(u);function g(e){return"string"==typeof e?e.trim().toLowerCase():""}function b(t,s){let a=g(t);if(f.has(a))return a;throw new e("INVALID_ARGS",`Batch step ${s} command is not available through command batch: ${String(t)}`)}function _(t,s){if(d.has(t))throw new e("INVALID_ARGS",`Batch step ${s} cannot run ${t}.`)}export{d as BATCH_BLOCKED_COMMANDS,m as BATCH_DAEMON_STEP_KEYS,r as GESTURE_KINDS,o as GESTURE_SUBCOMMAND_ERROR,h as INHERITED_PARENT_FLAG_KEYS,s as INTERNAL_COMMANDS,t as PUBLIC_COMMANDS,u as STRUCTURED_BATCH_COMMAND_NAMES,_ as assertBatchRuntimeCommandAllowed,l as isClientBackedCliCommandName,i as listCliCommandNames,p as listMcpExposedCommandNames,g as normalizeBatchCommandName,b as readStructuredBatchCommandName};
1
+ import{AppError as e}from"./733.js";let t={alert:"alert",appState:"appstate",appSwitcher:"app-switcher",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",close:"close",clipboard:"clipboard",devices:"devices",diff:"diff",fill:"fill",find:"find",focus:"focus",gesture:"gesture",get:"get",home:"home",install:"install",installFromSource:"install-from-source",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",open:"open",perf:"perf",prepare:"prepare",press:"press",push:"push",record:"record",reactNative:"react-native",reinstall:"reinstall",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",shutdown:"shutdown",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",wait:"wait"},s={installSource:"install_source",leaseAllocate:"lease_allocate",leaseHeartbeat:"lease_heartbeat",leaseRelease:"lease_release",releaseMaterializedPaths:"release_materialized_paths",runtime:"runtime",sessionList:"session_list"},a={auth:"auth",connect:"connect",connection:"connection",debug:"debug",disconnect:"disconnect",mcp:"mcp",metro:"metro",proxy:"proxy",reactDevtools:"react-devtools",session:"session",web:"web"},r=["pan","fling","swipe","pinch","rotate","transform"],o=`gesture requires one of: ${r.join(", ")}`,n=c(a.auth,a.connect,a.connection,a.disconnect,a.mcp,a.proxy,a.reactDevtools,a.web,t.prepare);function c(...e){return new Set(e)}function i(){return[...Object.values(t),...Object.values(a)].sort()}function l(e){return Object.values(t).includes(e)||e===a.debug||e===a.metro||e===a.session}function p(){return i().filter(e=>!n.has(e))}c(a.auth,a.connect,a.connection,a.debug,a.disconnect,a.mcp,a.metro,a.proxy,a.reactDevtools,a.session,a.web,t.appState,t.prepare,t.batch,t.devices,t.gesture,t.replay,t.test,t.trace);let u=[t.devices,t.boot,t.shutdown,t.apps,t.open,t.close,t.install,t.reinstall,t.installFromSource,t.push,t.triggerAppEvent,t.snapshot,t.screenshot,t.diff,t.wait,t.alert,t.settings,t.click,t.press,t.longPress,t.swipe,t.focus,t.type,t.fill,t.scroll,t.get,t.gesture,t.is,t.find,t.perf,t.logs,t.network,t.record,t.trace,t.test,t.appState,t.back,t.home,t.rotate,t.appSwitcher,t.keyboard,t.clipboard,t.reactNative],d=new Set(["batch","replay"]),m=["command","positionals","flags","runtime"],h=["platform","target","device","udid","serial","verbose","out"],f=new Set(u);function g(e){return"string"==typeof e?e.trim().toLowerCase():""}function b(t,s){let a=g(t);if(f.has(a))return a;throw new e("INVALID_ARGS",`Batch step ${s} command is not available through command batch: ${String(t)}`)}function _(t,s){if(d.has(t))throw new e("INVALID_ARGS",`Batch step ${s} cannot run ${t}.`)}export{d as BATCH_BLOCKED_COMMANDS,m as BATCH_DAEMON_STEP_KEYS,r as GESTURE_KINDS,o as GESTURE_SUBCOMMAND_ERROR,h as INHERITED_PARENT_FLAG_KEYS,s as INTERNAL_COMMANDS,t as PUBLIC_COMMANDS,u as STRUCTURED_BATCH_COMMAND_NAMES,_ as assertBatchRuntimeCommandAllowed,l as isClientBackedCliCommandName,i as listCliCommandNames,p as listMcpExposedCommandNames,g as normalizeBatchCommandName,b as readStructuredBatchCommandName};
@@ -0,0 +1 @@
1
+ import e from"node:crypto";import t,{promises as n}from"node:fs";import a from"node:path";import{Worker as r}from"node:worker_threads";import{fileURLToPath as i}from"node:url";import s from"node:os";import{buildMobileSnapshotPresentation as o,isSparseSnapshotQualityVerdict as l,now as d,isNodeVisibleInEffectiveViewport as u,sleep as c,publicSnapshotCaptureAnnotations as p,scrollCommand as h,longPressCommand as f,appendScreenshotScriptFlags as m,successText as w,focusCommand as g,toBackendResult as b,swipeCommand as y,recordingQualityInputToExportQuality as k,resolveInteractionTarget as v,toBackendContext as x,snapshotCaptureAnnotationsFrom as A,requireIntInRange as M,formatReactNativeOverlayWarning as S,pinchCommand as I,renderSnapshotQualityWarnings as R}from"./9873.js";import{emitDiagnostic as P}from"./432.js";import{asAppError as N,toAppErrorCode as _,AppError as D}from"./733.js";import{computeScreenshotDiffPixels as O,PNG as E,toBuffer as T,decodePng as C}from"./4418.js";import{expandRect as U,intersectArea as L,unionRects as $,rectCenter as B,clamp as q,normalizedRect as G,squaredDistance as X}from"./6024.js";import{whichCmd as Y,runCmd as F}from"./8875.js";import{formatSnapshotLine as K,formatRole as j,displayLabel as H,buildSnapshotDisplayLines as V}from"./7244.js";import{normalizeRef as z,findNodeByRef as W,buildSnapshotPresentationKey as J,usesMobileSnapshotPresentation as Z}from"./4291.js";import{extractNodeText as Q,findSnapshotAncestor as ee,parseSelectorChain as et,isNodeVisible as en,buildSnapshotNodeByIndex as ea,isNodeEditable as er,findSelectorChainMatch as ei,buildSelectorChainForNode as es,resolveSelectorChain as eo,findNodeByLabel as el,resolveRefLabel as ed,extractReadableText as eu,formatSelectorFailure as ec,normalizeType as ep,isFillableType as eh}from"./9836.js";import{findBestMatchesByLocator as ef}from"./587.js";import{isProcessAlive as em,readProcessStartTime as ew}from"./5628.js";import{sleep as eg}from"./5560.js";import{resolveAppsFilter as eb,assertResolvedAppsFilter as ey}from"./2748.js";let ek=/^-?\d+(\.\d+)?$/,ev=/^[^\s"\\]+$/,ex=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),eA=new Map([["--count","count"],["--pause-ms","pauseMs"]]),eM=new Map([["--delay-ms","delayMs"]]);function eS(e){return"click"===e||"press"===e}function eI(e){return eS(e)||"longpress"===e}function eR(e){return"type"===e||"fill"===e}function eP(e){return e_(e,eD)}function eN(e){return JSON.stringify(e)}function e_(e,t){return t(e)?e:eN(e)}function eD(e){return eO(e)&&e.startsWith("@")||ek.test(e)}function eO(e){return ev.test(e)}function eE(e){let t=(e.positionals??[]).map(e=>eP(e));return[e.command,...t].join(" ")}function eT(e,t){let n=t.flags??{};if(eS(t.command)){"number"==typeof n.count&&e.push("--count",String(n.count)),"number"==typeof n.intervalMs&&e.push("--interval-ms",String(n.intervalMs)),"number"==typeof n.holdMs&&e.push("--hold-ms",String(n.holdMs)),"number"==typeof n.jitterPx&&e.push("--jitter-px",String(n.jitterPx)),!0===n.doubleTap&&e.push("--double-tap");let t=n.clickButton;t&&"primary"!==t&&e.push("--button",t);return}if("swipe"===t.command){"number"==typeof n.count&&e.push("--count",String(n.count)),"number"==typeof n.pauseMs&&e.push("--pause-ms",String(n.pauseMs)),("one-way"===n.pattern||"ping-pong"===n.pattern)&&e.push("--pattern",n.pattern);return}eR(t.command)&&"number"==typeof n.delayMs&&e.push("--delay-ms",String(n.delayMs))}function eC(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",e_(t.metroHost,eO)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",e_(t.bundleUrl,eO)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",e_(t.launchUrl,eO)))}function eU(e,t){let n=[],a={},r=eS(e)?ex:"swipe"===e?eA:eR(e)?eM:void 0;for(let i=0;i<t.length;i+=1){let s=t[i];if(eS(e)&&"--double-tap"===s){a.doubleTap=!0;continue}let o=t[i+1];if(eS(e)&&"--button"===s&&void 0!==o){("primary"===o||"secondary"===o||"middle"===o)&&(a.clickButton=o),i+=1;continue}let l=r?.get(s);if(l&&void 0!==o){let e=e$(o);if(null!==e){a[l]=e,i+=1;continue}}if("swipe"===e&&"--pattern"===s&&void 0!==o){("one-way"===o||"ping-pong"===o)&&(a.pattern=o),i+=1;continue}n.push(s)}return{positionals:n,flags:a}}function eL(e){let t=[],n={};for(let a=0;a<e.length;a+=1){let r=e[a],i=e[a+1];if("--platform"===r&&void 0!==i){("ios"===i||"android"===i)&&(n.platform=i),a+=1;continue}if("--metro-host"===r&&void 0!==i){n.metroHost=i,a+=1;continue}if("--metro-port"===r&&void 0!==i){let e=e$(i);null!==e&&(n.metroPort=e),a+=1;continue}if("--bundle-url"===r&&void 0!==i){n.bundleUrl=i,a+=1;continue}if("--launch-url"===r&&void 0!==i){n.launchUrl=i,a+=1;continue}t.push(r)}return{positionals:t,flags:n}}function e$(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function eB(e){var t;let n=[],a={};for(let t of e){if("--relaunch"===t){a.relaunch=!0;continue}n.push(t)}let r=eL(n);return{positionals:r.positionals,flags:a,runtime:(t=r.flags).platform||t.metroHost||void 0!==t.metroPort||t.bundleUrl||t.launchUrl?r.flags:void 0}}function eq(e,t={}){let n=[e.command];if("snapshot"===e.command)e.flags?.snapshotInteractiveOnly&&n.push("-i"),"number"==typeof e.flags?.snapshotDepth&&n.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&n.push("-s",eP(e.flags.snapshotScope)),e.flags?.snapshotRaw&&n.push("--raw");else if("open"===e.command){for(let t of e.positionals??[])n.push(eP(t));e.flags?.relaunch&&n.push("--relaunch"),eC(n,e.runtime)}else if("runtime"===e.command)!function(e,t,n={}){let a=t.positionals??[];for(let t of n.includeAllPositionals?a:a.slice(0,1))e.push(e_(t,eO));eC(e,t.flags)}(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals});else if("record"===e.command)!function(e,t){let[n,...a]=t.positionals??[];for(let t of(n&&e.push(e_(n,eO)),a))e.push(eP(t));"number"==typeof t.flags?.fps&&e.push("--fps",String(t.flags.fps)),"number"==typeof t.flags?.screenshotMaxSize&&e.push("--max-size",String(t.flags.screenshotMaxSize)),("number"==typeof t.flags?.quality||"string"==typeof t.flags?.quality)&&e.push("--quality",String(t.flags.quality)),t.flags?.hideTouches&&e.push("--hide-touches")}(n,e);else if("screenshot"===e.command){for(let t of e.positionals??[])n.push(eP(t));m(n,e.flags)}else{for(let t of e.positionals??[])n.push(eP(t));eT(n,e)}return n.join(" ")}function eG(t,n){let a=e.createHash("sha256").update(t).digest(),r=e.createHash("sha256").update(n).digest();return e.timingSafeEqual(a,r)}let eX=["status","get","dismiss","enter","return"];function eY(e){return eX.includes(e)}function eF(e){let t=e?.trim().split(/\s+/,1)[0];if(!t||!t.startsWith("@")||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}class eK extends Error{}let ej=null,eH=!1,eV=!1,ez=0,eW=new Map;function eJ(e){eH=!0,eV||(eV=!0,P({level:"warn",phase:"png_worker_unavailable",data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function eZ(e){let t=eW.get(e.id);t&&(eW.delete(e.id),e1(),e.ok?t.resolve(e.result):t.reject(new D(_(e.error.code),e.error.message,e.error.details)))}function eQ(e,t){ej===e&&(eJ(t.message),ej=null,e.terminate().catch(()=>{}),e0(new eK(`PNG worker failed: ${t.message}`)))}function e0(e){let t=[...eW.values()];for(let n of(eW.clear(),t))n.reject(e)}function e1(){ej&&(eW.size>0?ej.ref():ej.unref())}function e2(){if(eH)return null;if(ej)return ej;let e=function(e,n){try{let r=i(e),s=a.extname(r)||".js";return[a.join(a.dirname(r),`${n}${s}`),a.join(a.dirname(r),"internal",`${n}${s}`)].find(e=>t.existsSync(e))??null}catch{return null}}(import.meta.url,"png-worker");if(!e)return eJ("worker entry module not found next to the current module"),null;try{let t=new r(e,{execArgv:e.endsWith(".ts")?["--experimental-strip-types"]:[]});return t.on("message",eZ),t.on("error",e=>{eQ(t,e)}),t.on("exit",e=>{eQ(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),ej=t,t}catch(e){return eJ(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}async function e4(e,t){try{return await function(e){let t=e2();if(!t)return Promise.reject(new eK("PNG worker is unavailable"));let n=ez+=1;return new Promise((a,r)=>{eW.set(n,{resolve:a,reject:r}),e1();try{t.postMessage({...e,id:n})}catch(e){eW.delete(n),e1(),r(new eK(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}(e)}catch(e){if(e instanceof eK)return t();throw e}}function e3(){e2()}async function e5(){let e=ej;ej=null,e0(new eK("PNG worker terminated")),e&&await e.terminate()}async function e8(e,t){let n=await e4({kind:"decode",png:e,label:t},()=>{let n=C(e,t);return{kind:"decode",width:n.width,height:n.height,data:n.data}});return new E({width:n.width,height:n.height,data:T(n.data)})}async function e6(e){return T((await e4({kind:"encode",width:e.width,height:e.height,data:e.data},()=>({kind:"encode",png:E.sync.write(e)}))).png)}async function e7(e){let{kind:t,...n}=await e4({kind:"diff-pixels",...e},()=>({kind:"diff-pixels",...O(e)}));return{...n,diffData:T(n.diffData)}}let e9=[0,187,255,255];function te(e,t,n,a){if(t<0||t>=e.width||n<0||n>=e.height)return;let r=(n*e.width+t)*4;e.data[r]=a[0],e.data[r+1]=a[1],e.data[r+2]=a[2],e.data[r+3]=a[3]}function tt(e,t,n){return Math.min(Math.max(e,t),n)}let tn=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function ta(e){let{mask:t,width:n,height:a,hooks:r}=e,i=new Uint8Array(t.length),s=new Int32Array(t.length),o=[];for(let e=0;e<t.length;e+=1){var l,d;if(!tr(t,i,e))continue;let u=0,c=(l=s,i[d=e]=1,l[0]=d,1),p=r.create(e);for(;u<c;){let e=s[u];u+=1,r.visit(p,e),c=function(e){let{mask:t,visited:n,queue:a,width:r,height:i,pixelIndex:s}=e,o=s%r,l=Math.floor(s/r),d=e.queueEnd;for(let e of tn){var u,c,p,h;let s=o+e.x,f=l+e.y;if(u=s,c=f,p=r,h=i,!(u>=0)||!(u<p)||!(c>=0)||!(c<h))continue;let m=f*r+s;tr(t,n,m)&&(d=function(e,t,n,a){return t[a]=1,e[n]=a,n+1}(a,n,d,m))}return d}({mask:t,visited:i,queue:s,queueEnd:c,width:n,height:a,pixelIndex:e})}o.push(p)}return o}function tr(e,t,n){return 1===e[n]&&1!==t[n]}let ti={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},ts={leading:20,trailing:20,separator:10,unknown:0,background:-30};function to(e){return"background"!==e.likelyKind}function tl(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function td(e,t){let n,a=0;for(let r of t){let t=tf(e,r.rect);t<=a||(a=t,n=r)}return n}function tu(e){let t=[];for(let n of[...e].sort((e,t)=>e.rect.y-t.rect.y)){let e=t.find(e=>{var t,a;return t=e.rect,tf(t,a=n.rect)>0||Math.abs(B(t).y-B(a).y)<=.5*Math.max(t.height,a.height)});if(!e){t.push({rect:n.rect,blocks:[n]});continue}e.blocks.push(n),e.blocks.sort((e,t)=>e.rect.x-t.rect.x),e.rect=$([e.rect,n.rect])}return t}function tc(e,t){let n,a=B(e);for(let e of t){let t=Math.sqrt(X(a,B(e.rect)));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tp(e){let t=th(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function th(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tf(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}async function tm(e){if(await Y("tesseract"))try{let[t,n]=await Promise.all([tg(e.baselinePath),tg(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tw(t.stdout,e.width,e.height),r=tw(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tA(i.text),s=function(e,t,n,a){let r=null,i=1/0;for(let s=0;s<n.length;s+=1){if(a.has(s))continue;let o=n[s];if(tA(o.text)!==t)continue;let l=B(e.normalizedRect),d=X(l,B(o.normalizedRect));d>=i||(r=s,i=d)}return r}(i,e,t,n);if(null===s)continue;n.add(s);let o=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},a=tI(t.rect.width/e.rect.width),r=tI(t.rect.height/e.rect.height),i=Math.abs(a-1)>=.08||Math.abs(r-1)>=.12;return{text:e.text,baselineRect:e.rect,currentRect:t.rect,delta:n,confidence:Math.round(100*Math.min(e.confidence,t.confidence))/100,possibleTextMetricMismatch:i}}(i,t[s]);r=o,(Math.abs(r.delta.x)>=2||Math.abs(r.delta.y)>=2||Math.abs(r.delta.width)>=2||Math.abs(r.delta.height)>=2||r.possibleTextMetricMismatch)&&a.push(o)}return a.sort((e,t)=>tb(t)-tb(e)).slice(0,12)}(a,r),s=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-tM(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(ty).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tk(t)-tk(e)).slice(0,4)}(i);if(0===a.length&&0===r.length)return;return{provider:"tesseract",baselineBlocks:a.length,currentBlocks:r.length,baselineBlocksRaw:a,currentBlocksRaw:r,matches:i,...s.length>0?{movementClusters:s}:{}}}catch{return}}function tw(e,t,n){let[a,...r]=e.split(/\r?\n/);if(!a)return[];let i=new Map(a.split(" ").map((e,t)=>[e,t])),s=[];for(let e of r){var o;if(!e.trim())continue;let t=e.split(" "),n=tx(t,i,"level"),a=tv(t,i,"text").trim(),r=tx(t,i,"conf");if(5!==n||(o=a,!/[\p{L}\p{N}]/u.test(o))||r<0)continue;let l=tx(t,i,"left"),d=tx(t,i,"top"),u=tx(t,i,"width"),c=tx(t,i,"height");u<=0||c<=0||s.push({key:[tv(t,i,"page_num"),tv(t,i,"block_num"),tv(t,i,"par_num"),tv(t,i,"line_num")].join(":"),text:a,confidence:r,rect:{x:l,y:d,width:u,height:c}})}let l=new Map;for(let e of s){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],a=[];for(let e of t){let t=a.at(-1);if(!t){a.push(e);continue}if(e.rect.x-(t.rect.x+t.rect.width)>Math.max(48,2.5*Math.max(t.rect.height,e.rect.height))){n.push(a),a=[e];continue}a.push(e)}return a.length>0&&n.push(a),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let a=[...e].sort((e,t)=>e.rect.x-t.rect.x),r=$(a.map(e=>e.rect)),i=Math.round(100*tM(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:G({x:tS(r.x/t),y:tS(r.y/n),width:tS(r.width/t),height:tS(r.height/n)})}})(e,t,n)).filter(e=>null!==e)}function tg(e){return F("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tb(e){return Math.abs(e.delta.x)+Math.abs(e.delta.y)+Math.abs(e.delta.width)+Math.abs(e.delta.height)+25*!!e.possibleTextMetricMismatch}function ty(e){let t=e.map(e=>e.delta.x),n=e.map(e=>e.delta.y);return{texts:e.map(e=>e.text),xRange:{min:Math.min(...t),max:Math.max(...t)},yRange:{min:Math.min(...n),max:Math.max(...n)}}}function tk(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tv(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tx(e,t,n){let a=Number(tv(e,t,n));return Number.isFinite(a)?a:0}function tA(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tM(e){return e.reduce((e,t)=>e+t,0)/e.length}function tS(e){return Math.round(100*e*100)/100}function tI(e){return Math.round(1e3*e)/1e3}function tR(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tP(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tN(e){return`#${t_(e.r)}${t_(e.g)}${t_(e.b)}`}function t_(e){return e.toString(16).padStart(2,"0")}function tD(e){return Math.round(100*e*100)/100}let tO=255*Math.sqrt(3);async function tE(e,t,r={}){var i,s,o,l,d;let u,c,p,h;await tT(e,"Baseline image not found"),await tT(t,"Current screenshot not found");let f=r.outputPath,[m,w]=await Promise.all([n.readFile(e),n.readFile(t)]),[g,b]=await Promise.all([e8(m,"baseline screenshot"),e8(w,"current screenshot")]);tC(g.width,g.height,"baseline screenshot",r.maxPixels),tC(b.width,b.height,"current screenshot",r.maxPixels);let y=r.threshold??.1;if(g.width!==b.width||g.height!==b.height){let e=g.width*g.height;return await tU(r.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:g.width,height:g.height},actual:{width:b.width,height:b.height}}}}let k=g.width*g.height,{diffData:v,diffMask:x,differentPixels:A}=await e7({width:g.width,height:g.height,baselineData:g.data,currentData:b.data,maxColorDistance:y*tO}),M=A>0?(s=(u=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n;return ta({mask:t,width:r,height:i,hooks:{create:e=>{var t,n;let a,i;return a=(t=e)%(n=r),{minX:a,minY:i=Math.floor(t/n),maxX:a,maxY:i,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}},visit:(e,t)=>{var i,s,o,l,d;let u,c,p;return i=e,s=t,o=r,l=n,d=a,u=s%o,c=Math.floor(s/o),p=4*s,void(i.minX=Math.min(i.minX,u),i.minY=Math.min(i.minY,c),i.maxX=Math.max(i.maxX,u),i.maxY=Math.max(i.maxY,c),i.differentPixels+=1,i.baselineRed+=l.data[p],i.baselineGreen+=l.data[p+1],i.baselineBlue+=l.data[p+2],i.currentRed+=d.data[p],i.currentGreen+=d.data[p+1],i.currentBlue+=d.data[p+2])}}})}(i={diffMask:x,baseline:g,current:b,totalPixels:k,differentPixels:A,maxRegions:r.maxRegions})).length<=2e3?function(e){let t=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return 0!==n?n:e.minX-t.minX})){var n,a;let e=t.find(e=>{var t,n,a;return t=e,n=r,a=12,t.minX-a<=n.maxX&&n.minX-a<=t.maxX&&t.minY-a<=n.maxY&&n.minY-a<=t.maxY});if(!e){t.push({...r});continue}n=e,a=r,n.minX=Math.min(n.minX,a.minX),n.minY=Math.min(n.minY,a.minY),n.maxX=Math.max(n.maxX,a.maxX),n.maxY=Math.max(n.maxY,a.maxY),n.differentPixels+=a.differentPixels,n.baselineRed+=a.baselineRed,n.baselineGreen+=a.baselineGreen,n.baselineBlue+=a.baselineBlue,n.currentRed+=a.currentRed,n.currentGreen+=a.currentGreen,n.currentBlue+=a.currentBlue}return t}(u):u,s.flatMap(e=>{var t,n,a;let r;return(t=e,n=i.baseline.width,a=i.baseline.height,r=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*a))&&r>=.35*n)?function(e,t,n){var a;let r=function(e,t){let n=[],a=null;for(let r=0;r<e.length;r+=1){if(e[r]<=t){a??=r;continue}null!==a&&(r-a>=6&&n.push([a,r-1]),a=null)}return null!==a&&e.length-a>=6&&n.push([a,e.length-1]),n}((a=function(e,t,n){let a=[];for(let r=e.minY;r<=e.maxY;r+=1){let i=0;for(let a=e.minX;a<=e.maxX;a+=1)1===t[r*n+a]&&(i+=1);a.push(i)}return a}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,r=0,i=Math.max(0,t-3),s=Math.min(a.length-1,t+3);for(let e=i;e<=s;e+=1)n+=a[e],r+=1;return Math.round(n/r)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),i=function(e,t,n){let a=[],r=e.minY;for(let[i,s]of t){let t=e.minY+Math.round((i+s)/2);t-r+1<n||e.maxY-t<n||(a.push([r,t]),r=t+1)}return a.push([r,e.maxY]),a}(e,r,n);if(i.length<=1)return[e];let s=i.map(([n,a])=>(function(e,t,n,a){let r=null;for(let o=t;o<=n;o+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,s;let e=o*a.baseline.width+t;1===a.diffMask[e]&&function(e,t,n,a,r,i){let s=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,a),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,a),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}(r??={minX:i=t,minY:s=o,maxX:i,maxY:s,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,o,a.baseline,a.current)}return r})(e,n,a,t)).filter(e=>null!==e);return s.length>1?s:[e]}(e,i,Math.max(24,Math.round(.03*i.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,i.maxRegions??8)).map((e,t)=>{var n,a,r,s,o,l,d,u,c,p,h;let f,m,w,g,b,y,k,v,x,A,M,S,I,R,P,N,_;return n=e,a=t+1,r={width:i.baseline.width,height:i.baseline.height,totalPixels:i.totalPixels,differentPixels:i.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},k={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tR(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),x=tR(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),A=y.width*y.height,M=tD(n.differentPixels/A),S=Math.round(tP(v)),I=Math.round(tP(x)),R=(s=y,o=r.width,l=r.height,s.width>=.55*o&&s.height>=.12*l?"large-area":s.width>=2.5*s.height?"horizontal-band":s.height>=2.5*s.width?"vertical-band":"compact"),P=(f=A/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",N=(d=v,u=x,m=tP(d),Math.abs(w=tP(u)-m)>=12?w>0?"brighter":"darker":Math.max(Math.abs(u.r-d.r),Math.abs(u.g-d.g),Math.abs(u.b-d.b))>=12?"color-shift":"mixed"),_=(c=k,p=r.width,h=r.height,g=c.x<p/3?"left":c.x>2*p/3?"right":"center",b=c.y<h/3?"top":c.y>2*h/3?"bottom":"middle","center"===g&&"middle"===b?"center":`${b}-${g}`),{index:a,rect:y,normalizedRect:G({x:tD(y.x/r.width),y:tD(y.y/r.height),width:tD(y.width/r.width),height:tD(y.height/r.height)}),differentPixels:n.differentPixels,shareOfDiffPercentage:tD(n.differentPixels/r.differentPixels),densityPercentage:M,shape:R,size:P,location:_,averageBaselineColorHex:tN(v),averageCurrentColorHex:tN(x),baselineLuminance:S,currentLuminance:I,dominantChange:N}}):[];if(A>0&&f){let e=new E({width:g.width,height:g.height,data:v});for(let t of M)t.rect.width<4||t.rect.height<4||function(e,t){let n=tt(t.x,0,e.width-1),a=tt(t.y,0,e.height-1),r=tt(t.x+t.width-1,0,e.width-1),i=tt(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let s=n;s<=r;s+=1)te(e,s,a+t,e9),te(e,s,i-t,e9);for(let s=a;s<=i;s+=1)te(e,n+t,s,e9),te(e,r-t,s,e9)}}(e,t.rect);await n.mkdir(a.dirname(f),{recursive:!0}),await n.writeFile(f,await e6(e))}else await tU(r.outputPath);let S=A>0?await tm({baselinePath:e,currentPath:t,width:g.width,height:g.height}):void 0,I=S&&(S.matches.length>0||(S.movementClusters?.length??0)>0)?{provider:S.provider,baselineBlocks:S.baselineBlocks,currentBlocks:S.currentBlocks,matches:S.matches,...S.movementClusters?{movementClusters:S.movementClusters}:{}}:void 0,R=A>0&&S?(c=function(e){let t=[];for(let n of e.sort((e,t)=>e.minY-t.minY||e.minX-t.minX)){let e=t.find(e=>{var t,a,r;return t=e,a=n,r=10,t.minX-r<=a.maxX&&a.minX-r<=t.maxX&&t.minY-r<=a.maxY&&a.minY-r<=t.maxY});if(!e){t.push({...n});continue}e.minX=Math.min(e.minX,n.minX),e.minY=Math.min(e.minY,n.minY),e.maxX=Math.max(e.maxX,n.maxX),e.maxY=Math.max(e.maxY,n.maxY),e.differentPixels+=n.differentPixels}return t}((l=function(e,t,n,a){let r=new Uint8Array(e);if(!a)return r;for(let e of[...a.baselineBlocksRaw,...a.currentBlocksRaw])!function(e,t,n,a){let r=q(Math.floor(a.x),0,t-1),i=q(Math.floor(a.y),0,n-1),s=q(Math.ceil(a.x+a.width),0,t),o=q(Math.ceil(a.y+a.height),0,n);for(let n=i;n<o;n+=1)for(let a=r;a<s;a+=1)e[n*t+a]=0}(r,t,n,U(e.rect,8));return r}((o={diffMask:x,width:g.width,height:g.height,regions:M,ocr:S}).diffMask,o.width,o.height,o.ocr),d=o.width,ta({mask:l,width:d,height:o.height,hooks:{create:e=>{var t,n;let a,r;return a=(t=e)%(n=d),{minX:a,minY:r=Math.floor(t/n),maxX:a,maxY:r,differentPixels:0}},visit:(e,t)=>{var n,a,r;let i,s;return n=e,i=(a=t)%(r=d),s=Math.floor(a/r),void(n.minX=Math.min(n.minX,i),n.minY=Math.min(n.minY,s),n.maxX=Math.max(n.maxX,i),n.maxY=Math.max(n.maxY,s),n.differentPixels+=1)}}}))),p=tu(o.ocr?.currentBlocksRaw??[]),h=tu(o.ocr?.baselineBlocksRaw??[]),c.filter(tp).map(e=>{var t,n,a,r,i,s,l,d,u,c,f;let m,w,g,b,y,k,v,x,A,M;return t=e,n=o,a=p,r=h,b=function(e,t){let n,a=0;for(let r of t){let t=L(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(g=th(t),n.regions),y=function(e,t,n){let a=td(e,t);if(a)return tc(e,a.blocks);let r=td(e,n);return r?tc(e,r.blocks):void 0}(g,a,r),k=function(e,t,n){if(e.height<=3&&e.width>=.12*n)return"separator";if(!t)return e.width>=.4*n?"background":"unknown";if(e.width>=.4*n)return"background";let a=e.x+e.width/2,r=t.x+t.width/2;return a<r-t.width/2?"leading":a>r+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(g,y?.block.rect,n.width),v=(i=g,s=k,l=t.differentPixels,d=n,m=i.width/i.height,w=l/(i.width*i.height),"separator"===s?"separator":"background"===s?"background":"trailing"===s&&m>=1.5&&m<=3.8&&w>=.35?"toggle":"trailing"===s&&i.width<=.06*d.width&&i.height<=.04*d.height?"chevron":"leading"===s&&m>=.55&&m<=1.8?"icon":tl(i,d)?"background":"visual"),x={...b?{regionIndex:b}:{},slot:k,likelyKind:v,rect:g},{...b?{regionIndex:b}:{},slot:k,likelyKind:v,rect:g,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(u=x,c=t.differentPixels,f=n,A=tl(u.rect,f)?-35:0,M=20*!!u.regionIndex,ti[u.likelyKind]+ts[u.slot]+M+A+Math.min(20,c/200))}}).filter(e=>e.rect.y>=.08*o.height).filter(to).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,o.maxDeltas??12)).map((e,t)=>{var n;return n=e,{index:t+1,...n.regionIndex?{regionIndex:n.regionIndex}:{},slot:n.slot,likelyKind:n.likelyKind,rect:n.rect,...n.nearestText?{nearestText:n.nearestText}:{}}})):[],P=k>0?Math.round(A/k*1e4)/100:0;return{...A>0&&f?{diffPath:f}:{},...M.length>0?{regions:M}:{},...I?{ocr:I}:{},...R.length>0?{nonTextDeltas:R}:{},totalPixels:k,differentPixels:A,mismatchPercentage:P,match:0===A}}async function tT(e,t){try{await n.access(e)}catch{throw new D("INVALID_ARGS",`${t}: ${e}`)}}function tC(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new D("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function tU(e){if(e)try{await n.unlink(e)}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tL(e){return e.width*e.height}function t$(e){return Math.round(100*e*100)/100}async function tB(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new D("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw N(e)}}async function tq(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new D("INVALID_ARGS","Local output paths are not allowed by command policy");try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??"client-visible",requestedClientPath:t?.kind==="downloadableArtifact"?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw N(e)}}async function tG(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw N(e)}}let tX=async(e,t)=>{let n,a,r;if(!t.baseline)throw new D("INVALID_ARGS","diff screenshot requires a baseline image");let i=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new D("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),s=t.current??{kind:"live"};if(t.overlayRefs&&!tz(s))throw new D("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let o=await tB(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=tz(s)?(a=await tY(e,t)).path:(n=await tB(e,s,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await tq(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tE(o.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});tz(s)&&(u=await tF(e,t,r?.path,u,l));let c=u.diffPath?await r?.publish():void 0;return c&&l.push(c),u.diffPath||await r?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await r?.cleanup?.(),e}finally{await o.cleanup?.(),await n?.cleanup?.(),await a?.cleanup?.()}};async function tY(e,t){let n=await tG(e,{prefix:"agent-device-diff-current",ext:".png"});try{await tK(e,t,n.path,tj(t))}catch(e){throw await n.cleanup(),e}return n}async function tF(e,t,n,a,r){var i,s,o,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await tV(n),a;let d=(i=t,s=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:tH(s??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:tH(i.out.clientPath)}:{},...i.out.fileName?{fileName:tH(i.out.fileName)}:{}}:void 0),u=await tq(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await tK(e,t,u.path,{overlayRefs:!0,...tj(t)}),i=await u.publish();return i&&r.push(i),{...a,currentOverlayPath:n.path??u.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...a.regions&&n.overlayRefs?{regions:(o=a.regions,l=n.overlayRefs,o.map(e=>{var t,n;let a,r=(t=e,n=l,a=tL(t.rect),n.map(e=>{let n=e.overlayRect,r=L(t.rect,n);return r<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:n,overlayCoveragePercentage:t$(r/tL(n)),regionCoveragePercentage:t$(r/a)}}).filter(e=>null!==e).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return 0!==n?n:t.overlayCoveragePercentage-e.overlayCoveragePercentage}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage})));return r.length>0?{...e,currentOverlayMatches:r}:e}))}:{}}}catch(e){throw await u.cleanup?.(),e}}async function tK(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new D("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,a)??{}}function tj(e){return e.surface?{surface:e.surface}:{}}function tH(e){let t=a.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function tV(e){try{await n.unlink(tH(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tz(e){return"live"===e.kind}async function tW(e,t){if(!Number.isInteger(t)||t<1)throw new D("INVALID_ARGS","Screenshot max size must be a positive integer");let a=await e8(await n.readFile(e),"screenshot"),r=Math.max(a.width,a.height);if(r<=t)return;let i=t/r,s=Math.max(1,Math.round(a.width*i)),o=Math.max(1,Math.round(a.height*i)),l=function(e,t,n){let a=new E({width:t,height:n});for(let r=0;r<n;r+=1){let i=r*e.height/n,s=(r+1)*e.height/n;for(let n=0;n<t;n+=1){let o=n*e.width/t,l=(n+1)*e.width/t,d=0,u=0,c=0,p=0,h=0;for(let t=Math.floor(i);t<Math.ceil(s);t+=1){let n=Math.min(t+1,s)-Math.max(t,i);for(let a=Math.floor(o);a<Math.ceil(l);a+=1){let r=n*(Math.min(a+1,l)-Math.max(a,o)),i=(t*e.width+a)*4;d+=(e.data[i]??0)*r,u+=(e.data[i+1]??0)*r,c+=(e.data[i+2]??0)*r,p+=(e.data[i+3]??0)*r,h+=r}}let f=(r*a.width+n)*4;a.data[f]=Math.round(d/h),a.data[f+1]=Math.round(u/h),a.data[f+2]=Math.round(c/h),a.data[f+3]=Math.round(p/h)}}return a}(a,s,o);await n.writeFile(e,await e6(l))}let tJ=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new D("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await tq(e,t.out,{field:"path",ext:".png"});try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},a.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,stabilize:t.stabilize,surface:t.surface}),void 0!==t.maxSize&&await tW(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...w(`Saved screenshot: ${a.path}`)}};function tZ(e,t){let n=j(e.type??"Element"),a=H(e,n),r=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",s=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,a,r,i,s].join("|")}function tQ(e,t){return t.flatten?e.map(e=>({text:K(e,0,!1),comparable:tZ(e,0)})):V(e).map(e=>({text:e.text,comparable:tZ(e.node,e.depth)}))}function t0(e,t){return e.get(t)??0}function t1(e){return e.map(e=>({index:e.index,depth:e.depth,parentIndex:e.parentIndex,type:e.type,role:e.role,subrole:e.subrole,label:e.label,value:e.value,identifier:e.identifier,enabled:e.enabled,selected:e.selected,focused:e.focused,hittable:e.hittable,rect:e.rect,bundleId:e.bundleId,appName:e.appName,windowTitle:e.windowTitle,surface:e.surface,hiddenContentAbove:e.hiddenContentAbove,hiddenContentBelow:e.hiddenContentBelow,interactionBlocked:e.interactionBlocked,presentationHints:e.presentationHints}))}let t2=async(e,t)=>{var n;let a,r,i=await t3(e,t),s=function(e){var t,n,a,r,i;let{previous:s,current:o,options:l,identity:d}=e;if(!0===l.forceFull||!0===l.raw||!s||!1===s.comparisonSafe||!1===o.comparisonSafe||(t=s,n=o,a=d,t.backend&&n.backend&&t.backend!==n.backend||a?.previousAppBundleId&&a.currentAppBundleId&&a.previousAppBundleId!==a.currentAppBundleId)||!s.presentationKey||s.presentationKey!==o.presentationKey||(r=s,i=o,r.truncated!==i.truncated||JSON.stringify(t1(r.nodes))!==JSON.stringify(t1(i.nodes))))return;let u=l.scope?.trim();return{ageMs:Math.max(0,o.createdAt-s.createdAt),nodeCount:o.nodes.length,...!0===l.interactiveOnly?{interactiveOnly:!0}:{},...u?{scope:u}:{}}}({previous:i.session?.snapshot,current:i.snapshot,options:t,identity:{previousAppBundleId:i.session?.appBundleId,currentAppBundleId:i.result.appBundleId??i.session?.appBundleId}});return await e.sessions.set(t5(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){let{nodes:t,backend:n,snapshotRaw:a}=e;if(a||!Z(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let r=o(t),i=new Set;return r.hiddenCount>0&&i.add("offscreen-nodes"),r.nodes.some(e=>e.hiddenContentAbove)&&i.add("scroll-hidden-above"),r.nodes.some(e=>e.hiddenContentBelow)&&i.add("scroll-hidden-below"),{partial:i.size>0,visibleNodeCount:r.nodes.length,totalNodeCount:t.length,reasons:[...i]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...p({...i.annotations,warnings:i.warnings}),...s?{unchanged:s}:{},...i.result.snapshotDiagnostics?{snapshotDiagnostics:i.result.snapshotDiagnostics}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},t4=async(e,t)=>{let n=await t3(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=t5(t.session,n);if(!r){let t=function(e,t={}){return tQ(e,t).length}(n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let s=function(e,t,n={}){let a=function(e,t){let n=e.length,a=t.length,r=n+a,i=new Map,s=[];i.set(1,0);for(let o=0;o<=r;o+=1){s.push(new Map(i));for(let r=-o;r<=o;r+=2){let l=r===-o||r!==o&&t0(i,r-1)<t0(i,r+1)?t0(i,r+1):t0(i,r-1)+1,d=l-r;for(;l<n&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(r,l),l>=n&&d>=a)return function(e,t,n,a,r){let i=[],s=a,o=r;for(let a=e.length-1;a>=0;a-=1){let r=e[a],l=s-o,d=l===-a||l!==a&&t0(r,l-1)<t0(r,l+1)?l+1:l-1,u=t0(r,d),c=u-d;for(;s>u&&o>c;)i.push({kind:"unchanged",text:n[o-1].text}),s-=1,o-=1;if(0===a)break;s===u?(i.push({kind:"added",text:n[c].text}),o=c):(i.push({kind:"removed",text:t[u].text}),s=u)}return i.reverse(),i}(s,e,t,n,a)}}return[]}(tQ(e,n),tQ(t,n)),r={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(r.additions+=1),"removed"===e.kind&&(r.removals+=1),"unchanged"===e.kind&&(r.unchanged+=1);return{summary:r,lines:a}}(r.nodes,n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!1,summary:s.summary,lines:s.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function t3(e,t){var n,a,r,i,s,o,l;let u,c,p,h,f;if(!e.backend.captureSnapshot)throw new D("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let m=t.session??"default",w=await e.sessions.get(m),g=await e.backend.captureSnapshot({session:m,requestId:t.requestId,appId:w?.appId,appBundleId:w?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,depth:t.depth,scope:t.scope,raw:t.raw}),b=(a=g,r=e,n=a.snapshot?a.snapshot:{nodes:a.nodes??[],truncated:a.truncated,backend:a.backend,createdAt:d(r)},n.presentationKey?n:{...n,presentationKey:J(t)}),y=A(g),k=d(e);return{snapshot:b,result:g,session:w,annotations:y,warnings:(u=[...(i={result:g,annotations:y,snapshot:b,options:t,session:w,capturedAt:b.createdAt??k,runtimeNow:k}).annotations.warnings??[]],i.annotations.quality&&u.push(...R(i.annotations.quality,i.snapshot.nodes)),u.push(...function(e){let t=e.annotations.analysis;if("android"!==e.snapshot.backend||!0!==e.options.interactiveOnly||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return"number"==typeof e.options.depth&&"number"==typeof t.maxDepth&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}(i)),i.annotations.quality||(u.push(...function(e){if("xctest"!==e.snapshot.backend||!0!==e.options.interactiveOnly||1!==e.snapshot.nodes.length)return[];let t=e.snapshot.nodes[0];return t?.type!=="Application"?[]:["iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known."]}(i)),u.push(...(c=new Set((s=i.snapshot.nodes).map(e=>e.parentIndex).filter(e=>void 0!==e)),s.filter(e=>!(c.has(e.index)||(e.type?.toLowerCase()??"").includes("text"))&&(e.label??"").split(", ").length>10).map(e=>{let t=(e.label??"").split(", ").length,n=e.identifier?` (${e.identifier})`:"";return`@${e.ref} [${e.type??"element"}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})))),(p=function(e){if(e?.backend!=="uiautomator-dump")return;let t=e.fallbackReason?` Reason: ${e.fallbackReason}`:"";return`Android snapshot helper unavailable; using stock UIAutomator dump, which can time out on busy React Native UIs.${t}`}(i.annotations.androidSnapshot))&&u.push(p),(h=S(i.snapshot.nodes))&&u.push(h),(f=function(e){var t,n,a,r,i,s;let o=e.session?.snapshot;if(!e.annotations.freshness&&o&&(t=o,n=e.snapshot,void 0===t.presentationKey||void 0===n.presentationKey||t.presentationKey===n.presentationKey)&&(a=o,r=e.capturedAt,[r,e.runtimeNow].some(e=>{let t=e-a.createdAt;return t>=0&&t<=2e3}))&&(i=o.nodes.length,s=e.snapshot.nodes.length,!(i<12)&&s<=Math.floor(.2*i)))return t8}(i))&&u.push(f),u.push(...(o=i.annotations.freshness,l=i.snapshot.backend,o?.staleAfterRetries&&"android"===l?"stuck-route"===o.reason?[`Recent ${o.action} was followed by a nearly identical snapshot after ${o.retryCount} automatic retr${1===o.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`]:"sharp-drop"===o.reason?[t8]:[]:[])),Array.from(new Set(u)))}}function t5(e,t){let n=t.session?.name??e??"default";return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}let t8="Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.",t6=async(e,t)=>await nt(e,t,"press"),t7=async(e,t)=>await nt(e,t,"click"),t9=async(e,t)=>{var n;if(!t.text)throw new D("INVALID_ARGS","fill requires text");let a=await nr(e,t);if(a)return a;let r=await v(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new D("UNSUPPORTED_OPERATION","fill is not supported by this backend");let i=nn(r),s=b(await e.backend.fill(x(e,t),i,t.text,{delayMs:t.delayMs})),o="node"in r?r.node?.type??"":"",l=o&&!eh(o,e.backend.platform)?`fill target ${n=r,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${o}", attempting fill anyway.`:void 0;return{...r,text:t.text,...l?{warning:l}:{},...s?{backendResult:s}:{}}},ne=async(e,t)=>{let n=t.text;if(!n)throw new D("INVALID_ARGS","type requires text");let a=eF(n);if(a)throw new D("INVALID_ARGS",`type does not accept a target ref like "${a}"`,{hint:`Use fill ${a} "text" to target that field, or press ${a} then type "text" to append.`});if(!e.backend.typeText)throw new D("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=M(t.delayMs??0,"delay-ms",0,1e4),i=b(await e.backend.typeText(x(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...w(`Typed ${Array.from(n).length} chars`)}};async function nt(e,t,n){let a=await na(e,t,n);if(a)return a;let r=await v(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new D("UNSUPPORTED_OPERATION","tap is not supported by this backend");let i=nn(r),s=b(await e.backend.tap(x(e,t),i,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...r,...s?{backendResult:s}:{}}}function nn(e){if(!e.point)throw new D("COMMAND_FAILED","Interaction target resolved without coordinates");return e.point}async function na(e,t,n){var a;if("click"!==n||"ref"!==t.target.kind||!e.backend.tapTarget||void 0!==(a=t).count||void 0!==a.intervalMs||void 0!==a.holdMs||void 0!==a.jitterPx||void 0!==a.doubleTap||void 0!==a.button&&"primary"!==a.button)return null;let r=b(await e.backend.tapTarget(x(e,t),{kind:"ref",ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}}));return{kind:"ref",target:{kind:"ref",ref:t.target.ref},...r?{backendResult:r}:{}}}async function nr(e,t){if("ref"!==t.target.kind||!e.backend.fillTarget)return null;let n=b(await e.backend.fillTarget(x(e,t),{kind:"ref",ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}},t.text,{delayMs:t.delayMs}));return{kind:"ref",target:{kind:"ref",ref:t.target.ref},text:t.text,...n?{backendResult:n}:{}}}function ni(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function ns(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,s=Q(n),o=er(n,i),l=!0===n.selected,d="text"===t?en(n):function(e,t,n){var a,r,i;let s;if("android"===n&&!1===e.visibleToUser)return!1;if(no(e.rect))return function(e,t){return u(e,t)}(e,t);if(e.rect)return!1;if("android"!==n&&!0===e.hittable)return!0;let o=(a=e,r=t,i=n,s=ea(r),ee(r,a,s,e=>!function(e,t){if("android"===t&&!1===e.visibleToUser)return!1;let n=ep(e.type??"");return!(n.includes("application")||n.includes("window")||n.includes("scrollview")||n.includes("tableview")||n.includes("collectionview"))&&"table"!==n&&"list"!==n&&"listview"!==n&&("android"===t?!0===e.hittable&&no(e.rect):!0===e.hittable||no(e.rect))}(e,i)?null:e));return!!o&&(no(o.rect)?function(e,t){return u(e,t)}(o,t):"android"!==n&&!0===o.hittable)}(n,a,i),c=!1;switch(t){case"visible":c=d;break;case"hidden":c=!d;break;case"editable":c=o;break;case"selected":c=l;break;case"text":c=s===(r??"")}let p="text"===t?`expected="${r??""}" actual="${s}"`:`actual=${JSON.stringify({visible:d,editable:o,selected:l})}`;return{pass:c,actualText:s,details:p}}function no(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function nl(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new D("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new D("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function nd(e,t,n={updateSession:!0}){let a=e.backend.captureSnapshot;if(!a)throw new D("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",i=await e.sessions.get(r),s=await a(x(e,t),{interactiveOnly:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw,includeRects:n.includeRects}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,...s.quality?{snapshotQuality:s.quality}:{},createdAt:d(e)};return n.updateSession&&i&&!l(o.snapshotQuality)&&await e.sessions.set({...i,snapshot:o}),{sessionName:r,session:i,snapshot:o}}async function nu(e,t,n){if(e.backend.readText){let a=await e.backend.readText(x(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return eu(n)}let nc=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new D("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nk(e,t,n);let{capture:a,match:r}=await nv(e,t,n);if(!r)throw new D("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let i=`@${r.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:i,node:r}:{kind:"text",ref:i,text:await nu(e,a,r),node:r}},np=async(e,t)=>{if("ref"===t.target.kind){let n=await nl(e,t.session),a=function(e,t,n){let a=z(t);if(!a)throw new D("INVALID_ARGS",n.invalidRefMessage);let r=W(e,a)??(n.fallbackLabel.length>0?el(e,n.fallbackLabel):null);if(!r)throw new D("COMMAND_FAILED",n.notFoundMessage);return{ref:a,node:r}}(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??"",invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${t.target.ref} not found`}),r=es(a.node,e.backend.platform,{action:"get"}),i={kind:"ref",ref:`@${a.ref}`};return"attrs"===t.property?{kind:"attrs",target:i,node:a.node,selectorChain:r}:{kind:"text",target:i,text:await nu(e,n,a.node),node:a.node,selectorChain:r}}let n=await nS(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=es(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:a};let r=await nu(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},nh=async(e,t)=>{let n=await np(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new D("COMMAND_FAILED","getText returned non-text result");return n},nf=async(e,t)=>{let n=await np(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new D("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nm=async(e,t)=>{var n;if(!ni(t.predicate))throw new D("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new D("INVALID_ARGS","is text requires expected text value");let a="visible"===(n=t.predicate)||"hidden"===n,r=await nd(e,t,{updateSession:!0,includeRects:a}),i=et(t.selector);if("exists"===t.predicate){let n=ei(r.snapshot.nodes,i,{platform:e.backend.platform});if(!n)throw new D("COMMAND_FAILED",ec(i,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:n.selector.raw,matches:n.matches,selectorChain:i.selectors.map(e=>e.raw)}}let s=eo(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!s)throw new D("COMMAND_FAILED",ec(i,[],{unique:!0}),{command:"is",reason:"selector_not_found",predicate:t.predicate,selector:i.raw});let o=ns({predicate:t.predicate,node:s.node,nodes:r.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!o.pass)throw new D("COMMAND_FAILED",`is ${t.predicate} failed for selector ${s.selector.raw}: ${o.details}`,{command:"is",reason:"predicate_failed",predicate:t.predicate,selector:s.selector.raw,predicateDetails:o.details});return{predicate:t.predicate,pass:!0,selector:s.selector.raw,..."text"===t.predicate?{text:o.actualText}:{},selectorChain:i.selectors.map(e=>e.raw)}},nw=async(e,t)=>await nm(e,{...t,predicate:"visible",selector:t.target.selector}),ng=async(e,t)=>await nm(e,{...t,predicate:"hidden",selector:t.target.selector}),nb=async(e,t)=>{if("sleep"===t.target.kind)return await c(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await nl(e,t.session),a=z(t.target.ref);if(!a)throw new D("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=W(n.snapshot.nodes,a),i=r?ed(r,n.snapshot.nodes):void 0;if(!i)throw new D("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await nA(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nx(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new D("INVALID_ARGS","wait requires text");return await nA(e,t,t.target.text,t.target.timeoutMs)},ny=async(e,t)=>{let n=await nb(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new D("COMMAND_FAILED","waitForText returned non-text result");return n};async function nk(e,t,n){let a=t.timeoutMs??1e4,r=d(e);for(;d(e)-r<a;){let{match:a}=await nv(e,t,n);if(a)return{kind:"found",found:!0,waitedMs:d(e)-r};await c(e,300)}throw new D("COMMAND_FAILED","find wait timed out")}async function nv(e,t,n){let a=await nd(e,t,{updateSession:!0,scope:"text"===n||"label"===n||"any"===n?t.query:void 0});if(l(a.snapshot.snapshotQuality))throw new D("COMMAND_FAILED","find could not read the current accessibility tree",{reason:a.snapshot.snapshotQuality.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen."});let r=ef(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];return{capture:a,match:r}}async function nx(e,t,n,a){let r=a??1e4,i=d(e),s=et(n);for(;d(e)-i<r;){let n=ei((await nd(e,t,{updateSession:!0})).snapshot.nodes,s,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:d(e)-i};await c(e,300)}throw new D("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nA(e,t,n,a){let r=a??1e4,i=d(e);for(;d(e)-i<r;){if(e.backend.findText?(await e.backend.findText(x(e,t),n)).found:await nM(e,t,n))return{kind:"text",text:n,waitedMs:d(e)-i};await c(e,300)}throw new D("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nM(e,t,n){return!!el((await nd(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nS(e,t,n,a){let r=await nd(e,{...t,session:n},{updateSession:!0}),i=et(a.selector),s=eo(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!s)throw new D("COMMAND_FAILED",ec(i,[],{unique:!0}));return{capture:r,node:s.node,selector:s.selector.raw,ref:`@${s.node.ref}`}}function nI(e,t){if(void 0!==e)return nR(e,t)}function nR(e,t){let n=e?.trim();if(!n)throw new D("INVALID_ARGS",`${t} must be a non-empty string`);return n}let nP=async(e,t={})=>{if(!e.backend.listDevices)throw new D("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(x(e,t),t.filter)}},nN=async(e,t={})=>{if(!e.backend.bootDevice)throw new D("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=n$(t.target),a=b(await e.backend.bootDevice(x(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...w("Booted device")}},n_=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new D("UNSUPPORTED_OPERATION","admin.shutdown is not supported by this backend");let n=n$(t.target),a=b(await e.backend.shutdownDevice(x(e,t),n));return{kind:"deviceShutdown",...n?{target:n}:{},...a?{backendResult:a}:{},...w("Shutdown device")}},nD=async(e,t)=>await nT(e,t,"install"),nO=async(e,t)=>await nT(e,t,"reinstall"),nE=async(e,t)=>await nT(e,t,"installFromSource");async function nT(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new D("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?nR(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new D("INVALID_ARGS",`admin.${n} requires app`);let s=x(e,t),o=await nC(e,s,t.source);try{var l,d,u,c,p;let t,a,h,f,m,g,y,k,v=await r.call(e.backend,s,{...i?{app:i}:{},source:o.source});return l=n,d=i,u=o.source,c=v,t=b(c),a=nB(c,"appName"),h=nB(c,"appId"),f=nB(c,"bundleId"),m=nB(c,"packageName"),g=nB(c,"launchTarget"),y=nB(c,"installablePath"),k=nB(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...h?{appId:h}:{},...a?{appName:a}:{},...f?{bundleId:f}:{},...m?{packageName:m}:{},...g?{launchTarget:g}:{},...y?{installablePath:y}:{},...k?{archivePath:k}:{},...t?{backendResult:t}:{},...w(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??g??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await o.cleanup?.()}}async function nC(e,t,n){let a=nL(n),r=await nU(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nL(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function nU(e,t){if("url"===t.kind)return{source:t};let n=await tB(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nL(e){if(!e||"object"!=typeof e)throw new D("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nR(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nR(e.id,"source.id")};if("url"===e.kind){let t=nR(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new D("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new D("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new D("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function n$(e){if(!e)return;let t=nI(e.id,"target.id"),n=nI(e.name,"target.name"),a={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...void 0!==e.headless?{headless:e.headless}:{}};return Object.keys(a).length>0?a:void 0}function nB(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}let nq=/^[A-Za-z0-9_.:-]{1,64}$/,nG=async(e,t)=>{var n;if(!e.backend.openApp)throw new D("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=nI(e.app,"app"),a=nI(e.appId,"appId"),r=nI(e.bundleId,"bundleId"),i=nI(e.packageName,"packageName"),s=nI(e.url,"url"),o=nI(e.activity,"activity"),l={...n?{app:n}:{},...a?{appId:a}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...s?{url:s}:{},...o?{activity:o}:{}};if(!((t=l).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new D("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=b(await e.backend.openApp(nz(e,t),a,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...w(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},nX=async(e,t={})=>{if(!e.backend.closeApp)throw new D("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nI(t.app,"app"),a=b(await e.backend.closeApp(nz(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...w(n?`Closed: ${n}`:"Closed app")}},nY=async(e,t={})=>{if(!e.backend.listApps)throw new D("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nz(e,t),ey(t.filter))}},nF=async(e,t)=>{if(!e.backend.getAppState)throw new D("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nR(t.app,"app"),a=await e.backend.getAppState(nz(e,t),n);return{kind:"appState",app:n,state:a}},nK=async(e,t)=>{if(!e.backend.pushFile)throw new D("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nR(t.app,"app"),a=await nH(e,t.input);try{let r=await e.backend.pushFile(nz(e,t),a.backendInput,n),i=b(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...w(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},nj=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new D("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nR(e,"name");if(!nq.test(t))throw new D("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,a=`apps.triggerEvent payload for "${r}"`,void 0!==n&&nV(n,a,8192);let i=b(await e.backend.triggerAppEvent(nz(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...w(`Triggered app event: ${r}`)}};async function nH(e,t){if(!t||"object"!=typeof t)throw new D("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nV(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await tB(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nV(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new D("INVALID_ARGS",`${t} must be a JSON object`)}(e,t),Buffer.byteLength(function(e,t){try{let n=JSON.stringify(e);if("string"!=typeof n)throw new D("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new D("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new D("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nz(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}let nW=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,nJ=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function nZ(e){var t,n;let a=!1,r=e;return{value:(t=r=(r=(r=(r=(r=r.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(a=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,r)=>(a=!0,`${String(t)}[REDACTED]${String(r)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(nJ,()=>(a=!0,"[REDACTED]")),n=()=>{a=!0},r=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=nQ(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function nQ(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))nW.test(n)&&(e.searchParams.set(n,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",n=!0),{value:t.toString(),redacted:n}}catch{return}}let n0=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function n1(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(n0.test(a))n[a]="[REDACTED]",t=!0;else{let e=n5(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function n2(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=n3(t,nZ);return n8(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??n5(e,2048)}function n4(e){return n3(e,e=>n5(e,2048))}function n3(e,t){if(void 0===e)return{redacted:!1};if("string"==typeof e)return t(e);if(!e||"object"!=typeof e)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let a=n3(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(n0.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=n3(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function n5(e,t){if(void 0===e)return{redacted:!1};let n=nZ(e);return n8(n.value,t,n.redacted)}function n8(e,t,n){if(void 0===e)return{redacted:n};let a=e;return a.length>t&&(a=`${a.slice(0,t)}...[truncated]`,n=!0),{value:a,redacted:n}}let n6=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new D("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await ae(e,t),{...at(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:aa(a.levels,"levels")}:{},...void 0!==a.search?{search:nR(a.search,"search")}:{},...void 0!==a.source?{source:nR(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=n5(e.message,4096),n=n4(e.metadata);return r||=t.redacted||n.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:t.value??"",...e.source?{source:e.source}:{},...n.value?{metadata:n.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}},n7=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new D("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let s={...at(r=t,25,200,"network limit"),include:function(e){if(void 0===e)return"summary";if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new D("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await ae(e,t),s),a=s.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?nQ(t=e.url)??n5(t,2048):void 0,r="headers"===a||"all"===a?n1(e.requestHeaders):void 0,s="headers"===a||"all"===a?n1(e.responseHeaders):void 0,o="body"===a||"all"===a?n2(e.requestBody):void 0,l="body"===a||"all"===a?n2(e.responseBody):void 0,d=n4(e.metadata);return i||=(n?.redacted??!1)||(r?.redacted??!1)||(s?.redacted??!1)||(o?.redacted??!1)||(l?.redacted??!1)||d.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...n?{url:n.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...r?.value?{requestHeaders:r.value}:{},...s?.value?{responseHeaders:s.value}:{},...o?.value!==void 0?{requestBody:o.value}:{},...l?.value!==void 0?{responseBody:l.value}:{},...d.value?{metadata:d.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:i,...n.notes?{notes:n.notes}:{}}},n9=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new D("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await ae(e,t),{...an(a=t),...void 0!==a.sampleMs?{sampleMs:M(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:aa(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=n5(e.message,4096),n=n4(e.metadata);return r||=t.redacted||n.redacted,{name:e.name,...void 0!==e.value?{value:e.value}:{},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...void 0!==t.value?{message:t.value}:{},...n.value?{metadata:n.value}:{}}}),...n.startedAt?{startedAt:n.startedAt}:{},...n.endedAt?{endedAt:n.endedAt}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}};async function ae(e,t){let n=x(e,t),a=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??a?.appId?{appId:t.appId??a?.appId}:{},...t.appBundleId??a?.appBundleId?{appBundleId:t.appBundleId??a?.appBundleId}:{}}}function at(e,t,n,a){return{...an(e),...void 0!==e.cursor?{cursor:nR(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:M(e.limit,a,1,n)}}function an(e){return{...void 0!==e.since?{since:nR(e.since,"since")}:{},...void 0!==e.until?{until:nR(e.until,"until")}:{}}}function aa(e,t,n=50){if(!Array.isArray(e))throw new D("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new D("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>nR(e,`${t}[${n}]`))}let ar=async(e,t)=>{let n=as(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new D("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await tq(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,s,o,l,d,u,c;let p,h,f,m,w=(i=t,s=r?.path,p={},s&&(p.outPath=s),h=(o=i.fps,void 0===o?void 0:M(o,"fps",1,60)),void 0!==h&&(p.fps=h),f=(l=i.maxSize,void 0===l?void 0:M(l,"maxSize",1,Number.MAX_SAFE_INTEGER)),void 0!==f&&(p.maxSize=f),m=function(e){if(void 0===e)return;let t=k(e);if(void 0===t)throw new D("INVALID_ARGS","quality must be one of: medium, high (legacy numeric values 5-10 are accepted)");return t}(i.quality),void 0!==m&&(p.quality=m),void 0!==i.hideTouches&&(p.showTouches=!0!==i.hideTouches),p),g=await a.call(e.backend,x(e,t),w),b=await r?.publish();return d=n,u=g,c=b,{..."string"==typeof u.path?{path:u.path}:{},..."string"==typeof u.telemetryPath?{telemetryPath:u.telemetryPath}:{},..."string"==typeof u.warning?{warning:u.warning}:{},...ao(d,u,c,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},ai=async(e,t)=>{let n=as(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new D("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await tq(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var i,s,o;let l={...r?.path?{outPath:r.path}:{}},d=await a.call(e.backend,x(e,t),l),u=await r?.publish();return i=n,s=d,o=u,{..."string"==typeof s.outPath?{outPath:s.outPath}:{},...ao(i,s,o,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}};function as(e,t){if("start"===e||"stop"===e)return e;throw new D("INVALID_ARGS",`${t} action must be start or stop`)}function ao(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...w("start"===e?a.startMessage:a.stopMessage)}}let al=async(e,t={})=>{if(!e.backend.pressBack)throw new D("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new D("INVALID_ARGS","system.back mode must be in-app or system");let a=b(await e.backend.pressBack(x(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...w("Back")}},ad=async(e,t={})=>{if(!e.backend.pressHome)throw new D("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=b(await e.backend.pressHome(x(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...w("Home")}},au=async(e,t)=>{if(!e.backend.rotate)throw new D("UNSUPPORTED_OPERATION","system.rotate is not supported by this backend");let n=function(e){switch(e){case"portrait":case"portrait-upside-down":case"landscape-left":case"landscape-right":return e;default:throw new D("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=b(await e.backend.rotate(x(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...w(`Rotated to ${n}`)}},ac=async(e,t={})=>{var n,a,r,i,s,o,l;if(!e.backend.setKeyboard)throw new D("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let d=t.action??"status";if(!eY(d))throw new D("INVALID_ARGS","system.keyboard action must be status, get, dismiss, enter, or return");let u=await e.backend.setKeyboard(x(e,t),{action:d}),c=b(u),p=(n=u)&&"object"==typeof n?u:{};return"enter"===d||"return"===d?{kind:"keyboardEnterPressed",action:"enter",state:p,...(a=c)?{backendResult:a}:{},...w("Keyboard enter pressed")}:"dismiss"===d?(r=d,{kind:"keyboardDismissed",action:r,state:i=p,...(s=c)?{backendResult:s}:{},...w(!1===i.dismissed?"Keyboard already hidden":"Keyboard dismissed")}):(o=d,{kind:"keyboardState",action:o,state:p,...(l=c)?{backendResult:l}:{}})},ap=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new D("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(x(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new D("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new D("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new D("INVALID_ARGS","system.clipboard write requires text");let n=b(await e.backend.setClipboard(x(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...w("Clipboard updated")}},ah=async(e,t={})=>{if(!e.backend.openSettings)throw new D("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=nI(t.target,"target"),a=b(await e.backend.openSettings(x(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...w(n?`Opened settings: ${n}`:"Opened settings")}},af=async(e,t={})=>{var n,a;if(!e.backend.handleAlert)throw new D("UNSUPPORTED_OPERATION","system.alert is not supported by this backend");let r=t.action??"get";if("get"!==r&&"accept"!==r&&"dismiss"!==r&&"wait"!==r)throw new D("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let i=void 0===t.timeoutMs?void 0:M(t.timeoutMs,"timeoutMs",0,12e4),s=await e.backend.handleAlert(x(e,t),r,{timeoutMs:i});return n=r,a=s,"get"===n?function(e){if("alertStatus"!==e.kind)throw new D("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:"get",alert:e.alert}}(a):"wait"===n?function(e){if("alertWait"!==e.kind)throw new D("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:"wait",alert:e.alert,...void 0!==e.waitedMs?{waitedMs:e.waitedMs}:{},...void 0!==e.timedOut?{timedOut:e.timedOut}:{},...w(e.alert?"Alert visible":"Alert wait timed out")}}(a):function(e,t){if("alertHandled"!==t.kind)throw new D("COMMAND_FAILED",`system.alert ${e} returned an invalid backend result`);return{kind:"alertHandled",action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...w(t.handled?`Alert ${e}ed`:"No alert handled")}}(n,a)},am=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new D("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=b(await e.backend.openAppSwitcher(x(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...w("Opened app switcher")}};function aw(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,ag(e)]));return{get:e=>ag(t.get(e)),set:e=>{t.set(e.name,ag(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>ag(e))}}(),policy:e.policy??function(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,capture:{screenshot:e=>tJ(t,e),diffScreenshot:e=>tX(t,e),snapshot:e=>t2(t,e),diffSnapshot:e=>t4(t,e)},selectors:{find:e=>nc(t,e),get:e=>np(t,e),getText:(e,n={})=>nh(t,{...n,target:e}),getAttrs:(e,n={})=>nf(t,{...n,target:e}),is:e=>nm(t,e),isVisible:(e,n={})=>nw(t,{...n,target:e}),isHidden:(e,n={})=>ng(t,{...n,target:e}),wait:e=>nb(t,e),waitForText:(e,n={})=>ny(t,{...n,text:e})},interactions:{click:(e,n={})=>t7(t,{...n,target:e}),press:(e,n={})=>t6(t,{...n,target:e}),fill:(e,n,a={})=>t9(t,{...a,target:e,text:n}),typeText:(e,n={})=>ne(t,{...n,text:e}),focus:(e,n={})=>g(t,{...n,target:e}),longPress:(e,n={})=>f(t,{...n,target:e}),swipe:e=>y(t,e),scroll:e=>h(t,e),pinch:e=>I(t,e)},system:{back:e=>al(t,e),home:e=>ad(t,e),rotate:e=>au(t,e),keyboard:e=>ac(t,e),clipboard:e=>ap(t,e),settings:e=>ah(t,e),alert:e=>af(t,e),appSwitcher:e=>am(t,e)},apps:{open:e=>nG(t,e),close:e=>nX(t,e),list:(e={})=>nY(t,{...e,filter:eb(e.filter)}),state:e=>nF(t,e),push:e=>nK(t,e),triggerEvent:e=>nj(t,e)},admin:{devices:e=>nP(t,e),boot:e=>nN(t,e),shutdown:e=>n_(t,e),install:e=>nD(t,e),reinstall:e=>nO(t,e),installFromSource:e=>nE(t,e)},recording:{record:e=>ar(t,e),trace:e=>ai(t,e)},observability:{logs:e=>n6(t,e),network:e=>n7(t,e),perf:e=>n9(t,e)}}}function ag(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function ab(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}async function ay(e){let{lockDirPath:n,owner:r}=e,i=a.join(n,"owner.json"),s=Date.now()+(e.timeoutMs??3e4),o=e.pollMs??100,l=e.ownerGraceMs??5e3,d=e.description??"process lock";for(t.mkdirSync(a.dirname(n),{recursive:!0});Date.now()<s;)try{t.mkdirSync(n),function(e,n){let a=`${e}.${process.pid}.${Date.now()}.tmp`;t.writeFileSync(a,JSON.stringify(n),"utf8"),t.renameSync(a,e)}(i,r);let e=!1;return async()=>{e||(e=!0,t.rmSync(n,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,n,a){let r=null;try{r=t.statSync(e)}catch{return!0}let i=ak(n);if(i){var s;return!(Number.isInteger((s=i).pid)&&!(s.pid<=0)&&em(s.pid)&&(!s.startTime||ew(s.pid)===s.startTime))&&(t.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-r.mtimeMs<a)&&(t.rmSync(e,{recursive:!0,force:!0}),!0)}(n,i,l))continue;await eg(o)}throw new D("COMMAND_FAILED",`Timed out waiting for ${d}`,{lockDirPath:n,...function(e,n){let a,r=Date.now(),i=ak(n);try{a=Math.max(0,Math.round(r-t.statSync(e).mtimeMs))}catch{}return{...void 0!==a?{lockAgeMs:a}:{},...i?{ownerPid:i.pid,ownerStartTime:i.startTime,ownerAgeMs:Math.max(0,Math.round(r-i.acquiredAtMs))}:{}}}(n,i)})}function ak(e){try{return JSON.parse(t.readFileSync(e,"utf8"))}catch{return null}}let av="0.27.1",ax="agent-browser";async function aA(e){let t=aI(e);if(t.installed){var n=t;if(!n.installed)throw a_(n);return{command:n.binaryPath,env:aN(n,process.env)}}throw a_(t)}async function aM(e){let n=aI(e);var r,i=n.nodeMajor;if(!(i>=24))throw new D("UNSUPPORTED_OPERATION","Web automation requires Node 24 or newer.",{currentNode:process.version,requiredNodeMajor:24,hint:"Run agent-device with Node 24+ for web setup and web automation."});let s=await ay({lockDirPath:a.join(n.installDir,"..",".agent-browser-install.lock"),owner:{pid:process.pid,startTime:ew(process.pid),acquiredAtMs:Date.now()},timeoutMs:3e5,description:"managed agent-browser setup"});try{let n=aI(e);if(n.installed)return n;return t.mkdirSync(n.installDir,{recursive:!0}),await aR(n),await aP(n,["install"],{timeoutMs:3e5}),await aP(n,["doctor","--offline","--quick"],{timeoutMs:6e4}),r=n,t.writeFileSync(a.join(r.installDir,"manifest.json"),JSON.stringify({package:ax,version:av,node:process.version,installedAt:new Date().toISOString()},null,2),"utf8"),aI(e)}finally{await s()}}async function aS(e){let t=aI(e);if(!t.installed)throw a_(t);let n=await aP(t,["doctor","--offline","--quick"],{timeoutMs:6e4,allowFailure:!0});return{status:t,...n}}function aI(n){var r,i,o;let l,d,u=n.stateDir??process.env.AGENT_DEVICE_STATE_DIR??a.join(process.env.HOME??process.cwd(),".agent-device"),c=a.join(u,"tools","agent-browser",av),p=(r=c,l=a.join(r,"package"),a.join(l,"node_modules",".bin","win32"===process.platform?"agent-browser.cmd":"agent-browser")),h=a.join(c,"home"),f=function(t){if("win32"===process.platform)return a.join(t,"home");let n=e.createHash("sha1").update(t).digest("hex").slice(0,12);return a.join(s.tmpdir(),"agent-device-web",n)}(c),m=(i=c,d=e.createHash("sha1").update(i).digest("hex").slice(0,12),a.join(s.tmpdir(),"adw",d)),w=function(e){try{return t.accessSync(e,t.constants.X_OK),!0}catch{return!1}}(p)&&(o=c,t.existsSync(a.join(o,"manifest.json"))),g=Number.parseInt(process.versions.node.split(".")[0]??"0",10);return{version:av,stateDir:u,installDir:c,binaryPath:p,homeDir:h,runtimeHomeDir:f,socketDir:m,installed:w,nodeMajor:g,nodeSupported:g>=24}}async function aR(e){let n=a.join(e.installDir,"package");t.mkdirSync(n,{recursive:!0}),await F("npm",["install","--prefix",n,"--no-audit","--no-fund","--no-save",`${ax}@${av}`],{env:process.env,timeoutMs:3e5})}async function aP(e,t,n){return await F(e.binaryPath,t,{allowFailure:n.allowFailure,env:aN(e,process.env),timeoutMs:n.timeoutMs})}function aN(e,n){return t.mkdirSync(e.homeDir,{recursive:!0}),function(e){if(e.runtimeHomeDir!==e.homeDir){t.mkdirSync(a.dirname(e.runtimeHomeDir),{recursive:!0});try{let n=t.lstatSync(e.runtimeHomeDir);if(n.isSymbolicLink()&&t.readlinkSync(e.runtimeHomeDir)===e.homeDir||n.isDirectory())return;n.isSymbolicLink()&&t.unlinkSync(e.runtimeHomeDir)}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}try{t.symlinkSync(e.homeDir,e.runtimeHomeDir,"dir")}catch{t.mkdirSync(e.runtimeHomeDir,{recursive:!0})}}}(e),t.mkdirSync(e.socketDir,{recursive:!0}),{...n,HOME:e.runtimeHomeDir,AGENT_BROWSER_SOCKET_DIR:e.socketDir}}function a_(e){return new D("TOOL_MISSING","Managed web browser backend is not installed.",{version:av,installDir:e.installDir,hint:!1===e.nodeSupported?`Web automation requires Node 24+; current Node is ${process.version}.`:"Run `agent-device web setup` to install the managed web backend."})}function aD(e){let t=N(e);return"TOOL_MISSING"!==t.code?t:new D(t.code,t.message,{...t.details??{},hint:"string"==typeof t.details?.hint?t.details.hint:"Run `agent-device web setup` to install the managed web backend."})}export{ay as acquireProcessLock,eT as appendScriptSeriesFlags,aw as createAgentDevice,e8 as decodePngAsync,aS as doctorManagedAgentBrowser,e6 as encodePngAsync,ns as evaluateIsPredicate,eF as findMistargetedTypeRefToken,eq as formatPortableActionLine,eE as formatScriptActionSummary,eP as formatScriptArg,eN as formatScriptStringLiteral,eS as isClickLikeCommand,eY as isKeyboardAction,ni as isSupportedPredicate,eI as isTouchTargetCommand,ab as localCommandPolicy,aD as mapManagedAgentBrowserError,eB as parseReplayOpenFlags,eL as parseReplayRuntimeFlags,eU as parseReplaySeriesFlags,e3 as prewarmPngWorker,aA as resolveAgentBrowserTool,aM as setupManagedAgentBrowser,e5 as terminatePngWorker,eG as timingSafeStringEqual};
package/dist/src/4428.js CHANGED
@@ -1,3 +1,3 @@
1
- import e from"node:fs";import{parseAllDocuments as t,stringify as n}from"yaml";import{AppError as r}from"./733.js";import{recordingQualityInputToExportQuality as i,readScreenshotScriptFlag as o,MAESTRO_COMPAT_TRACKER_URL as s,MAESTRO_NEW_ISSUE_URL as l}from"./9873.js";import{formatScriptStringLiteral as a,parseReplayOpenFlags as u,formatPortableActionLine as f,parseReplaySeriesFlags as c,parseReplayRuntimeFlags as p,isClickLikeCommand as h}from"./368.js";let d=/^[A-Z_][A-Z0-9_]*$/,m=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,g="AD_VAR_";function A(e){return e.startsWith("AD_")}function v(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(A(e))throw v(e);t[e]=r}return{values:t}}function w(e,t){Object.assign(e.values,t)}function b(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(g))continue;let e=n.slice(g.length);0!==e.length&&d.test(e)&&(A(e)||(t[e]=r))}return t}function I(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!d.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(A(i))throw v(i);t[i]=n.slice(e+1)}return t}function $(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function S(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function _(e,t,n){return e.replace(m,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function N(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>_(e,t,n)),flags:R(e.flags,t,n)??{},runtime:R(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:_(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function R(e,t,n){return e?function e(t,n,r){return"string"==typeof t?_(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let D=new Set(["ios","android","macos","linux"]),M=new Set(["mobile","tv","desktop"]);function x(e){let t=[],n=[],s=e.split(/\r?\n/),l=!1;for(let[e,a]of s.entries()){let s=a.trim();if(0===s.length||s.startsWith("#"))continue;if(L(s)){if(l)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let f=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...s]=function(e){let t=[],n=0;for(;n<e.length&&!((n=function(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}(e,n))>=e.length);){let i='"'===e[n]?function(e,t){let n=!1,i=t+1;for(;i<e.length;i+=1){let t=e.charAt(i);if('"'===t&&!n)break;if(n){n=!1;continue}n="\\"===t}if(i>=e.length)throw new r("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,i+1)),nextCursor:i+1}}(e,n):function(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}(e,n);t.push(i.value),n=i.nextCursor}return t}(t);if(void 0===n||"context"===n)return null;let l={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){l.positionals=[];for(let e=0;e<s.length;e+=1){let t=s[e];if("-i"===t){l.flags.snapshotInteractiveOnly=!0;continue}if("-c"!==t){if("--raw"===t){l.flags.snapshotRaw=!0;continue}if("--force-full"===t){l.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<s.length){let t=Number(s[e+1]);Number.isFinite(t)&&t>=0&&(l.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<s.length){l.flags.snapshotScope=s[e+1],e+=1;continue}if("--backend"===t&&e+1<s.length){e+=1;continue}}}return l}if("open"===n){let e=u(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l.runtime=e.runtime,l}if("runtime"===n){let e=p(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l}if(h(n)){let e=c(n,s);Object.assign(l.flags,e.flags);let t=e.positionals[0];if(void 0===t)return l;if(t.startsWith("@"))return l.positionals=[t],e.positionals[1]&&(l.result={refLabel:e.positionals[1]}),l;let r=e.positionals[0],i=e.positionals[1];return V(r)&&V(i)&&e.positionals.length>=2?l.positionals=[r,i]:l.positionals=[e.positionals.join(" ")],l}if("fill"===n){let e=c(n,s);if(Object.assign(l.flags,e.flags),!(e.positionals.length>=2))return l.positionals=e.positionals,l;let[t,r,...i]=e.positionals;return t.startsWith("@")?(i.length>0?(l.positionals=[t,i.join(" ")],l.result={refLabel:r}):l.positionals=[t,r],l):(l.positionals=[t,[r,...i].join(" ")],l)}if("get"===n){let e=s[0],t=s[1];return void 0===e||void 0===t?l.positionals=s:t.startsWith("@")?(l.positionals=[e,t],s[2]&&(l.result={refLabel:s[2]})):l.positionals=[e,s.slice(1).join(" ")],l}if("swipe"===n||"type"===n){let e=c(n,s);return Object.assign(l.flags,e.flags),l.positionals=e.positionals,l}if("record"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t];if("--hide-touches"===n){l.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<s.length){let e=i(s[t+1]);void 0!==e&&(l.flags.quality=e),t+=1;continue}if("--max-size"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.screenshotMaxSize=Math.floor(e)),t+=1;continue}e.push(n)}return l.positionals=e,l}if("screenshot"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t],r=o({args:s,index:t,flags:l.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return l.positionals=e,l}return l.positionals=s,l}(a);f&&(t.push(f),n.push(e+1),l=!0)}return{actions:t,actionLines:n}}function O(e){let t=e.split(/\r?\n/),n={};for(let[e,i]of t.entries()){let t=i.trim();if(0===t.length||t.startsWith("#"))continue;if(L(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!d.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&D.has(e)&&j(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&M.has(e)&&j(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&j(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&j(n,"retries",Math.floor(e))}}return n}function L(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function j(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function V(e){return!!e&&!Number.isNaN(Number(e))}function k(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${a(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(f(e,{runtimeIncludeAllPositionals:!0}));let o=`${i.join("\n")}
1
+ import e from"node:fs";import{parseAllDocuments as t,stringify as n}from"yaml";import{AppError as r}from"./733.js";import{recordingQualityInputToExportQuality as i,readScreenshotScriptFlag as o,MAESTRO_COMPAT_TRACKER_URL as s,MAESTRO_NEW_ISSUE_URL as l}from"./9873.js";import{formatScriptStringLiteral as a,parseReplayOpenFlags as u,formatPortableActionLine as f,parseReplaySeriesFlags as c,parseReplayRuntimeFlags as p,isClickLikeCommand as h}from"./2577.js";let d=/^[A-Z_][A-Z0-9_]*$/,m=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,g="AD_VAR_";function A(e){return e.startsWith("AD_")}function v(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(A(e))throw v(e);t[e]=r}return{values:t}}function w(e,t){Object.assign(e.values,t)}function b(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(g))continue;let e=n.slice(g.length);0!==e.length&&d.test(e)&&(A(e)||(t[e]=r))}return t}function I(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!d.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(A(i))throw v(i);t[i]=n.slice(e+1)}return t}function $(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function S(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function _(e,t,n){return e.replace(m,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function N(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>_(e,t,n)),flags:R(e.flags,t,n)??{},runtime:R(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:_(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function R(e,t,n){return e?function e(t,n,r){return"string"==typeof t?_(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let D=new Set(["ios","android","macos","linux"]),M=new Set(["mobile","tv","desktop"]);function x(e){let t=[],n=[],s=e.split(/\r?\n/),l=!1;for(let[e,a]of s.entries()){let s=a.trim();if(0===s.length||s.startsWith("#"))continue;if(L(s)){if(l)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let f=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...s]=function(e){let t=[],n=0;for(;n<e.length&&!((n=function(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}(e,n))>=e.length);){let i='"'===e[n]?function(e,t){let n=!1,i=t+1;for(;i<e.length;i+=1){let t=e.charAt(i);if('"'===t&&!n)break;if(n){n=!1;continue}n="\\"===t}if(i>=e.length)throw new r("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,i+1)),nextCursor:i+1}}(e,n):function(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}(e,n);t.push(i.value),n=i.nextCursor}return t}(t);if(void 0===n||"context"===n)return null;let l={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){l.positionals=[];for(let e=0;e<s.length;e+=1){let t=s[e];if("-i"===t){l.flags.snapshotInteractiveOnly=!0;continue}if("-c"!==t){if("--raw"===t){l.flags.snapshotRaw=!0;continue}if("--force-full"===t){l.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<s.length){let t=Number(s[e+1]);Number.isFinite(t)&&t>=0&&(l.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<s.length){l.flags.snapshotScope=s[e+1],e+=1;continue}if("--backend"===t&&e+1<s.length){e+=1;continue}}}return l}if("open"===n){let e=u(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l.runtime=e.runtime,l}if("runtime"===n){let e=p(s);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l}if(h(n)){let e=c(n,s);Object.assign(l.flags,e.flags);let t=e.positionals[0];if(void 0===t)return l;if(t.startsWith("@"))return l.positionals=[t],e.positionals[1]&&(l.result={refLabel:e.positionals[1]}),l;let r=e.positionals[0],i=e.positionals[1];return V(r)&&V(i)&&e.positionals.length>=2?l.positionals=[r,i]:l.positionals=[e.positionals.join(" ")],l}if("fill"===n){let e=c(n,s);if(Object.assign(l.flags,e.flags),!(e.positionals.length>=2))return l.positionals=e.positionals,l;let[t,r,...i]=e.positionals;return t.startsWith("@")?(i.length>0?(l.positionals=[t,i.join(" ")],l.result={refLabel:r}):l.positionals=[t,r],l):(l.positionals=[t,[r,...i].join(" ")],l)}if("get"===n){let e=s[0],t=s[1];return void 0===e||void 0===t?l.positionals=s:t.startsWith("@")?(l.positionals=[e,t],s[2]&&(l.result={refLabel:s[2]})):l.positionals=[e,s.slice(1).join(" ")],l}if("swipe"===n||"type"===n){let e=c(n,s);return Object.assign(l.flags,e.flags),l.positionals=e.positionals,l}if("record"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t];if("--hide-touches"===n){l.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<s.length){let e=i(s[t+1]);void 0!==e&&(l.flags.quality=e),t+=1;continue}if("--max-size"===n&&t+1<s.length){let e=Number(s[t+1]);Number.isFinite(e)&&(l.flags.screenshotMaxSize=Math.floor(e)),t+=1;continue}e.push(n)}return l.positionals=e,l}if("screenshot"===n){let e=[];for(let t=0;t<s.length;t+=1){let n=s[t],r=o({args:s,index:t,flags:l.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return l.positionals=e,l}return l.positionals=s,l}(a);f&&(t.push(f),n.push(e+1),l=!0)}return{actions:t,actionLines:n}}function O(e){let t=e.split(/\r?\n/),n={};for(let[e,i]of t.entries()){let t=i.trim();if(0===t.length||t.startsWith("#"))continue;if(L(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!d.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&D.has(e)&&j(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&M.has(e)&&j(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&j(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&j(n,"retries",Math.floor(e))}}return n}function L(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function j(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function V(e){return!!e&&!Number.isNaN(Number(e))}function k(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${a(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(f(e,{runtimeIncludeAllPositionals:!0}));let o=`${i.join("\n")}
2
2
  `,s=`${t}.tmp-${process.pid}-${Date.now()}`;e.writeFileSync(s,o),e.renameSync(s,t)}function E(e){let n=t(e);for(let e of n)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new r("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return n.map(e=>e.toJSON()).filter(e=>null!==e)}function G(e){return`${e.map(e=>n(e).trimEnd()).join("\n---\n")}
3
3
  `}function C(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function P(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw J(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function W(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function F(e){return e.map((e,t)=>{if("string"==typeof e||W(e))return e;throw new r("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function K(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}function z(e,t){if(null==e)return{};if(!W(e))throw new r("INVALID_ARGS",`${t} expects a map.`);let n={};for(let[t,r]of Object.entries(e))("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=String(r));return n}function U(e,t){return W(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function q(e,t){if(e.appId)return e.appId;throw new r("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function Y(e,t){if("string"==typeof t)return t;throw new r("INVALID_ARGS",`${e} expects a string value.`)}function Z(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function H(e){throw J(`Maestro command "${e}" is not supported yet.`)}function J(e){throw new r("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${s}. If this syntax matters for your flows, comment there or open a focused issue at ${l}.`)}function T(e,t){return`${e},${t}`}function B(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw J('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function Q(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:"absolute",x:Number(t[1]),y:Number(t[2])};let n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:"percent",x:Number(n[1]),y:Number(n[2])};throw J('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}export{P as assertOnlyKeys,y as buildReplayVarScope,b as collectReplayShellEnv,T as formatMaestroPoint,W as isPlainRecord,w as mergeReplayVarScopeValues,F as normalizeCommandList,K as normalizePlatform,B as parseAbsolutePoint,Q as parseMaestroPoint,E as parseMaestroYamlDocuments,I as parseReplayCliEnvEntries,x as parseReplayScriptDetailed,z as readEnvMap,$ as readReplayCliEnvEntries,O as readReplayScriptMetadata,S as readReplayShellEnvSource,U as readTimeoutMs,q as requireAppId,Y as requireStringValue,Z as resolveMaestroString,N as resolveReplayAction,G as stringifyMaestroYamlDocuments,C as support_action,H as unsupportedCommand,J as unsupportedMaestroSyntax,k as writeReplayScript};
package/dist/src/8184.js CHANGED
@@ -1 +1 @@
1
- import{setSessionSnapshot as e,captureSnapshot as r,isNavigationSensitiveAction as t,markPendingInteractionOutcome as n,markPostGestureStabilization as o,getSnapshotReferenceFrame as i,recordTouchVisualizationEvent as a,markAndroidSnapshotFreshness as c,stripInternalInteractionFlags as s}from"./9722.js";import{isSparseSnapshotQualityVerdict as d,successText as f}from"./9873.js";import{getAndroidScreenSize as u}from"./input-actions.js";import{emitDiagnostic as l}from"./432.js";async function h(t,n,o,i,a){let c={...n??{},snapshotInteractiveOnly:a.interactiveOnly},s=i(c,t.appBundleId,t.trace?.outPath),{snapshot:f}=await r({device:t.device,session:t,flags:c,outPath:c.out,logPath:s.logPath??"",androidFreshnessMode:a.androidFreshnessMode});return d(f.snapshotQuality)||(e(t,f),o.set(t.name,t)),f}function p(e){var r,t,n;let o,i,a,{data:c,fallbackX:s,fallbackY:d,referenceFrame:u,extra:l}=e,h=(r=l,t=s,n=d,o="string"==typeof r?.ref?r.ref:void 0,i="string"==typeof r?.button?r.button:void 0,a="string"==typeof r?.gesture?r.gesture:void 0,("string"==typeof r?.text?`Filled ${Array.from(r.text).length} chars`:o?"longpress"===a?`Long pressed @${o} (${t}, ${n})`:i&&"primary"!==i?`Clicked ${i} @${o} (${t}, ${n})`:`Tapped @${o} (${t}, ${n})`:void 0)??("string"==typeof c?.message?c.message:void 0));return{x:s,y:d,...u??{},...l??{},...c??{},...f(h)}}function g(e){let{session:r,sessionStore:i,command:d,positionals:f,retryPositionals:u,flags:l,result:h,responseData:p,actionStartedAt:g,actionFinishedAt:_,androidFreshnessBaseline:m}=e,v=s(l);return i.recordAction(r,{command:d,positionals:f,flags:v??{},result:h}),n({session:r,command:d,positionals:u??f,flags:l,preSnapshot:r.snapshot}),t(d)&&c(r,d,m??r.snapshot),o(r,d,u??f,l),a(r,d,f,h,v??{},g,_),{ok:!0,data:p}}async function _(e){let{session:r,flags:t,sessionStore:n,contextFromFlags:o,captureSnapshotForSession:a}=e;if(!r.recording)return;if(r.recording.touchReferenceFrame)return r.recording.touchReferenceFrame;if("android"===r.device.platform){let e=await u(r.device),t={referenceWidth:e.width,referenceHeight:e.height};return r.recording&&(r.recording.touchReferenceFrame=t),t}let c=i(r.snapshot);if(c)return r.recording&&(r.recording.touchReferenceFrame=c),c;if(!r.recording)return;let s=i(await a(r,t,n,o,{interactiveOnly:!0}));return s&&r.recording&&(r.recording.touchReferenceFrame=s),s}async function m(e){try{return await _(e)}catch(r){l({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:r instanceof Error?r.message:String(r)}});return}}function v(e){return i({nodes:e,createdAt:0})}export{p as buildTouchVisualizationResult,g as finalizeTouchInteraction,h as interaction_snapshot_captureSnapshotForSession,v as readSnapshotNodesReferenceFrame,m as resolveDirectTouchReferenceFrameSafely};
1
+ import{setSessionSnapshot as e,captureSnapshot as r,isNavigationSensitiveAction as t,markPendingInteractionOutcome as n,markPostGestureStabilization as o,getSnapshotReferenceFrame as i,recordTouchVisualizationEvent as a,markAndroidSnapshotFreshness as c,stripInternalInteractionFlags as s}from"./9722.js";import{isSparseSnapshotQualityVerdict as d,successText as f}from"./9873.js";import{getAndroidScreenSize as u}from"./input-actions.js";import{emitDiagnostic as l}from"./432.js";async function h(t,n,o,i,a){let c={...n??{},snapshotInteractiveOnly:a.interactiveOnly},s=i(c,t.appBundleId,t.trace?.outPath),{snapshot:f}=await r({device:t.device,session:t,flags:c,outPath:c.out,logPath:s.logPath??"",includeRects:a.includeRects,androidFreshnessMode:a.androidFreshnessMode});return d(f.snapshotQuality)||(e(t,f),o.set(t.name,t)),f}function p(e){var r,t,n;let o,i,a,c,{data:s,fallbackX:d,fallbackY:u,referenceFrame:l,extra:h}=e,p=(r=h,t=d,n=u,o="string"==typeof r?.ref?r.ref:void 0,i="string"==typeof r?.button?r.button:void 0,a="string"==typeof r?.gesture?r.gesture:void 0,c=void 0===t||void 0===n?"":` (${t}, ${n})`,("string"==typeof r?.text?`Filled ${Array.from(r.text).length} chars`:o?"longpress"===a?`Long pressed @${o}${c}`:i&&"primary"!==i?`Clicked ${i} @${o}${c}`:`Tapped @${o}${c}`:void 0)??("string"==typeof s?.message?s.message:void 0));return{...void 0===d||void 0===u?{}:{x:d,y:u},...l??{},...h??{},...s??{},...f(p)}}function g(e){let{session:r,sessionStore:i,command:d,positionals:f,retryPositionals:u,flags:l,result:h,responseData:p,actionStartedAt:g,actionFinishedAt:_,androidFreshnessBaseline:m}=e,v=s(l);return i.recordAction(r,{command:d,positionals:f,flags:v??{},result:h}),n({session:r,command:d,positionals:u??f,flags:l,preSnapshot:r.snapshot}),t(d)&&c(r,d,m??r.snapshot),o(r,d,u??f,l),a(r,d,f,h,v??{},g,_),{ok:!0,data:p}}async function _(e){let{session:r,flags:t,sessionStore:n,contextFromFlags:o,captureSnapshotForSession:a}=e;if(!r.recording)return;if(r.recording.touchReferenceFrame)return r.recording.touchReferenceFrame;if("android"===r.device.platform){let e=await u(r.device),t={referenceWidth:e.width,referenceHeight:e.height};return r.recording&&(r.recording.touchReferenceFrame=t),t}let c=i(r.snapshot);if(c)return r.recording&&(r.recording.touchReferenceFrame=c),c;if(!r.recording)return;let s=i(await a(r,t,n,o,{interactiveOnly:!0}));return s&&r.recording&&(r.recording.touchReferenceFrame=s),s}async function m(e){try{return await _(e)}catch(r){l({level:"warn",phase:"touch_reference_frame_resolve_failed",data:{platform:e.session.device.platform,error:r instanceof Error?r.message:String(r)}});return}}function v(e){return i({nodes:e,createdAt:0})}export{p as buildTouchVisualizationResult,g as finalizeTouchInteraction,h as interaction_snapshot_captureSnapshotForSession,v as readSnapshotNodesReferenceFrame,m as resolveDirectTouchReferenceFrameSafely};
@@ -0,0 +1,4 @@
1
+ import e from"node:crypto";import t from"node:fs";import n from"node:path";import{resolveUserPath as r,expandUserHomePath as o}from"./9612.js";import{readVersion as s,findProjectRoot as i}from"./7244.js";function a(s,u={}){var l,c;let p,f=(l=s,c=u,(p=(l??"").trim())?r(p,{env:c.env}):function(r={}){var s;let a,u,l,c=n.join(o("~",{env:r.env}),".agent-device"),p=r.projectRoot??i();return(s=p,t.existsSync(n.join(s,"package.json"))&&t.existsSync(n.join(s,"src","daemon.ts")))?n.join(c,"dev",(a=function(e){try{return t.realpathSync.native(e)}catch{return n.resolve(e)}}(p),u=n.basename(a).replaceAll(/[^a-zA-Z0-9._-]+/g,"-"),l=e.createHash("sha1").update(a).digest("hex").slice(0,12),`${u||"agent-device"}-${l}`)):c}(c));return{baseDir:f,infoPath:n.join(f,"daemon.json"),lockPath:n.join(f,"daemon.lock"),logPath:n.join(f,"daemon.log"),sessionsDir:n.join(f,"sessions")}}function u(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function l(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function c(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function p(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}let f=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,m=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,d=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function h(){let e=process.argv[1];return e?g(e):"unknown"}function g(r,o=i()){try{let s=n.resolve(o),i=[n.resolve(r)],a=new Set,u=[];for(;i.length>0;){let e=i.pop();if(!e||a.has(e))continue;a.add(e);let r=t.statSync(e);if(!r.isFile())continue;let o=n.relative(s,e)||e;u.push(`${o}:${r.size}:${Math.trunc(r.mtimeMs)}`);let l=t.readFileSync(e,"utf8");for(let t of function(e){let t=new Set;return M(e,f,t),M(e,m,t),[...t]}(l)){let r=function(e,t){let r=n.resolve(n.dirname(e),t),o=v(r);if(o)return o;for(let e of d){let t=v(`${r}${e}`);if(t)return t}for(let e of d){let t=v(n.join(r,`index${e}`));if(t)return t}return null}(e,t);r&&i.push(r)}}let l=u.sort().join("|"),c=e.createHash("sha1").update(l).digest("hex");return`graph:${u.length}:${c}`}catch{return"unknown"}}function M(e,t,n){t.lastIndex=0;let r=null;for(;null!==(r=t.exec(e));){let e=r[1]?.trim();e?.startsWith(".")&&n.add(e)}}function v(e){try{return t.statSync(e).isFile()?e:null}catch{return null}}let y=/^[A-Za-z0-9_@%+=:,./-]+$/;function S(e){return`'${e.replaceAll("'","'\\''")}'`}function j(e){return y.test(e)?e:S(e)}function x(e,t){let n=[],r=e+t.toString(),o=r.indexOf("\n");for(;-1!==o;){let e=r.slice(0,o).trim();r=r.slice(o+1),e&&n.push(e),o=r.indexOf("\n")}return{lines:n,buffer:r}}function $(e){return e.meta?.requestProgress==="replay-test"}function b(e){return!!e&&"object"==typeof e&&"progress"===e.type&&!!e.event}function w(e){return!!e&&"object"==typeof e&&"response"===e.type&&!!e.response}function D(e){return`${JSON.stringify({type:"progress",event:e})}
2
+ `}function k(e){return`${JSON.stringify({type:"response",response:e})}
3
+ `}function P(e){return`${JSON.stringify({type:"response",response:e})}
4
+ `}function _(e,t={}){return{ok:!0,service:e,version:s(),rpcProtocolVersion:1,...void 0!==t.upstream?{upstream:t.upstream}:{}}}function A(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function z(e){let t=e?.snapshotDiagnostics?.samples;if(t&&0!==t.length)return C(t)}function C(e){if(0===e.length)return;let t=R(e);return{stats:t,...t.p95Ms>=1500?{warning:N(t)}:{}}}function O(e){let t=e.flatMap(e=>(function(e){if(!e||e.count<=0)return[];let t=e.platform;return 1===e.count?[{durationMs:e.maxMs,platform:t}]:2===e.count?[{durationMs:e.p50Ms,platform:t},{durationMs:e.maxMs,platform:t}]:[...Array.from({length:e.count-3},()=>({durationMs:e.p50Ms,platform:t})),{durationMs:e.p50Ms,platform:t},{durationMs:e.p95Ms,platform:t},{durationMs:e.maxMs,platform:t}]})(e?.stats));if(0===t.length)return;let n=R(t);return{stats:n,...n.p95Ms>=1500?{warning:N(n)}:{}}}function E(e){if(!e||"object"!=typeof e||Array.isArray(e))return;let t=function(e){let t=H(e);if(!t)return;let n=function(e){let t={count:e.count,p50Ms:e.p50Ms,p95Ms:e.p95Ms,maxMs:e.maxMs,slowThresholdMs:e.slowThresholdMs};if(!Object.values(t).some(e=>"number"!=typeof e))return t}(t);if(n){var r;let e,o,s,i;return{...n,...(o="string"==typeof(r=t).platform?r.platform:void 0,i=(s=H(r.backends))&&(e=Object.entries(s).filter(e=>"number"==typeof e[1])).length>0?Object.fromEntries(e):void 0,{...o?{platform:o}:{},...i?{backends:i}:{}})}}}(e.stats);if(!t)return;let n="string"==typeof e.warning?e.warning:void 0;return{stats:t,...n?{warning:n}:{}}}function R(e){let t,n=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:n.length,p50Ms:T(n,50),p95Ms:T(n,95),maxMs:n[n.length-1]??0,slowThresholdMs:1500,...1===new Set(t=e.map(e=>e.platform).filter(e=>!!e)).size?{platform:t[0]}:{},...function(e){let t={};for(let n of e)n.backend&&(t[n.backend]=(t[n.backend]??0)+1);return Object.keys(t).length>0?{backends:t}:{}}(e)}}function T(e,t){if(0===e.length)return 0;let n=Math.max(0,Math.ceil(t/100*e.length)-1);return e[Math.min(n,e.length-1)]??0}function N(e){let t=e.platform?`${e.platform} `:"";return`Warning: ${t}snapshots are slow in this run: p95 ${e.p95Ms}ms over ${e.count} captures. Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function H(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}export{_ as buildDaemonHealthPayload,g as computeDaemonCodeSignature,x as consumeTextLines,b as isDaemonProgressEnvelope,w as isDaemonResponseEnvelope,O as mergeSnapshotDiagnostics,p as normalizeTenantId,E as readSnapshotDiagnosticsSummary,A as recordSnapshotTiming,h as resolveDaemonCodeSignature,a as resolveDaemonPaths,u as resolveDaemonServerMode,l as resolveDaemonTransportPreference,c as resolveSessionIsolationMode,D as serializeDaemonProgressEnvelope,k as serializeDaemonResponseEnvelope,P as serializeDaemonRpcResponseEnvelope,S as shellQuote,j as shellQuoteIfNeeded,$ as shouldStreamRequestProgress,z as summarizeSnapshotDiagnostics,C as summarizeSnapshotTimingSamples};
package/dist/src/9581.js CHANGED
@@ -1,4 +1,15 @@
1
- import{COMMON_COMMAND_SUPPORTED_FLAG_KEYS as e,managementCliSchemas as t,perfCliSchemas as o,captureCliSchemas as n,observabilityCliSchemas as s,replayCliSchemas as a,interactionCliSchemas as r,recordingCliSchemas as i,METRO_PREPARE_FLAGS as d,batchCliSchemas as c,systemCliSchemas as l,reactNativeCliSchemas as m}from"./9873.js";import{listCommandMetadata as p,debuggingCliSchemas as u,metroCliSchemas as g}from"./2948.js";let f={auth:{usageOverride:"auth status|login|logout",listUsageOverride:"auth",helpDescription:"Manage cloud login state used by remote daemon and cloud device workflows.",summary:"Manage cloud login state used by remote daemon and cloud device workflows",positionalArgs:["status|login|logout"],supportedFlags:["remoteConfig","stateDir"]},connect:{usageOverride:"connect [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]",helpDescription:"Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.",listUsageOverride:"connect",summary:"Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI",allowedFlags:["remoteConfig","daemonBaseUrl","tenant","runId","leaseId","leaseBackend","force","noLogin"],supportedFlags:["stateDir","daemonAuthToken","session","platform",...d,"launchUrl"]},connection:{usageOverride:"connection status",listUsageOverride:"connection",helpDescription:"Inspect active remote connection state",summary:"Inspect the active saved remote connection before assuming commands are local",positionalArgs:["status"],supportedFlags:["remoteConfig","stateDir","session"]},disconnect:{helpDescription:"Disconnect remote daemon state, stop owned Metro companion, and release lease",listUsageOverride:"disconnect",summary:"Clear remote connection state, stop owned Metro companions, and release remote leases",allowedFlags:["shutdown"],supportedFlags:["remoteConfig","stateDir","session"]},mcp:{helpDescription:"Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.",summary:"Start MCP server"},"react-devtools":{usageOverride:"react-devtools [...args]",listUsageOverride:"react-devtools",helpDescription:"Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis",summary:"Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles",positionalArgs:["args?"],allowsExtraPositionals:!0,supportedFlags:e},web:{usageOverride:"web setup | web doctor",listUsageOverride:"web setup|doctor",helpDescription:`Install and inspect the managed web automation backend used by --platform web.
1
+ import{COMMON_COMMAND_SUPPORTED_FLAG_KEYS as e,managementCliSchemas as t,perfCliSchemas as o,captureCliSchemas as a,observabilityCliSchemas as n,replayCliSchemas as r,interactionCliSchemas as s,recordingCliSchemas as i,METRO_PREPARE_FLAGS as d,batchCliSchemas as c,systemCliSchemas as l,reactNativeCliSchemas as p}from"./9873.js";import{listCommandMetadata as u,debuggingCliSchemas as m,metroCliSchemas as h}from"./2948.js";let g={auth:{usageOverride:"auth status|login|logout",listUsageOverride:"auth",helpDescription:"Manage cloud login state used by remote daemon and cloud device workflows.",summary:"Manage cloud login state used by remote daemon and cloud device workflows",positionalArgs:["status|login|logout"],supportedFlags:["remoteConfig","stateDir"]},connect:{usageOverride:"connect [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]",helpDescription:"Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.",listUsageOverride:"connect",summary:"Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI",allowedFlags:["remoteConfig","daemonBaseUrl","tenant","runId","leaseId","leaseBackend","force","noLogin"],supportedFlags:["stateDir","daemonAuthToken","session","platform",...d,"launchUrl"]},connection:{usageOverride:"connection status",listUsageOverride:"connection",helpDescription:"Inspect active remote connection state",summary:"Inspect the active saved remote connection before assuming commands are local",positionalArgs:["status"],supportedFlags:["remoteConfig","stateDir","session"]},disconnect:{helpDescription:"Disconnect remote daemon state, stop owned Metro companion, and release lease",listUsageOverride:"disconnect",summary:"Clear remote connection state, stop owned Metro companions, and release remote leases",allowedFlags:["shutdown"],supportedFlags:["remoteConfig","stateDir","session"]},mcp:{helpDescription:"Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.",summary:"Start MCP server"},proxy:{usageOverride:"proxy [--host <host>] [--port <port>] [--daemon-auth-token <token>] [--state-dir <path>]",listUsageOverride:"proxy",helpDescription:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
2
+
3
+ Run this on the host that has access to simulators/devices, then point another machine at the printed daemon base URL with --daemon-base-url or AGENT_DEVICE_DAEMON_BASE_URL.
4
+
5
+ The proxy starts or reuses a local HTTP daemon, accepts /health, /rpc, /upload, and /artifacts/*, and also accepts the same routes under /agent-device/*. Health is unauthenticated for reachability probes. Other routes require the generated bearer token printed at startup, or the explicit --daemon-auth-token value when provided. The proxy rewrites authorized client requests to the upstream daemon token instead of exposing the local daemon token.
6
+
7
+ Use the /agent-device base path when connecting through cloudflared, ngrok, or another shared origin. Treat the bearer token as a secret; anyone with it can control the proxied daemon. This direct proxy flow does not use agent-device auth.
8
+
9
+ Examples:
10
+ agent-device proxy --port 4310
11
+ cloudflared tunnel --url http://127.0.0.1:4310
12
+ agent-device devices --daemon-base-url https://example.trycloudflare.com/agent-device --daemon-auth-token <token>`,summary:"Expose a local daemon through cloudflared, ngrok, or another HTTP tunnel",allowedFlags:["proxyHost","proxyPort","daemonAuthToken","stateDir"]},"react-devtools":{usageOverride:"react-devtools [...args]",listUsageOverride:"react-devtools",helpDescription:"Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis",summary:"Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles",positionalArgs:["args?"],allowsExtraPositionals:!0,supportedFlags:e},web:{usageOverride:"web setup | web doctor",listUsageOverride:"web setup|doctor",helpDescription:`Install and inspect the managed web automation backend used by --platform web.
2
13
 
3
14
  First-run flow:
4
15
  agent-device web setup
@@ -8,4 +19,4 @@ First-run flow:
8
19
 
9
20
  Runtime web commands do not install the backend implicitly. If the managed backend is missing, run agent-device web setup. The backend is resolved only from the managed install in the effective agent-device state dir.
10
21
 
11
- Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:"Manage web automation backend",positionalArgs:["setup|doctor"],supportedFlags:["stateDir"]}},v={...t,...n,...l,...r,...s,...o,...u,...g,...a,...c,...i,...m},h=new Map(p().map(t=>[t.name,{helpDescription:t.description,supportedFlags:e}]));function b(e){if(e)return C(e)}function w(e){let t=C(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function C(e){let t=Object.hasOwn(f,e)?f[e]:void 0;if(t)return t;let o=h.get(e),n=Object.hasOwn(v,e)?v[e]:void 0;if(o)return n?{...o,...n}:o}function _(e,t){let o=b(e);if(!o?.defaults)return!1;let n=!1;for(let[e,s]of Object.entries(o.defaults))void 0===t[e]&&(t[e]=s,n=!0);return n}export{_ as applyCommandDefaults,w as getCliCommandSchema,b as getCommandSchema};
22
+ Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:"Manage web automation backend",positionalArgs:["setup|doctor"],supportedFlags:["stateDir"]}},f={...t,...a,...l,...s,...n,...o,...m,...h,...r,...c,...i,...p},v=new Map(u().map(t=>[t.name,{helpDescription:t.description,supportedFlags:e}]));function b(e){if(e)return y(e)}function w(e){let t=y(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function y(e){let t=Object.hasOwn(g,e)?g[e]:void 0;if(t)return t;let o=v.get(e),a=Object.hasOwn(f,e)?f[e]:void 0;if(o)return a?{...o,...a}:o}function k(e,t){let o=b(e);if(!o?.defaults)return!1;let a=!1;for(let[e,n]of Object.entries(o.defaults))void 0===t[e]&&(t[e]=n,a=!0);return a}export{k as applyCommandDefaults,w as getCliCommandSchema,b as getCommandSchema};