agent-device 0.17.2 → 0.17.3

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 (83) hide show
  1. package/README.md +2 -2
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.2.apk → agent-device-android-multitouch-helper-0.17.3.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.3.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.2.manifest.json → agent-device-android-multitouch-helper-0.17.3.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.2.apk → agent-device-android-snapshot-helper-0.17.3.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.3.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.2.manifest.json → agent-device-android-snapshot-helper-0.17.3.manifest.json} +6 -6
  8. package/dist/src/123.js +1 -1
  9. package/dist/src/1231.js +1 -1
  10. package/dist/src/1352.js +1 -1
  11. package/dist/src/221.js +2 -2
  12. package/dist/src/2403.js +3 -3
  13. package/dist/src/2415.js +36 -29
  14. package/dist/src/5611.js +1 -0
  15. package/dist/src/5827.js +1 -0
  16. package/dist/src/6088.js +1 -0
  17. package/dist/src/6133.js +1 -0
  18. package/dist/src/7847.js +1 -1
  19. package/dist/src/9471.js +1 -1
  20. package/dist/src/9542.js +6 -3
  21. package/dist/src/9616.js +2 -1
  22. package/dist/src/9818.js +1 -1
  23. package/dist/src/android-snapshot-helper.d.ts +0 -1
  24. package/dist/src/android.js +5 -5
  25. package/dist/src/apple.js +1 -1
  26. package/dist/src/apps.js +10 -10
  27. package/dist/src/args.js +53 -14
  28. package/dist/src/batch.js +1 -1
  29. package/dist/src/cli-output.js +29 -0
  30. package/dist/src/cli.js +15 -16
  31. package/dist/src/command-surface.js +1 -1
  32. package/dist/src/contracts.d.ts +52 -0
  33. package/dist/src/contracts.js +1 -1
  34. package/dist/src/find.js +1 -1
  35. package/dist/src/generic.js +5 -5
  36. package/dist/src/index.d.ts +111 -8
  37. package/dist/src/index.js +1 -1
  38. package/dist/src/input-actions.js +1 -1
  39. package/dist/src/interaction.js +1 -1
  40. package/dist/src/react-native.js +1 -1
  41. package/dist/src/record-trace-recording.js +3 -3
  42. package/dist/src/selector-runtime.js +1 -1
  43. package/dist/src/selectors.d.ts +14 -0
  44. package/dist/src/selectors.js +1 -1
  45. package/dist/src/server.js +2 -2
  46. package/dist/src/session.js +8 -10
  47. package/dist/src/snapshot.js +2 -2
  48. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
  49. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +14 -0
  50. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +297 -0
  51. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +328 -0
  52. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +121 -172
  53. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +153 -5
  54. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +171 -0
  55. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -10
  56. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +64 -18
  57. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +200 -0
  58. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +406 -0
  59. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +82 -169
  60. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +425 -0
  61. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +77 -6
  62. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +10 -1
  63. package/ios-runner/README.md +5 -5
  64. package/ios-runner/RUNNER_PROTOCOL.md +0 -1
  65. package/package.json +3 -3
  66. package/server.json +2 -2
  67. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.2.apk.sha256 +0 -1
  68. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.2.apk.sha256 +0 -1
  69. package/dist/src/1534.js +0 -1
  70. package/dist/src/1620.js +0 -1
  71. package/dist/src/1644.js +0 -2
  72. package/dist/src/2284.js +0 -1
  73. package/dist/src/2474.js +0 -1
  74. package/dist/src/2672.js +0 -1
  75. package/dist/src/3393.js +0 -1
  76. package/dist/src/5898.js +0 -1
  77. package/dist/src/695.js +0 -1
  78. package/dist/src/7455.js +0 -1
  79. package/dist/src/8173.js +0 -27
  80. package/dist/src/8407.js +0 -1
  81. package/dist/src/8699.js +0 -1
  82. package/dist/src/9673.js +0 -1
  83. package/dist/src/9974.js +0 -1
package/dist/src/221.js CHANGED
@@ -1,6 +1,6 @@
1
- import e from"node:crypto";import t from"node:fs";import r from"node:fs/promises";import n from"node:os";import i from"node:path";import o from"node:net";import{AppError as a}from"./9152.js";import{intersectArea as s,isScrollableType as l}from"./4778.js";import{emitDiagnostic as u}from"./7599.js";import{installAndroidAdbPackage as d}from"./9639.js";let c="android-snapshot-helper",h="com.callstack.agentdevice.snapshothelper",p="com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",f="android-snapshot-helper-v1",w="uiautomator-xml",m={"-r":"replace","-t":"allowTestPackages","-d":"allowDowngrade","-g":"grantPermissions"};async function A(e){let t=await x(e.apkPath);if(t!==e.manifest.sha256)throw new a("COMMAND_FAILED","Android snapshot helper APK checksum mismatch",{apkPath:e.apkPath,expectedSha256:e.manifest.sha256,actualSha256:t})}async function M(e){let t=e.fetch??fetch,o=await t(e.manifestUrl);if(!o.ok)throw new a("COMMAND_FAILED","Failed to download Android snapshot helper manifest",{manifestUrl:e.manifestUrl,status:o.status,statusText:o.statusText});let s=g(JSON.parse((await v(o,65536,"Android snapshot helper manifest")).toString("utf8")));if(!s.apkUrl)throw new a("COMMAND_FAILED","Android snapshot helper manifest does not include apkUrl",{manifestUrl:e.manifestUrl});let l=e.cacheDir??i.join(n.tmpdir(),`agent-device-android-snapshot-helper-${s.version}`),u=!e.cacheDir;await r.mkdir(l,{recursive:!0});let d=s.assetName??`agent-device-android-snapshot-helper-${s.version}.apk`,c=i.join(l,d),h=await t(s.apkUrl);if(!h.ok)throw new a("COMMAND_FAILED","Failed to download Android snapshot helper APK",{apkUrl:s.apkUrl,status:h.status,statusText:h.statusText});await r.writeFile(c,await v(h,0x1400000,"Android snapshot helper APK"));let p={apkPath:c,manifest:s};return await A(p),{...p,cleanup:async()=>{await r.rm(u?l:c,{recursive:u,force:!0})}}}function g(e){var t,r;if(!e||"object"!=typeof e||Array.isArray(e))throw new a("INVALID_ARGS","Android snapshot helper manifest must be an object.");return{name:D(e.name,"name",c),version:y(e.version,"version"),releaseTag:I(e.releaseTag),assetName:I(e.assetName),apkUrl:(t=e.apkUrl,r="apkUrl",null===t?null:y(t,r)),sha256:function(e){let t=y(e,"sha256").trim().toLowerCase();if(64!==t.length||!function(e){for(let t of e){let e=t.charCodeAt(0),r=e>=48&&e<=57,n=e>=97&&e<=102;if(!r&&!n)return!1}return!0}(t))throw new a("INVALID_ARGS","Android snapshot helper manifest sha256 must be a 64-character hex string.");return t}(e.sha256),checksumName:I(e.checksumName),packageName:y(e.packageName,"packageName"),versionCode:C(e.versionCode,"versionCode"),instrumentationRunner:y(e.instrumentationRunner,"instrumentationRunner"),minSdk:C(e.minSdk,"minSdk"),targetSdk:void 0===e.targetSdk?void 0:C(e.targetSdk,"targetSdk"),outputFormat:D(e.outputFormat,"outputFormat",w),statusProtocol:D(e.statusProtocol,"statusProtocol",f),installArgs:N(e.installArgs)}}async function v(e,t,r){let n=e.headers.get("content-length");if(null!==n){let e=Number(n);if(Number.isFinite(e)&&e>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:e,maxBytes:t})}if(!e.body){let n=Buffer.from(await e.arrayBuffer());if(n.length>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:n.length,maxBytes:t});return n}let i=e.body.getReader(),o=[],s=0;try{for(;;){let{done:e,value:n}=await i.read();if(e)break;if((s+=n.byteLength)>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:s,maxBytes:t});o.push(Buffer.from(n))}}finally{i.releaseLock()}return Buffer.concat(o,s)}function N(e){let t=function(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be a string array.`);return e}(e,"installArgs");if("install"!==t[0])throw new a("INVALID_ARGS",'Android snapshot helper manifest installArgs must start with "install".');if(t.some(e=>e.includes("\0")))throw new a("INVALID_ARGS","Android snapshot helper manifest installArgs must not contain null bytes.");let r=t.slice(1).find(e=>void 0===b(e));if(r)throw new a("INVALID_ARGS",`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return t}async function x(r){return await new Promise((n,i)=>{let o=e.createHash("sha256"),a=t.createReadStream(r);a.on("error",i),a.on("data",e=>o.update(e)),a.on("end",()=>n(o.digest("hex")))})}function y(e,t){if("string"!=typeof e||0===e.trim().length)throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} is required.`);return e}function I(e){return"string"==typeof e&&e.trim().length>0?e:void 0}function C(e,t){if("number"!=typeof e||!Number.isInteger(e))throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be an integer.`);return e}function D(e,t,r){if(e!==r)throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be "${r}".`);return r}function b(e){if(Object.hasOwn(m,e))return m[e]}function*S(e){let t=/<node\b[^>]*>/g,r=t.exec(e);for(;r;)yield _(r[0]),r=t.exec(e)}function _(e){let t,r,n,i,o,a=(t=function(e){let t=new Map,r=e.indexOf(" "),n=e.lastIndexOf(">");if(r<0||n<=r)return t;let i=r;for(;i<n;){let r=function(e,t,r){var n,i;if((t=F(e,t,r))>=r||"/"===(n=e[t])||">"===n)return;let o=t;t=function(e,t,r){for(var n;t<r&&!("="===(n=e[t]??"")||"/"===n||">"===n||L(n));)t+=1;return t}(e,t,r);let a=e.slice(o,t);if(t=F(e,t,r),!a||"="!==e[t])return;t=F(e,t+1,r);let s=e[t];if('"'!==(i=s)&&"'"!==i)return;let l=t+1,u=e.indexOf(s,l);if(!(u<0)&&!(u>=r))return{name:a,value:function(e){let t="",r=0;for(;r<e.length;){let n=e.indexOf("&",r);if(n<0){t+=e.slice(r);break}t+=e.slice(r,n);let i=e.indexOf(";",n+1);if(i<0){t+=e.slice(n);break}t+=function(e){switch(e){case"amp":return"&";case"lt":return"<";case"gt":return">";case"quot":return'"';case"apos":return"'";default:return function(e){if(!e.startsWith("#"))return;let t=e[1]?.toLowerCase()==="x"?16:10,r=16===t?e.slice(2):e.slice(1);if(!r||!function(e,t){for(let r of e){let e=r.charCodeAt(0),n=e>=48&&e<=57;if(10===t){if(!n)return!1;continue}let i=e>=65&&e<=70,o=e>=97&&e<=102;if(!n&&!i&&!o)return!1}return!0}(r,t))return;let n=Number.parseInt(r,t);if(Number.isFinite(n))try{return String.fromCodePoint(n)}catch{return}}(e)}}(e.slice(n+1,i))??e.slice(n,i+1),r=i+1}return t}(e.slice(l,u)),nextCursor:u+1}}(e,i,n);if(!r)break;t.set(r.name,r.value),i=r.nextCursor}return t}(e),r=e=>{let r=O(t,e);if(null!==r)return"true"===r},n=(e,r)=>{let n=(e=>{let r=O(t,e);if(null===r||""===r.trim())return;let n=Number(r);return Number.isFinite(n)?n:void 0})(r);return void 0===n?{}:{[e]:n}},i=(e,t)=>{let n=r(t);return void 0===n?{}:{[e]:n}},{text:O(t,"text"),desc:O(t,"content-desc"),resourceId:O(t,"resource-id"),packageName:O(t,"package"),className:O(t,"class"),bounds:O(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused"),password:r("password"),...i("visibleToUser","visible-to-user"),...n("drawingOrder","drawing-order"),...i("scrollable","scrollable"),...i("canScrollForward","can-scroll-forward"),...i("canScrollBackward","can-scroll-backward"),...n("windowIndex","window-index"),...n("windowType","window-type"),...n("windowLayer","window-layer"),...i("windowActive","window-active"),...i("windowFocused","window-focused"),...void 0===(o=E(O(t,"window-bounds")))?{}:{windowRect:o}}),s=E(a.bounds);return{...a,...s?{rect:s}:{}}}function T(e,t,r){let{sourceNodes:n,...i}=k(P(e),t,r);return i}function k(e,t,r){let n={nodes:[],sourceNodes:[],...void 0!==t?{maxNodes:t}:{},maxDepth:r.depth??1/0,options:r,analysis:function(e){let t=0,r=0,n=[...e.children];for(;n.length>0;){let e=n.pop();t+=1,r=Math.max(r,e.depth),n.push(...e.children)}return{rawNodeCount:t,maxDepth:r}}(e),interactiveDescendantMemo:new Map,truncated:!1},i=r.scope?function(e,t){let r=t.toLowerCase(),n=[...e.children],i=0;for(;i<n.length;){let e=n[i++],t=e.label?.toLowerCase()??"",o=e.value?.toLowerCase()??"",a=e.identifier?.toLowerCase()??"";if(t.includes(r)||o.includes(r)||a.includes(r))return e;n.push(...e.children)}return null}(e,r.scope):null;for(let t of i?[i]:e.children)if(function e(t,r,n,i,o=!1,a=!1){if(void 0!==t.maxNodes&&t.nodes.length>=t.maxNodes){t.truncated=!0;return}if(n>t.maxDepth)return;let s=t.options.raw||function(e,t,r,n,i){var o,a,s;if(!1===e.visibleToUser)return!1;let u=function(e){let t=V(e.type),r=!!(e.label&&e.label.trim().length>0),n=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:r&&!B(e.label??""),hasMeaningfulId:n&&!B(e.identifier??""),isStructural:function(e){let t=e.split(".").pop()??e;return t.includes("layout")||"viewgroup"===t||"view"===t}(t),isVisual:"imageview"===t||"imagebutton"===t}}(e);return t.interactiveOnly?function(e,t,r,n,i){var o,a,s,u,d;return!((o=e).rect&&(o.rect.width<=0||o.rect.height<=0))&&(!!(e.hittable||l(t.type)&&n)||(a=t,s=r,u=n,d=i,(!!a.hasMeaningfulText||!!a.hasMeaningfulId)&&!a.isVisual&&(!a.isStructural||!!d)&&(s||u||d)))}(e,u,r,n,i):t.compact?u.hasMeaningfulText||u.hasMeaningfulId||!!e.hittable:!u.isStructural&&!u.isVisual||(o=e,a=u,s=n,!!o.hittable||!!a.hasMeaningfulText||!!a.hasMeaningfulId||s)}(r,t.options,o,function e(t,r){let n=t.interactiveDescendantMemo.get(r);if(void 0!==n)return n;for(let n of r.children)if(!1!==n.visibleToUser&&(n.hittable||e(t,n)))return t.interactiveDescendantMemo.set(r,!0),!0;return t.interactiveDescendantMemo.set(r,!1),!1}(t,r),a)?function(e,t,r,n){let i=e.nodes.length;return e.sourceNodes.push(t),e.nodes.push({index:i,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:r,parentIndex:n,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{}}),i}(t,r,n,i):i,u=o||!!r.hittable,d=a||function(e){if(!e)return!1;let t=V(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(r.type);for(let i of r.children)if(e(t,i,n+1,s,u,d),t.truncated)return}(n,t,0),n.truncated)break;let o={nodes:n.nodes,sourceNodes:n.sourceNodes,analysis:n.analysis};return n.truncated?{...o,truncated:!0}:o}function F(e,t,r){for(;t<r&&L(e[t]??"");)t+=1;return t}function L(e){return" "===e||"\n"===e||"\r"===e||" "===e}function O(e,t){return e.get(t)??null}function E(e){if(!e)return;let t=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),n=Number(t[2]);return{x:r,y:n,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-n)}}function P(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,depth:-1,children:[]},r=[t],n=/<node\b[^>]*>|<\/node>/g,i=n.exec(e);for(;i;){let t=i[0];if(t.startsWith("</node")){r.length>1&&r.pop(),i=n.exec(e);continue}let o=_(t),a=r[r.length-1],s={type:o.className,label:o.text||o.desc,value:o.text,identifier:o.resourceId,packageName:o.packageName,rect:o.rect,enabled:o.enabled,visibleToUser:o.visibleToUser,drawingOrder:o.drawingOrder,hittable:o.clickable??o.focusable,scrollable:o.scrollable,canScrollForward:o.canScrollForward,canScrollBackward:o.canScrollBackward,windowIndex:o.windowIndex,windowType:o.windowType,windowLayer:o.windowLayer,windowActive:o.windowActive,windowFocused:o.windowFocused,windowRect:o.windowRect,depth:a.depth+1,parentIndex:void 0,children:[]};a.children.push(s),t.endsWith("/>")||r.push(s),i=n.exec(e)}return function e(t){let r=0;for(let n of t.children)!1!==n.visibleToUser&&(e(n),t.children[r]=n,r+=1);r<t.children.length&&(t.children.length=r)}(t),function(e){let t,r=e.children.filter(U);if(r.length<2)return;let n=r.filter(e=>$(e)&&H(e));if(0===n.length)return;let i=(t=n.map(e=>e.windowLayer).filter(e=>void 0!==e)).length>0?Math.max(...t):void 0;e.children=e.children.filter(e=>!$(e)||!!H(e)&&(void 0===i||e.windowLayer===i))}(t),function e(t,r){for(let n of t.children)e(n,r);if(t.children.length<2)return;let n=t.children,i=n.filter(e=>{var t,n;return t=e,n=r,!1!==t.visibleToUser&&void 0!==t.drawingOrder&&R(t)&&function e(t,r){let n=r.agentVisibleContentMemo.get(t);if(void 0!==n)return n;let i=function(t,r){if(!1===t.visibleToUser)return!1;if(t.hittable)return!0;let n=t.label?.trim()??"";if(n&&!B(n))return!0;let i=t.identifier?.trim()??"";return!(!i||B(i))||t.children.some(t=>e(t,r))}(t,r);return r.agentVisibleContentMemo.set(t,i),i}(t,n)});0!==i.length&&(t.children=n.filter(e=>!function(e,t){if(!1===e.visibleToUser||void 0===e.drawingOrder||!R(e))return!1;for(let r of t)if(r!==e&&!(r.drawingOrder<=e.drawingOrder)&&function(e,t){let r=t.width*t.height;return r<=0?0:s(e,t)/r}(r.rect,e.rect)>=.9)return!0;return!1}(e,i)))}(t,{agentVisibleContentMemo:new WeakMap}),function(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),function(e){if(!e.scrollable||!l(e.type)||`${e.type??""}`.toLowerCase().includes("horizontalscrollview"))return!1;let t=function(e){if(!e.rect||0===e.children.length)return null;let t=e.children.map(e=>e.rect).filter(e=>void 0!==e);if(0===t.length)return null;let r=Math.min(...t.map(e=>e.x)),n=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),o=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,n-r-e.rect.width),vertical:Math.max(0,o-i-e.rect.height)}}(e);return!t||!(t.horizontal>t.vertical)||!(t.horizontal>16)}(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}(t),t}function R(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function U(e){return void 0!==e.windowIndex||void 0!==e.windowType}function $(e){return 1===e.windowType}function H(e){return!0===e.windowActive||!0===e.windowFocused}function V(e){return e?e.toLowerCase():""}function B(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}async function K(e){let t=G(e),r=await e.adb(W(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs}),{output:n,cleanupDone:i}=await X(e,t,r);if(t.outputPath&&!i&&await J(e.adb,t.outputPath),0!==r.exitCode)throw new a("COMMAND_FAILED","Android snapshot helper failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,helper:n.metadata});return n}function G(e){let t=Q(e.timeoutMs,8e3),r=Q(e.packageName,h);return{waitForIdleTimeoutMs:Q(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:Q(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:Q(e.commandTimeoutMs,t+5e3),maxDepth:Q(e.maxDepth,128),maxNodes:Q(e.maxNodes,5e3),packageName:r,runner:Q(e.instrumentationRunner,`${r}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...void 0!==e.emitChunks?{emitChunks:e.emitChunks}:{}}}function Q(e,t){return void 0===e?t:e}function W(e){return["shell","am","instrument","-w","-e","waitForIdleTimeoutMs",String(e.waitForIdleTimeoutMs),"-e","waitForIdleQuietMs",String(e.waitForIdleQuietMs),"-e","timeoutMs",String(e.timeoutMs),"-e","maxDepth",String(e.maxDepth),"-e","maxNodes",String(e.maxNodes),...e.outputPath?["-e","outputPath",e.outputPath]:[],...void 0!==e.emitChunks?["-e","emitChunks",String(e.emitChunks)]:[],e.runner]}async function X(e,t,r){try{return{output:Y(`${r.stdout}
1
+ import e from"node:crypto";import t from"node:fs";import r from"node:fs/promises";import n from"node:os";import i from"node:path";import o from"node:net";import{AppError as a}from"./9152.js";import{intersectArea as s,isScrollableType as l}from"./4778.js";import{emitDiagnostic as u}from"./7599.js";import{installAndroidAdbPackage as d}from"./9639.js";let c="android-snapshot-helper",h="com.callstack.agentdevice.snapshothelper",p="com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",f="android-snapshot-helper-v1",w="uiautomator-xml",m={"-r":"replace","-t":"allowTestPackages","-d":"allowDowngrade","-g":"grantPermissions"};async function A(e){let t=await x(e.apkPath);if(t!==e.manifest.sha256)throw new a("COMMAND_FAILED","Android snapshot helper APK checksum mismatch",{apkPath:e.apkPath,expectedSha256:e.manifest.sha256,actualSha256:t})}async function M(e){let t=e.fetch??fetch,o=await t(e.manifestUrl);if(!o.ok)throw new a("COMMAND_FAILED","Failed to download Android snapshot helper manifest",{manifestUrl:e.manifestUrl,status:o.status,statusText:o.statusText});let s=g(JSON.parse((await v(o,65536,"Android snapshot helper manifest")).toString("utf8")));if(!s.apkUrl)throw new a("COMMAND_FAILED","Android snapshot helper manifest does not include apkUrl",{manifestUrl:e.manifestUrl});let l=e.cacheDir??i.join(n.tmpdir(),`agent-device-android-snapshot-helper-${s.version}`),u=!e.cacheDir;await r.mkdir(l,{recursive:!0});let d=s.assetName??`agent-device-android-snapshot-helper-${s.version}.apk`,c=i.join(l,d),h=await t(s.apkUrl);if(!h.ok)throw new a("COMMAND_FAILED","Failed to download Android snapshot helper APK",{apkUrl:s.apkUrl,status:h.status,statusText:h.statusText});await r.writeFile(c,await v(h,0x1400000,"Android snapshot helper APK"));let p={apkPath:c,manifest:s};return await A(p),{...p,cleanup:async()=>{await r.rm(u?l:c,{recursive:u,force:!0})}}}function g(e){var t,r;if(!e||"object"!=typeof e||Array.isArray(e))throw new a("INVALID_ARGS","Android snapshot helper manifest must be an object.");return{name:D(e.name,"name",c),version:y(e.version,"version"),releaseTag:I(e.releaseTag),assetName:I(e.assetName),apkUrl:(t=e.apkUrl,r="apkUrl",null===t?null:y(t,r)),sha256:function(e){let t=y(e,"sha256").trim().toLowerCase();if(64!==t.length||!function(e){for(let t of e){let e=t.charCodeAt(0),r=e>=48&&e<=57,n=e>=97&&e<=102;if(!r&&!n)return!1}return!0}(t))throw new a("INVALID_ARGS","Android snapshot helper manifest sha256 must be a 64-character hex string.");return t}(e.sha256),checksumName:I(e.checksumName),packageName:y(e.packageName,"packageName"),versionCode:C(e.versionCode,"versionCode"),instrumentationRunner:y(e.instrumentationRunner,"instrumentationRunner"),minSdk:C(e.minSdk,"minSdk"),targetSdk:void 0===e.targetSdk?void 0:C(e.targetSdk,"targetSdk"),outputFormat:D(e.outputFormat,"outputFormat",w),statusProtocol:D(e.statusProtocol,"statusProtocol",f),installArgs:N(e.installArgs)}}async function v(e,t,r){let n=e.headers.get("content-length");if(null!==n){let e=Number(n);if(Number.isFinite(e)&&e>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:e,maxBytes:t})}if(!e.body){let n=Buffer.from(await e.arrayBuffer());if(n.length>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:n.length,maxBytes:t});return n}let i=e.body.getReader(),o=[],s=0;try{for(;;){let{done:e,value:n}=await i.read();if(e)break;if((s+=n.byteLength)>t)throw new a("COMMAND_FAILED",`${r} download exceeds size limit`,{contentLength:s,maxBytes:t});o.push(Buffer.from(n))}}finally{i.releaseLock()}return Buffer.concat(o,s)}function N(e){let t=function(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be a string array.`);return e}(e,"installArgs");if("install"!==t[0])throw new a("INVALID_ARGS",'Android snapshot helper manifest installArgs must start with "install".');if(t.some(e=>e.includes("\0")))throw new a("INVALID_ARGS","Android snapshot helper manifest installArgs must not contain null bytes.");let r=t.slice(1).find(e=>void 0===b(e));if(r)throw new a("INVALID_ARGS",`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return t}async function x(r){return await new Promise((n,i)=>{let o=e.createHash("sha256"),a=t.createReadStream(r);a.on("error",i),a.on("data",e=>o.update(e)),a.on("end",()=>n(o.digest("hex")))})}function y(e,t){if("string"!=typeof e||0===e.trim().length)throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} is required.`);return e}function I(e){return"string"==typeof e&&e.trim().length>0?e:void 0}function C(e,t){if("number"!=typeof e||!Number.isInteger(e))throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be an integer.`);return e}function D(e,t,r){if(e!==r)throw new a("INVALID_ARGS",`Android snapshot helper manifest ${t} must be "${r}".`);return r}function b(e){if(Object.hasOwn(m,e))return m[e]}function*S(e){let t=/<node\b[^>]*>/g,r=t.exec(e);for(;r;)yield _(r[0]),r=t.exec(e)}function _(e){let t,r,n,i,o,a=(t=function(e){let t=new Map,r=e.indexOf(" "),n=e.lastIndexOf(">");if(r<0||n<=r)return t;let i=r;for(;i<n;){let r=function(e,t,r){var n,i;if((t=F(e,t,r))>=r||"/"===(n=e[t])||">"===n)return;let o=t;t=function(e,t,r){for(var n;t<r&&!("="===(n=e[t]??"")||"/"===n||">"===n||L(n));)t+=1;return t}(e,t,r);let a=e.slice(o,t);if(t=F(e,t,r),!a||"="!==e[t])return;t=F(e,t+1,r);let s=e[t];if('"'!==(i=s)&&"'"!==i)return;let l=t+1,u=e.indexOf(s,l);if(!(u<0)&&!(u>=r))return{name:a,value:function(e){let t="",r=0;for(;r<e.length;){let n=e.indexOf("&",r);if(n<0){t+=e.slice(r);break}t+=e.slice(r,n);let i=e.indexOf(";",n+1);if(i<0){t+=e.slice(n);break}t+=function(e){switch(e){case"amp":return"&";case"lt":return"<";case"gt":return">";case"quot":return'"';case"apos":return"'";default:return function(e){if(!e.startsWith("#"))return;let t=e[1]?.toLowerCase()==="x"?16:10,r=16===t?e.slice(2):e.slice(1);if(!r||!function(e,t){for(let r of e){let e=r.charCodeAt(0),n=e>=48&&e<=57;if(10===t){if(!n)return!1;continue}let i=e>=65&&e<=70,o=e>=97&&e<=102;if(!n&&!i&&!o)return!1}return!0}(r,t))return;let n=Number.parseInt(r,t);if(Number.isFinite(n))try{return String.fromCodePoint(n)}catch{return}}(e)}}(e.slice(n+1,i))??e.slice(n,i+1),r=i+1}return t}(e.slice(l,u)),nextCursor:u+1}}(e,i,n);if(!r)break;t.set(r.name,r.value),i=r.nextCursor}return t}(e),r=e=>{let r=O(t,e);if(null!==r)return"true"===r},n=(e,r)=>{let n=(e=>{let r=O(t,e);if(null===r||""===r.trim())return;let n=Number(r);return Number.isFinite(n)?n:void 0})(r);return void 0===n?{}:{[e]:n}},i=(e,t)=>{let n=r(t);return void 0===n?{}:{[e]:n}},{text:O(t,"text"),desc:O(t,"content-desc"),resourceId:O(t,"resource-id"),packageName:O(t,"package"),className:O(t,"class"),bounds:O(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused"),password:r("password"),...i("visibleToUser","visible-to-user"),...n("drawingOrder","drawing-order"),...i("scrollable","scrollable"),...i("canScrollForward","can-scroll-forward"),...i("canScrollBackward","can-scroll-backward"),...n("windowIndex","window-index"),...n("windowType","window-type"),...n("windowLayer","window-layer"),...i("windowActive","window-active"),...i("windowFocused","window-focused"),...void 0===(o=E(O(t,"window-bounds")))?{}:{windowRect:o}}),s=E(a.bounds);return{...a,...s?{rect:s}:{}}}function T(e,t,r){let{sourceNodes:n,...i}=k(P(e),t,r);return i}function k(e,t,r){let n={nodes:[],sourceNodes:[],...void 0!==t?{maxNodes:t}:{},maxDepth:r.depth??1/0,options:r,analysis:function(e){let t=0,r=0,n=[...e.children];for(;n.length>0;){let e=n.pop();t+=1,r=Math.max(r,e.depth),n.push(...e.children)}return{rawNodeCount:t,maxDepth:r}}(e),interactiveDescendantMemo:new Map,truncated:!1},i=r.scope?function(e,t){let r=t.toLowerCase(),n=[...e.children],i=0;for(;i<n.length;){let e=n[i++],t=e.label?.toLowerCase()??"",o=e.value?.toLowerCase()??"",a=e.identifier?.toLowerCase()??"";if(t.includes(r)||o.includes(r)||a.includes(r))return e;n.push(...e.children)}return null}(e,r.scope):null;for(let t of i?[i]:e.children)if(function e(t,r,n,i,o=!1,a=!1){if(void 0!==t.maxNodes&&t.nodes.length>=t.maxNodes){t.truncated=!0;return}if(n>t.maxDepth)return;let s=t.options.raw||function(e,t,r,n,i){var o,a,s;if(!1===e.visibleToUser)return!1;let u=function(e){let t=V(e.type),r=!!(e.label&&e.label.trim().length>0),n=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:r&&!B(e.label??""),hasMeaningfulId:n&&!B(e.identifier??""),isStructural:function(e){let t=e.split(".").pop()??e;return t.includes("layout")||"viewgroup"===t||"view"===t}(t),isVisual:"imageview"===t||"imagebutton"===t}}(e);return t.interactiveOnly?function(e,t,r,n,i){var o,a,s,u,d;return!((o=e).rect&&(o.rect.width<=0||o.rect.height<=0))&&(!!(e.hittable||l(t.type)&&n)||(a=t,s=r,u=n,d=i,(!!a.hasMeaningfulText||!!a.hasMeaningfulId)&&!a.isVisual&&(!a.isStructural||!!d)&&(s||u||d)))}(e,u,r,n,i):!u.isStructural&&!u.isVisual||(o=e,a=u,s=n,!!o.hittable||!!a.hasMeaningfulText||!!a.hasMeaningfulId||s)}(r,t.options,o,function e(t,r){let n=t.interactiveDescendantMemo.get(r);if(void 0!==n)return n;for(let n of r.children)if(!1!==n.visibleToUser&&(n.hittable||e(t,n)))return t.interactiveDescendantMemo.set(r,!0),!0;return t.interactiveDescendantMemo.set(r,!1),!1}(t,r),a)?function(e,t,r,n){let i=e.nodes.length;return e.sourceNodes.push(t),e.nodes.push({index:i,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:r,parentIndex:n,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{}}),i}(t,r,n,i):i,u=o||!!r.hittable,d=a||function(e){if(!e)return!1;let t=V(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(r.type);for(let i of r.children)if(e(t,i,n+1,s,u,d),t.truncated)return}(n,t,0),n.truncated)break;let o={nodes:n.nodes,sourceNodes:n.sourceNodes,analysis:n.analysis};return n.truncated?{...o,truncated:!0}:o}function F(e,t,r){for(;t<r&&L(e[t]??"");)t+=1;return t}function L(e){return" "===e||"\n"===e||"\r"===e||" "===e}function O(e,t){return e.get(t)??null}function E(e){if(!e)return;let t=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),n=Number(t[2]);return{x:r,y:n,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-n)}}function P(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,depth:-1,children:[]},r=[t],n=/<node\b[^>]*>|<\/node>/g,i=n.exec(e);for(;i;){let t=i[0];if(t.startsWith("</node")){r.length>1&&r.pop(),i=n.exec(e);continue}let o=_(t),a=r[r.length-1],s={type:o.className,label:o.text||o.desc,value:o.text,identifier:o.resourceId,packageName:o.packageName,rect:o.rect,enabled:o.enabled,visibleToUser:o.visibleToUser,drawingOrder:o.drawingOrder,hittable:o.clickable??o.focusable,scrollable:o.scrollable,canScrollForward:o.canScrollForward,canScrollBackward:o.canScrollBackward,windowIndex:o.windowIndex,windowType:o.windowType,windowLayer:o.windowLayer,windowActive:o.windowActive,windowFocused:o.windowFocused,windowRect:o.windowRect,depth:a.depth+1,parentIndex:void 0,children:[]};a.children.push(s),t.endsWith("/>")||r.push(s),i=n.exec(e)}return function e(t){let r=0;for(let n of t.children)!1!==n.visibleToUser&&(e(n),t.children[r]=n,r+=1);r<t.children.length&&(t.children.length=r)}(t),function(e){let t,r=e.children.filter(U);if(r.length<2)return;let n=r.filter(e=>$(e)&&H(e));if(0===n.length)return;let i=(t=n.map(e=>e.windowLayer).filter(e=>void 0!==e)).length>0?Math.max(...t):void 0;e.children=e.children.filter(e=>!$(e)||!!H(e)&&(void 0===i||e.windowLayer===i))}(t),function e(t,r){for(let n of t.children)e(n,r);if(t.children.length<2)return;let n=t.children,i=n.filter(e=>{var t,n;return t=e,n=r,!1!==t.visibleToUser&&void 0!==t.drawingOrder&&R(t)&&function e(t,r){let n=r.agentVisibleContentMemo.get(t);if(void 0!==n)return n;let i=function(t,r){if(!1===t.visibleToUser)return!1;if(t.hittable)return!0;let n=t.label?.trim()??"";if(n&&!B(n))return!0;let i=t.identifier?.trim()??"";return!(!i||B(i))||t.children.some(t=>e(t,r))}(t,r);return r.agentVisibleContentMemo.set(t,i),i}(t,n)});0!==i.length&&(t.children=n.filter(e=>!function(e,t){if(!1===e.visibleToUser||void 0===e.drawingOrder||!R(e))return!1;for(let r of t)if(r!==e&&!(r.drawingOrder<=e.drawingOrder)&&function(e,t){let r=t.width*t.height;return r<=0?0:s(e,t)/r}(r.rect,e.rect)>=.9)return!0;return!1}(e,i)))}(t,{agentVisibleContentMemo:new WeakMap}),function(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),function(e){if(!e.scrollable||!l(e.type)||`${e.type??""}`.toLowerCase().includes("horizontalscrollview"))return!1;let t=function(e){if(!e.rect||0===e.children.length)return null;let t=e.children.map(e=>e.rect).filter(e=>void 0!==e);if(0===t.length)return null;let r=Math.min(...t.map(e=>e.x)),n=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),o=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,n-r-e.rect.width),vertical:Math.max(0,o-i-e.rect.height)}}(e);return!t||!(t.horizontal>t.vertical)||!(t.horizontal>16)}(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}(t),t}function R(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function U(e){return void 0!==e.windowIndex||void 0!==e.windowType}function $(e){return 1===e.windowType}function H(e){return!0===e.windowActive||!0===e.windowFocused}function V(e){return e?e.toLowerCase():""}function B(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}async function K(e){let t=G(e),r=await e.adb(W(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs}),{output:n,cleanupDone:i}=await X(e,t,r);if(t.outputPath&&!i&&await J(e.adb,t.outputPath),0!==r.exitCode)throw new a("COMMAND_FAILED","Android snapshot helper failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,helper:n.metadata});return n}function G(e){let t=Q(e.timeoutMs,8e3),r=Q(e.packageName,h);return{waitForIdleTimeoutMs:Q(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:Q(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:Q(e.commandTimeoutMs,t+5e3),maxDepth:Q(e.maxDepth,128),maxNodes:Q(e.maxNodes,5e3),packageName:r,runner:Q(e.instrumentationRunner,`${r}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...void 0!==e.emitChunks?{emitChunks:e.emitChunks}:{}}}function Q(e,t){return void 0===e?t:e}function W(e){return["shell","am","instrument","-w","-e","waitForIdleTimeoutMs",String(e.waitForIdleTimeoutMs),"-e","waitForIdleQuietMs",String(e.waitForIdleQuietMs),"-e","timeoutMs",String(e.timeoutMs),"-e","maxDepth",String(e.maxDepth),"-e","maxNodes",String(e.maxNodes),...e.outputPath?["-e","outputPath",e.outputPath]:[],...void 0!==e.emitChunks?["-e","emitChunks",String(e.emitChunks)]:[],e.runner]}async function X(e,t,r){try{return{output:Y(`${r.stdout}
2
2
  ${r.stderr}`),cleanupDone:!1}}catch(n){return await z(e,t,r,n)}}async function z(e,t,r,n){if(n instanceof a&&0!==r.exitCode&&n.details?.helper)throw n;let i=await j(e,t,r);if(i)return{output:i,cleanupDone:!0};throw new a("COMMAND_FAILED",0===r.exitCode?"Android snapshot helper output could not be parsed":"Android snapshot helper failed before returning parseable output",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode},n)}async function j(e,t,r){if(0===r.exitCode&&t.outputPath){var n;return await q(e.adb,t.outputPath,function(e){try{let t=er(e);return et(ee(t.results))}catch{return null}}(`${r.stdout}
3
- ${r.stderr}`)??{outputFormat:w,waitForIdleTimeoutMs:(n=t).waitForIdleTimeoutMs,waitForIdleQuietMs:n.waitForIdleQuietMs,timeoutMs:n.timeoutMs,maxDepth:n.maxDepth,maxNodes:n.maxNodes,transport:"instrumentation"})}}async function q(e,t,r){let n;try{var i;n=await e((i=t,["shell","sh","-c",'cat "$1"; status=$?; rm -f "$1"; exit "$status"',"agent-device-snapshot-helper-output",i]),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(0!==n.exitCode)return;let o=n.stdout.trim();if(o.includes("<hierarchy")&&o.includes("</hierarchy>"))return{xml:o,metadata:r}}async function J(e,t){try{await e(["shell","rm","-f",t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Y(e){let t=er(e),r=ee(t.results);return{xml:function(e,t){if(0===e.length)throw new a("COMMAND_FAILED","Android snapshot helper did not return XML chunks",{helper:t});let r=function(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new a("COMMAND_FAILED","Android snapshot helper returned incomplete XML chunks",{expectedChunks:t,actualChunks:e.length});return t}(e),n=Buffer.concat(function(e,t){let r=[];for(let n=0;n<t;n+=1){let i=e.get(n);if(void 0===i)throw new a("COMMAND_FAILED","Android snapshot helper returned incomplete XML chunks",{missingChunkIndex:n,expectedChunks:t});r.push(Buffer.from(i,"base64"))}return r}(function(e,t){let r=new Map;for(let n of e){if(void 0===n.index||n.index<0||n.index>=t)throw new a("COMMAND_FAILED","Android snapshot helper returned invalid chunk index",{chunkIndex:n.index,expectedChunks:t});if(r.has(n.index))throw new a("COMMAND_FAILED","Android snapshot helper returned duplicate XML chunks",{chunkIndex:n.index});r.set(n.index,n.payloadBase64)}return r}(e,r),r)).toString("utf8");if(!n.includes("<hierarchy")||!n.includes("</hierarchy>"))throw new a("COMMAND_FAILED","Android snapshot helper output did not contain XML",{xml:n});return n}(function(e){let t=[];for(let r of e){if(r.agentDeviceProtocol!==f||r.outputFormat!==w)continue;let{payloadBase64:e}=r;void 0!==e&&t.push({index:el(r.chunkIndex),count:el(r.chunkCount),payloadBase64:e})}return t}(t.status),r),metadata:{...et(r),transport:"instrumentation"}}}function Z(e,t={outputFormat:w},r={},n){return{...T(e,n,r),metadata:t}}function ee(e){let t=e.find(e=>e.agentDeviceProtocol===f);if(!t)throw new a("COMMAND_FAILED","Android snapshot helper did not return a final result");if("true"!==t.ok){var r;throw new a("COMMAND_FAILED",(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android snapshot helper returned an error",{errorType:t.errorType,helper:t})}return t}function et(e){var t;return{helperApiVersion:e.helperApiVersion,outputFormat:w,waitForIdleTimeoutMs:el(e.waitForIdleTimeoutMs),waitForIdleQuietMs:el(e.waitForIdleQuietMs),timeoutMs:el(e.timeoutMs),maxDepth:el(e.maxDepth),maxNodes:el(e.maxNodes),rootPresent:eu(e.rootPresent),captureMode:"interactive-windows"===(t=e.captureMode)||"active-window"===t?t:void 0,windowCount:el(e.windowCount),nodeCount:el(e.nodeCount),truncated:eu(e.truncated),elapsedMs:el(e.elapsedMs)}}function er(e){var t;let r={status:[],results:[],currentStatus:null,currentResult:null};for(let t of e.split(/\r?\n/))!function(e,t){if(e.startsWith("INSTRUMENTATION_STATUS: ")){t.currentStatus??={},eo(e.slice(24),t.currentStatus);return}if(e.startsWith("INSTRUMENTATION_STATUS_CODE: "))return en(t);if(e.startsWith("INSTRUMENTATION_RESULT: ")){t.currentResult??={},eo(e.slice(24),t.currentResult);return}e.startsWith("INSTRUMENTATION_CODE: ")&&ei(t)}(t,r);return en(t=r),ei(t),{status:r.status,results:r.results}}function en(e){e.currentStatus&&(e.status.push(e.currentStatus),e.currentStatus=null)}function ei(e){e.currentResult&&(e.results.push(e.currentResult),e.currentResult=null)}function eo(e,t){let r=e.indexOf("=");r<0||(t[e.slice(0,r)]=e.slice(r+1))}function ea(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function es(e){return"true"===e||"false"!==e&&void 0}let el=ea,eu=es,ed=new Map,ec=new Map;async function eh(e){var t,r,n;let i;if(!(void 0===(i=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION)||!/^(0|false|no|off)$/i.test(i))||!e.adbProvider?.spawn)return;let o=G(e),a=e.deviceKey??"android:default",s=(t=a,r=o,n=e,JSON.stringify({deviceKey:t,packageName:r.packageName,runner:r.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,waitForIdleTimeoutMs:r.waitForIdleTimeoutMs,waitForIdleQuietMs:r.waitForIdleQuietMs,timeoutMs:r.timeoutMs,maxDepth:r.maxDepth,maxNodes:r.maxNodes}));if(ec.get(a)===s)return;let l=ed.get(a);if(l&&l.identity!==s&&(await ep(a),l=void 0),!l)try{l=await ef({deviceKey:a,identity:s,options:e,resolved:o})}catch(e){ec.set(a,s),u({level:"warn",phase:"android_snapshot_helper_session_disabled",data:{deviceKey:a,reason:e instanceof Error?e.message:String(e)}});return}try{let e=l.capturedCount>0,t=await em(l,o);return l.capturedCount+=1,{xml:t.xml,metadata:{...t.metadata,transport:"persistent-session",sessionReused:e}}}catch(e){throw await ep(a),e}}async function ep(e){let t=ed.get(e);if(t){ed.delete(e);try{await eA(t,`quit ${Date.now()}`,1e3)}catch{}try{await t.process.kill("SIGTERM")}catch{}await ew(t.process,2e3);try{await eM(t)}catch{}u({phase:"android_snapshot_helper_session_stop",data:{deviceKey:e,port:t.port,capturedCount:t.capturedCount,lifetimeMs:Date.now()-t.startedAtMs}})}}async function ef(e){let t=await new Promise((e,t)=>{let r=o.createServer();r.unref(),r.on("error",t),r.listen(0,"127.0.0.1",()=>{let n=r.address();if(!n||"string"==typeof n)return void r.close(()=>t(Error("Failed to allocate a local TCP port")));let i=n.port;r.close(()=>e(i))})});await e.options.adb(["forward",`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:5e3});let r=W({...e.resolved,outputPath:void 0,emitChunks:!1}),n=r[r.length-1];if(!n)throw new a("INVALID_ARGS","Android snapshot helper runner was not resolved");let i=[...r.slice(0,-1),"-e","sessionPort",String(t),n],s=e.options.adbProvider.spawn(i,{allowFailure:!0,captureOutput:!1}),l={identity:e.identity,deviceKey:e.deviceKey,port:t,adb:e.options.adb,process:s,startedAtMs:Date.now(),capturedCount:0};try{var d;return await (d=s,new Promise((e,t)=>{let r="",n=setTimeout(()=>{t(new a("COMMAND_FAILED","Android snapshot helper session did not become ready",{output:r,timeoutMs:1e4}))},1e4),i=t=>{(r+=t.toString()).includes(`agentDeviceProtocol=${f}`)&&r.includes("sessionReady=true")&&(clearTimeout(n),e())};d.stdout?.on("data",i),d.stderr?.on("data",i),d.once("exit",(e,i)=>{clearTimeout(n),t(new a("COMMAND_FAILED","Android snapshot helper session exited before ready",{output:r,exitCode:e,signal:i}))}),d.on("error",e=>{clearTimeout(n),t(e)})})),ed.set(e.deviceKey,l),u({phase:"android_snapshot_helper_session_ready",data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),l}catch(e){await eM(l);try{s.kill("SIGTERM")}catch{}throw await ew(s,2e3),e}}function ew(e,t){return new Promise(r=>{let n=setTimeout(r,t);e.once("close",()=>{clearTimeout(n),r()}),e.once("exit",()=>{clearTimeout(n),r()})})}async function em(e,t){let r=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`,n=Math.max(t.timeoutMs+2e3,3e3);return function(e,t){var r;let{headers:n,xml:i}=function(e){let t=e.indexOf("\n\n");if(t<0)throw new a("COMMAND_FAILED","Android snapshot helper session returned malformed output",{response:e});return{headers:function(e){let t={};for(let r of e.split(/\r?\n/)){let e=r.indexOf("=");e<0||(t[r.slice(0,e)]=r.slice(e+1))}return t}(e.slice(0,t)),xml:e.slice(t+2)}}(e);return function(e,t){if(e.agentDeviceProtocol!==f)throw new a("COMMAND_FAILED","Android snapshot helper session returned wrong protocol",{headers:e});if(e.outputFormat!==w)throw new a("COMMAND_FAILED","Android snapshot helper session returned wrong output format",{headers:e});if(e.requestId!==t)throw new a("COMMAND_FAILED","Android snapshot helper session returned stale output",{headers:e,requestId:t});if("true"!==e.ok)throw new a("COMMAND_FAILED",e.message||e.errorType||"Android snapshot helper session returned an error",{helper:e})}(n,t),function(e,t){let r=ea(e.byteLength);if(void 0!==r&&Buffer.byteLength(t,"utf8")!==r)throw new a("COMMAND_FAILED","Android snapshot helper session returned truncated XML",{headers:e,actualByteLength:Buffer.byteLength(t,"utf8")});if(!t.includes("<hierarchy")||!t.includes("</hierarchy>"))throw new a("COMMAND_FAILED","Android snapshot helper session did not return XML",{headers:e,xml:t})}(n,i),{xml:i,metadata:{helperApiVersion:(r=n).helperApiVersion,outputFormat:w,waitForIdleTimeoutMs:ea(r.waitForIdleTimeoutMs),waitForIdleQuietMs:ea(r.waitForIdleQuietMs),timeoutMs:ea(r.timeoutMs),maxDepth:ea(r.maxDepth),maxNodes:ea(r.maxNodes),rootPresent:es(r.rootPresent),captureMode:"interactive-windows"===r.captureMode||"active-window"===r.captureMode?r.captureMode:void 0,windowCount:ea(r.windowCount),nodeCount:ea(r.nodeCount),truncated:es(r.truncated),elapsedMs:ea(r.elapsedMs)}}}(await eA(e,`snapshot ${r}`,n),r)}function eA(e,t,r){return new Promise((n,i)=>{let s=o.connect({host:"127.0.0.1",port:e.port}),l=[],u=setTimeout(()=>{s.destroy(),i(new a("COMMAND_FAILED","Android snapshot helper session request timed out",{command:t,timeoutMs:r,port:e.port}))},r);s.on("connect",()=>{s.write(`${t}
3
+ ${r.stderr}`)??{outputFormat:w,waitForIdleTimeoutMs:(n=t).waitForIdleTimeoutMs,waitForIdleQuietMs:n.waitForIdleQuietMs,timeoutMs:n.timeoutMs,maxDepth:n.maxDepth,maxNodes:n.maxNodes,transport:"instrumentation"})}}async function q(e,t,r){let n;try{var i;n=await e((i=t,["shell","sh","-c",'cat "$1"; status=$?; rm -f "$1"; exit "$status"',"agent-device-snapshot-helper-output",i]),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(0!==n.exitCode)return;let o=n.stdout.trim();if(o.includes("<hierarchy")&&o.includes("</hierarchy>"))return{xml:o,metadata:r}}async function J(e,t){try{await e(["shell","rm","-f",t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Y(e){let t=er(e),r=ee(t.results);return{xml:function(e,t){if(0===e.length)throw new a("COMMAND_FAILED","Android snapshot helper did not return XML chunks",{helper:t});let r=function(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new a("COMMAND_FAILED","Android snapshot helper returned incomplete XML chunks",{expectedChunks:t,actualChunks:e.length});return t}(e),n=Buffer.concat(function(e,t){let r=[];for(let n=0;n<t;n+=1){let i=e.get(n);if(void 0===i)throw new a("COMMAND_FAILED","Android snapshot helper returned incomplete XML chunks",{missingChunkIndex:n,expectedChunks:t});r.push(Buffer.from(i,"base64"))}return r}(function(e,t){let r=new Map;for(let n of e){if(void 0===n.index||n.index<0||n.index>=t)throw new a("COMMAND_FAILED","Android snapshot helper returned invalid chunk index",{chunkIndex:n.index,expectedChunks:t});if(r.has(n.index))throw new a("COMMAND_FAILED","Android snapshot helper returned duplicate XML chunks",{chunkIndex:n.index});r.set(n.index,n.payloadBase64)}return r}(e,r),r)).toString("utf8");if(!n.includes("<hierarchy")||!n.includes("</hierarchy>"))throw new a("COMMAND_FAILED","Android snapshot helper output did not contain XML",{xml:n});return n}(function(e){let t=[];for(let r of e){if(r.agentDeviceProtocol!==f||r.outputFormat!==w)continue;let{payloadBase64:e}=r;void 0!==e&&t.push({index:el(r.chunkIndex),count:el(r.chunkCount),payloadBase64:e})}return t}(t.status),r),metadata:{...et(r),transport:"instrumentation"}}}function Z(e,t={outputFormat:w},r={},n){return{...T(e,n,r),metadata:t}}function ee(e){let t=e.find(e=>e.agentDeviceProtocol===f);if(!t)throw new a("COMMAND_FAILED","Android snapshot helper did not return a final result");if("true"!==t.ok){var r;throw new a("COMMAND_FAILED",(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android snapshot helper returned an error",{errorType:t.errorType,helper:t})}return t}function et(e){var t;return{helperApiVersion:e.helperApiVersion,outputFormat:w,waitForIdleTimeoutMs:el(e.waitForIdleTimeoutMs),waitForIdleQuietMs:el(e.waitForIdleQuietMs),timeoutMs:el(e.timeoutMs),maxDepth:el(e.maxDepth),maxNodes:el(e.maxNodes),rootPresent:eu(e.rootPresent),captureMode:"interactive-windows"===(t=e.captureMode)||"active-window"===t?t:void 0,windowCount:el(e.windowCount),nodeCount:el(e.nodeCount),truncated:eu(e.truncated),elapsedMs:el(e.elapsedMs)}}function er(e){var t;let r={status:[],results:[],currentStatus:null,currentResult:null};for(let t of e.split(/\r?\n/))!function(e,t){if(e.startsWith("INSTRUMENTATION_STATUS: ")){t.currentStatus??={},eo(e.slice(24),t.currentStatus);return}if(e.startsWith("INSTRUMENTATION_STATUS_CODE: "))return en(t);if(e.startsWith("INSTRUMENTATION_RESULT: ")){t.currentResult??={},eo(e.slice(24),t.currentResult);return}e.startsWith("INSTRUMENTATION_CODE: ")&&ei(t)}(t,r);return en(t=r),ei(t),{status:r.status,results:r.results}}function en(e){e.currentStatus&&(e.status.push(e.currentStatus),e.currentStatus=null)}function ei(e){e.currentResult&&(e.results.push(e.currentResult),e.currentResult=null)}function eo(e,t){let r=e.indexOf("=");r<0||(t[e.slice(0,r)]=e.slice(r+1))}function ea(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function es(e){return"true"===e||"false"!==e&&void 0}let el=ea,eu=es,ed=new Map,ec=new Map;async function eh(e){var t,r,n;let i;if(!(void 0===(i=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION)||!/^(0|false|no|off)$/i.test(i))||!e.adbProvider?.spawn)return;let o=G(e),a=e.deviceKey??"android:default",s=(t=a,r=o,n=e,JSON.stringify({deviceKey:t,packageName:r.packageName,runner:r.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,waitForIdleTimeoutMs:r.waitForIdleTimeoutMs,waitForIdleQuietMs:r.waitForIdleQuietMs,timeoutMs:r.timeoutMs,maxDepth:r.maxDepth,maxNodes:r.maxNodes}));if(ec.get(a)===s)return;let l=ed.get(a);if(l&&l.identity!==s&&(await ep(a),l=void 0),!l)try{l=await ef({deviceKey:a,identity:s,options:e,resolved:o})}catch(e){ec.set(a,s),u({level:"warn",phase:"android_snapshot_helper_session_disabled",data:{deviceKey:a,reason:e instanceof Error?e.message:String(e)}});return}try{let e=l.capturedCount>0,t=await em(l,o);return l.capturedCount+=1,{xml:t.xml,metadata:{...t.metadata,transport:"persistent-session",sessionReused:e}}}catch(e){throw await ep(a),e}}async function ep(e){let t=ed.get(e);if(t){ed.delete(e);try{await eA(t,`quit ${Date.now()}`,1e3)}catch{}try{await t.process.kill("SIGTERM")}catch{}await ew(t.process,2e3);try{await eM(t)}catch{}u({phase:"android_snapshot_helper_session_stop",data:{deviceKey:e,port:t.port,capturedCount:t.capturedCount,lifetimeMs:Date.now()-t.startedAtMs}})}}async function ef(e){let t=await new Promise((e,t)=>{let r=o.createServer();r.unref(),r.on("error",t),r.listen(0,"127.0.0.1",()=>{let n=r.address();if(!n||"string"==typeof n)return void r.close(()=>t(Error("Failed to allocate a local TCP port")));let i=n.port;r.close(()=>e(i))})});await e.options.adb(["forward",`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:5e3});let r=W({...e.resolved,outputPath:void 0,emitChunks:!1}),n=r[r.length-1];if(!n)throw new a("INVALID_ARGS","Android snapshot helper runner was not resolved");let i=[...r.slice(0,-1),"-e","sessionPort",String(t),n],s=e.options.adbProvider.spawn(i,{allowFailure:!0,captureOutput:!1}),l={identity:e.identity,deviceKey:e.deviceKey,port:t,adb:e.options.adb,process:s,startedAtMs:Date.now(),capturedCount:0};try{var d;return await (d=s,new Promise((e,t)=>{let r="",n=setTimeout(()=>{t(new a("COMMAND_FAILED","Android snapshot helper session did not become ready",{output:r,timeoutMs:1e4}))},1e4),i=t=>{(r+=t.toString()).includes(`agentDeviceProtocol=${f}`)&&r.includes("sessionReady=true")&&(clearTimeout(n),e())};d.stdout?.on("data",i),d.stderr?.on("data",i),d.once("exit",(e,i)=>{clearTimeout(n),t(new a("COMMAND_FAILED","Android snapshot helper session exited before ready",{output:r,exitCode:e,signal:i}))}),d.on("error",e=>{clearTimeout(n),t(e)})})),ed.set(e.deviceKey,l),u({phase:"android_snapshot_helper_session_ready",data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),l}catch(e){await eM(l);try{s.kill("SIGTERM")}catch{}throw await ew(s,2e3),e}}function ew(e,t){return new Promise(r=>{let n=setTimeout(r,t);e.once("close",()=>{clearTimeout(n),r()}),e.once("exit",()=>{clearTimeout(n),r()})})}async function em(e,t){let r=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`,n=Math.min(t.commandTimeoutMs,Math.max(t.timeoutMs+1e4,3e3));return function(e,t){var r;let{headers:n,xml:i}=function(e){let t=e.indexOf("\n\n");if(t<0)throw new a("COMMAND_FAILED","Android snapshot helper session returned malformed output",{response:e});return{headers:function(e){let t={};for(let r of e.split(/\r?\n/)){let e=r.indexOf("=");e<0||(t[r.slice(0,e)]=r.slice(e+1))}return t}(e.slice(0,t)),xml:e.slice(t+2)}}(e);return function(e,t){if(e.agentDeviceProtocol!==f)throw new a("COMMAND_FAILED","Android snapshot helper session returned wrong protocol",{headers:e});if(e.outputFormat!==w)throw new a("COMMAND_FAILED","Android snapshot helper session returned wrong output format",{headers:e});if(e.requestId!==t)throw new a("COMMAND_FAILED","Android snapshot helper session returned stale output",{headers:e,requestId:t});if("true"!==e.ok)throw new a("COMMAND_FAILED",e.message||e.errorType||"Android snapshot helper session returned an error",{helper:e})}(n,t),function(e,t){let r=ea(e.byteLength);if(void 0!==r&&Buffer.byteLength(t,"utf8")!==r)throw new a("COMMAND_FAILED","Android snapshot helper session returned truncated XML",{headers:e,actualByteLength:Buffer.byteLength(t,"utf8")});if(!t.includes("<hierarchy")||!t.includes("</hierarchy>"))throw new a("COMMAND_FAILED","Android snapshot helper session did not return XML",{headers:e,xml:t})}(n,i),{xml:i,metadata:{helperApiVersion:(r=n).helperApiVersion,outputFormat:w,waitForIdleTimeoutMs:ea(r.waitForIdleTimeoutMs),waitForIdleQuietMs:ea(r.waitForIdleQuietMs),timeoutMs:ea(r.timeoutMs),maxDepth:ea(r.maxDepth),maxNodes:ea(r.maxNodes),rootPresent:es(r.rootPresent),captureMode:"interactive-windows"===r.captureMode||"active-window"===r.captureMode?r.captureMode:void 0,windowCount:ea(r.windowCount),nodeCount:ea(r.nodeCount),truncated:es(r.truncated),elapsedMs:ea(r.elapsedMs)}}}(await eA(e,`snapshot ${r}`,n),r)}function eA(e,t,r){return new Promise((n,i)=>{let s=o.connect({host:"127.0.0.1",port:e.port}),l=[],u=setTimeout(()=>{s.destroy(),i(new a("COMMAND_FAILED","Android snapshot helper session request timed out",{command:t,timeoutMs:r,port:e.port}))},r);s.on("connect",()=>{s.write(`${t}
4
4
  `)}),s.on("data",e=>{l.push(Buffer.from(e))}),s.on("error",e=>{clearTimeout(u),i(e)}),s.on("close",()=>{clearTimeout(u),n(Buffer.concat(l).toString("utf8"))})})}async function eM(e){await e.process.stdin?.end(),await e.process.stdout?.destroy(),await e.process.stderr?.destroy(),await eg(e)}async function eg(e){await e.adb(["forward","--remove",`tcp:${e.port}`],{allowFailure:!0,timeoutMs:5e3})}let ev=new Map;function eN(e){ey(ex(e.deviceKey,e.packageName,e.versionCode))}function ex(e,t,r){return e?`${e}\0${t}\0${r}`:void 0}function ey(e){e&&ev.delete(e)}async function eI(e){var t,r,n;let{adb:i,artifact:o}=e,s=e.installPolicy??"missing-or-outdated",l=o.manifest.packageName,u=o.manifest.versionCode;if("never"===s)return{packageName:l,versionCode:u,installed:!1,reason:"skipped"};let d=ex(e.deviceKey,l,u),c=d?ev.get(d):void 0;if(d&&"always"!==s&&void 0!==c)return{packageName:l,versionCode:u,installedVersionCode:c,installed:!1,reason:"current"};let h=await eC(i,l,e.timeoutMs),p=(t=s,r=h,n=u,"never"===t?"skipped":"always"===t?"forced":void 0===r?"missing":r<n?"outdated":"current");if("current"===p){if(void 0===h)throw Error("Expected installed versionCode for current Android snapshot helper");return d&&ev.set(d,h),{packageName:l,versionCode:u,installedVersionCode:h,installed:!1,reason:p}}await A(o);let f=await eD(i,e.adbProvider??i,o.apkPath,function(e){let t={};for(let r of e.slice(1)){let e=b(r);if(!e)throw new a("INVALID_ARGS",`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);t[e]=!0}return t}(N(o.manifest.installArgs)),{packageName:l,timeoutMs:e.timeoutMs});if(0!==f.exitCode)throw ey(d),new a("COMMAND_FAILED","Failed to install Android snapshot helper",{packageName:l,versionCode:u,stdout:f.stdout,stderr:f.stderr,exitCode:f.exitCode});return d&&ev.set(d,u),{packageName:l,versionCode:u,installedVersionCode:h,installed:!0,reason:p}}async function eC(e,t,r){let n=await e(["shell","cmd","package","list","packages","--show-versioncode",t],{allowFailure:!0,timeoutMs:r});if(0===n.exitCode){var i=`${n.stdout}
5
5
  ${n.stderr}`,o=t;let e=`package:${o}`;for(let t of i.split(/\r?\n/)){if(!t.startsWith(e)||t.length>e.length&&!/\s/.test(t[e.length]??""))continue;let r=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(r)return Number(r[1])}return}}async function eD(e,t,r,n,i){var o;let a=async()=>await d(r,{allowFailure:!0,provider:t,...n,timeoutMs:i.timeoutMs}),s=await a();if(0===s.exitCode||(o=s,!`${o.stdout}
6
6
  ${o.stderr}`.includes("INSTALL_FAILED_UPDATE_INCOMPATIBLE")))return s;let l=await e(["uninstall",i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs}),u=await a();return 0===u.exitCode?u:{...u,stderr:[u.stderr,l.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${l.stderr}`:""].filter(Boolean).join("\n")}}export{c as ANDROID_SNAPSHOT_HELPER_NAME,w as ANDROID_SNAPSHOT_HELPER_OUTPUT_FORMAT,h as ANDROID_SNAPSHOT_HELPER_PACKAGE,f as ANDROID_SNAPSHOT_HELPER_PROTOCOL,p as ANDROID_SNAPSHOT_HELPER_RUNNER,S as androidUiNodes,k as buildUiHierarchySnapshot,K as captureAndroidSnapshotWithHelper,eh as captureAndroidSnapshotWithHelperSession,eI as ensureAndroidSnapshotHelper,eN as forgetAndroidSnapshotHelperInstall,g as parseAndroidSnapshotHelperManifest,Y as parseAndroidSnapshotHelperOutput,Z as parseAndroidSnapshotHelperXml,T as parseUiHierarchy,P as parseUiHierarchyTree,M as prepareAndroidSnapshotHelperArtifactFromManifestUrl,ep as stopAndroidSnapshotHelperSession,A as verifyAndroidSnapshotHelperArtifact};
package/dist/src/2403.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"./9152.js";import{readScreenshotScriptFlag as i}from"./695.js";import{formatScriptStringLiteral as o,parseReplayOpenFlags as s,formatPortableActionLine as l,parseReplaySeriesFlags as a,parseReplayRuntimeFlags as u,isClickLikeCommand as f}from"./123.js";import{MAESTRO_COMPAT_TRACKER_URL as p,MAESTRO_NEW_ISSUE_URL as c}from"./1352.js";let h=/^[A-Z_][A-Z0-9_]*$/,d=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,m="AD_VAR_";function g(e){return e.startsWith("AD_")}function A(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(g(e))throw A(e);t[e]=r}return{values:t}}function v(e,t){Object.assign(e.values,t)}function w(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(m))continue;let e=n.slice(m.length);0!==e.length&&h.test(e)&&(g(e)||(t[e]=r))}return t}function b(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!h.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(g(i))throw A(i);t[i]=n.slice(e+1)}return t}function I(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function $(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function _(e,t,n){return e.replace(d,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function S(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>_(e,t,n)),flags:N(e.flags,t,n)??{},runtime:N(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:_(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function N(e,t,n){return e?function e(t,n,r){return"string"==typeof t?_(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let R=new Set(["ios","android","macos","linux"]),D=new Set(["mobile","tv","desktop"]);function M(e){let t=[],n=[],o=e.split(/\r?\n/),l=!1;for(let[e,p]of o.entries()){let o=p.trim();if(0===o.length||o.startsWith("#"))continue;if(x(o)){if(l)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let c=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...o]=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<o.length;e+=1){let t=o[e];if("-i"===t){l.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){l.flags.snapshotCompact=!0;continue}if("--raw"===t){l.flags.snapshotRaw=!0;continue}if("--force-full"===t){l.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<o.length){let t=Number(o[e+1]);Number.isFinite(t)&&t>=0&&(l.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<o.length){l.flags.snapshotScope=o[e+1],e+=1;continue}if("--backend"===t&&e+1<o.length){e+=1;continue}}return l}if("open"===n){let e=s(o);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l.runtime=e.runtime,l}if("runtime"===n){let e=u(o);return l.positionals=e.positionals,Object.assign(l.flags,e.flags),l}if(f(n)){let e=a(n,o);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 j(r)&&j(i)&&e.positionals.length>=2?l.positionals=[r,i]:l.positionals=[e.positionals.join(" ")],l}if("fill"===n){let e=a(n,o);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=o[0],t=o[1];return void 0===e||void 0===t?l.positionals=o:t.startsWith("@")?(l.positionals=[e,t],o[2]&&(l.result={refLabel:o[2]})):l.positionals=[e,o.slice(1).join(" ")],l}if("swipe"===n||"type"===n){let e=a(n,o);return Object.assign(l.flags,e.flags),l.positionals=e.positionals,l}if("record"===n){let e=[];for(let t=0;t<o.length;t+=1){let n=o[t];if("--hide-touches"===n){l.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<o.length){let e=Number(o[t+1]);Number.isFinite(e)&&(l.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<o.length){let e=Number(o[t+1]);Number.isFinite(e)&&(l.flags.quality=Math.floor(e)),t+=1;continue}e.push(n)}return l.positionals=e,l}if("screenshot"===n){let e=[];for(let t=0;t<o.length;t+=1){let n=o[t],r=i({args:o,index:t,flags:l.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return l.positionals=e,l}return l.positionals=o,l}(p);c&&(t.push(c),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(x(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!h.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&R.has(e)&&L(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&D.has(e)&&L(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&L(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&L(n,"retries",Math.floor(e))}}return n}function x(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function L(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function j(e){return!!e&&!Number.isNaN(Number(e))}function V(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${o(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(l(e,{runtimeIncludeAllPositionals:!0}));let s=`${i.join("\n")}
2
- `,a=`${t}.tmp-${process.pid}-${Date.now()}`;e.writeFileSync(a,s),e.renameSync(a,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 k(e){return`${e.map(e=>n(e).trimEnd()).join("\n---\n")}
3
- `}function C(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function G(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw H(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function P(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function W(e){return e.map((e,t)=>{if("string"==typeof e||P(e))return e;throw new r("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function K(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}function F(e,t){if(null==e)return{};if(!P(e))throw new r("INVALID_ARGS",`${t} expects a map.`);let n={};for(let[t,r]of Object.entries(e))("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=String(r));return n}function U(e,t){return P(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function q(e,t){if(e.appId)return e.appId;throw new r("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function z(e,t){if("string"==typeof t)return t;throw new r("INVALID_ARGS",`${e} expects a string value.`)}function Y(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function Z(e){throw H(`Maestro command "${e}" is not supported yet.`)}function H(e){throw new r("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${p}. If this syntax matters for your flows, comment there or open a focused issue at ${c}.`)}function J(e,t){return`${e},${t}`}function T(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw H('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function B(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:"absolute",x:Number(t[1]),y:Number(t[2])};let n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:"percent",x:Number(n[1]),y:Number(n[2])};throw H('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}export{G as assertOnlyKeys,y as buildReplayVarScope,w as collectReplayShellEnv,J as formatMaestroPoint,P as isPlainRecord,v as mergeReplayVarScopeValues,W as normalizeCommandList,K as normalizePlatform,T as parseAbsolutePoint,B as parseMaestroPoint,E as parseMaestroYamlDocuments,b as parseReplayCliEnvEntries,M as parseReplayScriptDetailed,F as readEnvMap,I as readReplayCliEnvEntries,O as readReplayScriptMetadata,$ as readReplayShellEnvSource,U as readTimeoutMs,q as requireAppId,z as requireStringValue,Y as resolveMaestroString,S as resolveReplayAction,k as stringifyMaestroYamlDocuments,C as support_action,Z as unsupportedCommand,H as unsupportedMaestroSyntax,V as writeReplayScript};
1
+ import e from"node:fs";import{parseAllDocuments as t,stringify as n}from"yaml";import{AppError as r}from"./9152.js";import{MAESTRO_NEW_ISSUE_URL as i,MAESTRO_COMPAT_TRACKER_URL as o,readScreenshotScriptFlag as s}from"./6133.js";import{formatScriptStringLiteral as l,parseReplayOpenFlags as a,formatPortableActionLine as u,parseReplaySeriesFlags as f,parseReplayRuntimeFlags as p,isClickLikeCommand as c}from"./123.js";let h=/^[A-Z_][A-Z0-9_]*$/,d=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g,m="AD_VAR_";function g(e){return e.startsWith("AD_")}function A(e){return new r("INVALID_ARGS",`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function y(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;for(let n of[e.fileEnv,e.shellEnv,e.cliEnv])if(n)for(let[e,r]of Object.entries(n)){if(g(e))throw A(e);t[e]=r}return{values:t}}function v(e,t){Object.assign(e.values,t)}function w(e){let t={};for(let[n,r]of Object.entries(e)){if("string"!=typeof r||!n.startsWith(m))continue;let e=n.slice(m.length);0!==e.length&&h.test(e)&&(g(e)||(t[e]=r))}return t}function b(e){let t={};for(let n of e){let e=n.indexOf("=");if(e<=0)throw new r("INVALID_ARGS",`Invalid -e entry "${n}": expected KEY=VALUE.`);let i=n.slice(0,e);if(!h.test(i))throw new r("INVALID_ARGS",`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(g(i))throw A(i);t[i]=n.slice(e+1)}return t}function I(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):[]}function $(e){if(e&&"object"==typeof e&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}return process.env}function S(e,t,n){return e.replace(d,(e,i,o,s)=>{if(i)return"${";if(!o)return e;if(Object.prototype.hasOwnProperty.call(t.values,o))return String(t.values[o]);if(void 0!==s)return s.replace(/\\(.)/g,"$1");throw new r("INVALID_ARGS",`Unresolved variable \${${o}} at ${n.file}:${n.line}.`)})}function _(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>S(e,t,n)),flags:N(e.flags,t,n)??{},runtime:N(e.runtime,t,n),replayControl:function(e,t,n){if(!e)return e;if(e.kind==="maestroRunFlowWhen"){return{...e,selector:S(e.selector,t,n)}}return e}(e.replayControl,t,n)}}function N(e,t,n){return e?function e(t,n,r){return"string"==typeof t?S(t,n,r):Array.isArray(t)?t.map(t=>e(t,n,r)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,i])=>[t,e(i,n,r)])):t}(e,t,n):e}let R=new Set(["ios","android","macos","linux"]),D=new Set(["mobile","tv","desktop"]);function M(e){let t=[],n=[],i=e.split(/\r?\n/),o=!1;for(let[e,l]of i.entries()){let i=l.trim();if(0===i.length||i.startsWith("#"))continue;if(x(i)){if(o)throw new r("INVALID_ARGS",`env directives must precede all actions (line ${e+1}).`);continue}let u=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let[n,...i]=function(e){let t=[],n=0;for(;n<e.length&&!((n=function(e,t){let n=t;for(;n<e.length&&/\s/.test(e.charAt(n));)n+=1;return n}(e,n))>=e.length);){let i='"'===e[n]?function(e,t){let n=!1,i=t+1;for(;i<e.length;i+=1){let t=e.charAt(i);if('"'===t&&!n)break;if(n){n=!1;continue}n="\\"===t}if(i>=e.length)throw new r("INVALID_ARGS",`Invalid replay script line: ${e}`);return{value:JSON.parse(e.slice(t,i+1)),nextCursor:i+1}}(e,n):function(e,t){let n=t;for(;n<e.length&&!/\s/.test(e.charAt(n));)n+=1;return{value:e.slice(t,n),nextCursor:n}}(e,n);t.push(i.value),n=i.nextCursor}return t}(t);if(void 0===n||"context"===n)return null;let o={ts:Date.now(),command:n,positionals:[],flags:{}};if("snapshot"===n){o.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){o.flags.snapshotInteractiveOnly=!0;continue}if("-c"!==t){if("--raw"===t){o.flags.snapshotRaw=!0;continue}if("--force-full"===t){o.flags.snapshotForceFull=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(o.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){o.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}}return o}if("open"===n){let e=a(i);return o.positionals=e.positionals,Object.assign(o.flags,e.flags),o.runtime=e.runtime,o}if("runtime"===n){let e=p(i);return o.positionals=e.positionals,Object.assign(o.flags,e.flags),o}if(c(n)){let e=f(n,i);Object.assign(o.flags,e.flags);let t=e.positionals[0];if(void 0===t)return o;if(t.startsWith("@"))return o.positionals=[t],e.positionals[1]&&(o.result={refLabel:e.positionals[1]}),o;let r=e.positionals[0],s=e.positionals[1];return j(r)&&j(s)&&e.positionals.length>=2?o.positionals=[r,s]:o.positionals=[e.positionals.join(" ")],o}if("fill"===n){let e=f(n,i);if(Object.assign(o.flags,e.flags),!(e.positionals.length>=2))return o.positionals=e.positionals,o;let[t,r,...s]=e.positionals;return t.startsWith("@")?(s.length>0?(o.positionals=[t,s.join(" ")],o.result={refLabel:r}):o.positionals=[t,r],o):(o.positionals=[t,[r,...s].join(" ")],o)}if("get"===n){let e=i[0],t=i[1];return void 0===e||void 0===t?o.positionals=i:t.startsWith("@")?(o.positionals=[e,t],i[2]&&(o.result={refLabel:i[2]})):o.positionals=[e,i.slice(1).join(" ")],o}if("swipe"===n||"type"===n){let e=f(n,i);return Object.assign(o.flags,e.flags),o.positionals=e.positionals,o}if("record"===n){let e=[];for(let t=0;t<i.length;t+=1){let n=i[t];if("--hide-touches"===n){o.flags.hideTouches=!0;continue}if("--fps"===n&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(o.flags.fps=Math.floor(e)),t+=1;continue}if("--quality"===n&&t+1<i.length){let e=Number(i[t+1]);Number.isFinite(e)&&(o.flags.quality=Math.floor(e)),t+=1;continue}e.push(n)}return o.positionals=e,o}if("screenshot"===n){let e=[];for(let t=0;t<i.length;t+=1){let n=i[t],r=s({args:i,index:t,flags:o.flags});if(r.handled){t=r.nextIndex;continue}e.push(n)}return o.positionals=e,o}return o.positionals=i,o}(l);u&&(t.push(u),n.push(e+1),o=!0)}return{actions:t,actionLines:n}}function O(e){let t=e.split(/\r?\n/),n={};for(let[e,i]of t.entries()){let t=i.trim();if(0===t.length||t.startsWith("#"))continue;if(x(t)){!function(e,t,n){let{key:i,value:o}=function(e,t){let n=e.slice(3).replace(/^[\s]+/,""),i=n.indexOf("=");if(i<=0)throw new r("INVALID_ARGS",`Invalid env directive on line ${t}: expected "env KEY=VALUE".`);let o=n.slice(0,i);if(!h.test(o))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(o.startsWith("AD_"))throw new r("INVALID_ARGS",`Invalid env key "${o}" on line ${t}: the AD_* namespace is reserved for built-in variables. Rename ${o} to avoid the AD_ prefix.`);return{key:o,value:function(e,t){if(0===e.length)return"";if(e.startsWith('"'))try{let t=JSON.parse(e);if("string"!=typeof t)throw Error("not a string literal");return t}catch{throw new r("INVALID_ARGS",`Invalid quoted env value on line ${t}.`)}return e}(n.slice(i+1),t)}}(t,n),s=e.env??{};if(Object.prototype.hasOwnProperty.call(s,i))throw new r("INVALID_ARGS",`Duplicate env directive "${i}" on line ${n}.`);s[i]=o,e.env=s}(n,t,e+1);continue}if(!t.startsWith("context "))break;let o=t.match(/(?:^|\s)platform=([^\s]+)/);if(o){let e=o[1];e&&R.has(e)&&L(n,"platform",e)}let s=t.match(/(?:^|\s)target=([^\s]+)/);if(s){let e=s[1];e&&D.has(e)&&L(n,"target",e)}let l=t.match(/(?:^|\s)timeout=(\d+)/);if(l){let e=Number(l[1]);Number.isFinite(e)&&e>=1&&L(n,"timeoutMs",Math.floor(e))}let a=t.match(/(?:^|\s)retries=(\d+)/);if(a){let e=Number(a[1]);Number.isFinite(e)&&e>=0&&L(n,"retries",Math.floor(e))}}return n}function x(e){return"env"===e||e.startsWith("env ")||e.startsWith("env ")}function L(e,t,n){let i=e[t];if(void 0!==i)throw new r("INVALID_ARGS",i===n?`Duplicate replay test metadata "${t}" in context header.`:`Conflicting replay test metadata "${t}" in context header: ${String(i)} vs ${String(n)}.`);e[t]=n}function j(e){return!!e&&!Number.isNaN(Number(e))}function V(t,n,r){let i=[];if(r){let e=r.device.kind?` kind=${r.device.kind}`:"",t=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${t} device=${l(r.device.name)}${e} theme=unknown`)}for(let e of n)i.push(u(e,{runtimeIncludeAllPositionals:!0}));let o=`${i.join("\n")}
2
+ `,s=`${t}.tmp-${process.pid}-${Date.now()}`;e.writeFileSync(s,o),e.renameSync(s,t)}function k(e){let n=t(e);for(let e of n)if(e.errors.length>0){let t=e.errors[0]?.message??"Invalid Maestro YAML flow.";throw new r("INVALID_ARGS",`Invalid Maestro YAML flow: ${t}`)}return n.map(e=>e.toJSON()).filter(e=>null!==e)}function E(e){return`${e.map(e=>n(e).trimEnd()).join("\n---\n")}
3
+ `}function G(e,t=[],n){return{ts:Date.now(),command:e,positionals:t,flags:n??{}}}function C(e,t,n){let r=new Set(n),i=Object.keys(e).filter(e=>!r.has(e));if(i.length>0)throw H(`Maestro ${t} field "${i[0]}" is not supported yet.`)}function P(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function W(e){return e.map((e,t)=>{if("string"==typeof e||P(e))return e;throw new r("INVALID_ARGS",`Unsupported Maestro command at index ${t+1}: expected a scalar or one-key map.`)})}function F(e){if(e){let t;return"android"===(t=e.trim().toLowerCase())?"android":"ios"===t?"ios":void 0}}function K(e,t){if(null==e)return{};if(!P(e))throw new r("INVALID_ARGS",`${t} expects a map.`);let n={};for(let[t,r]of Object.entries(e))("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=String(r));return n}function U(e,t){return P(e)&&"number"==typeof e.timeout&&Number.isFinite(e.timeout)?Math.max(0,Math.floor(e.timeout)):t}function q(e,t){if(e.appId)return e.appId;throw new r("INVALID_ARGS",`${t} requires appId in the Maestro flow config.`)}function z(e,t){if("string"==typeof t)return t;throw new r("INVALID_ARGS",`${e} expects a string value.`)}function Y(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t.env,n)?String(t.env[n]):e)}function Z(e){throw H(`Maestro command "${e}" is not supported yet.`)}function H(e){throw new r("INVALID_ARGS",`${e} See supported/unsupported Maestro compatibility at ${o}. If this syntax matters for your flows, comment there or open a focused issue at ${i}.`)}function J(e,t){return`${e},${t}`}function T(e){let t=e.match(/^(\d+),(\d+)$/);if(!t)throw H('Only absolute Maestro point selectors like "100,200" are supported.');return{x:Number(t[1]),y:Number(t[2])}}function B(e){let t=e.match(/^\s*(\d+)\s*,\s*(\d+)\s*$/);if(t)return{kind:"absolute",x:Number(t[1]),y:Number(t[2])};let n=e.match(/^\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*$/);if(n)return{kind:"percent",x:Number(n[1]),y:Number(n[2])};throw H('Only Maestro swipe coordinates like "100,200" or "50%,75%" are supported.')}export{C as assertOnlyKeys,y as buildReplayVarScope,w as collectReplayShellEnv,J as formatMaestroPoint,P as isPlainRecord,v as mergeReplayVarScopeValues,W as normalizeCommandList,F as normalizePlatform,T as parseAbsolutePoint,B as parseMaestroPoint,k as parseMaestroYamlDocuments,b as parseReplayCliEnvEntries,M as parseReplayScriptDetailed,K as readEnvMap,I as readReplayCliEnvEntries,O as readReplayScriptMetadata,$ as readReplayShellEnvSource,U as readTimeoutMs,q as requireAppId,z as requireStringValue,Y as resolveMaestroString,_ as resolveReplayAction,E as stringifyMaestroYamlDocuments,G as support_action,Z as unsupportedCommand,H as unsupportedMaestroSyntax,V as writeReplayScript};